pygame学习笔记(5):游戏精灵


Posted in Python onApril 15, 2015

据说在任天堂FC时代,精灵的作用相当巨大,可是那时候只知道怎么玩超级玛丽、魂斗罗,却对精灵一点也不知。pygame.sprite.Sprite就是Pygame里面用来实现精灵的一个类,使用时,并不需要对它实例化,只需要继承他,然后按需写出自己的类就好了,因此非常简单实用。

一、什么是精灵

精灵可以认为成是一个个小图片,一种可以在屏幕上移动的图形对象,并且可以与其他图形对象交互。精灵图像可以是使用pygame绘制函数绘制的图像,也可以是原来就有的图像文件。

二、sprite中主要且常用的变量有以下几个:更多详细的见http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite
self.image这个负责显示什么。如self.image=pygame.Surface([x,y])说明该精灵是一个x,y大小的距形,self.image=pygame.image.load(filename)说明该精灵调用显示filename这个图片文件。

self.image.fill([color]),负责对self.image着色,如self.image=pygame.Surface([x,y])

self.image.fill([255,0,0])

对x,y距形填充红色。
self.rect负责在哪里显示。一般来说,先用self.rect=self.image.get_rect()获得image距形大小,然后给self.rect设定显示的位置,一般用self.rect.topleft(topright、bottomleft、bottomright)来设定某一个角的显示位置。另外,self.rect.top、self.rect.bottom、self.rect.right、self.rect.left分别表示上下左右。
self.update 负责使精灵行为生效。
Sprite.add  添加精灵到group中去。
Sprite.remove 从group中删除
Sprite.kill 从groups中全部删除精灵
Sprite.alive 判断精灵是否属于groups

三、建立一个简单的精灵

所有精灵在建立时都是从pygame.sprite.Sprite中继承的。

(1)做一个精灵,绘制一个宽30、高30的距形,具体代码如下:

class Temp(pygame.sprite.Sprite):

    def __init__(self,color,initial_position):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([30,30])

        self.image.fill(color)

        self.rect=self.image.get_rect()

        self.rect.topleft=initial_position

这里逐句进行一下分析,pygame.sprite.Sprite.__init__(self)完成初始化。self.image = pygame.Surface([30,30])定义显示30*30的一个距形surface。self.image.fill(color)用color来填充颜色。self.rect=self.image.get_rect()获取self.image大小。self.rect.topleft=initial_position确定左上角显示位置,当然也可以用topright、bottomrigh、bottomleft来分别确定其他几个角的位置。精灵的显示,在一个640*480大小的白色窗体[50,100]的位置绘制一个30*30大小的红色距形,完整代码如下:

import pygame,sys

pygame.init()

class Temp(pygame.sprite.Sprite):

    def __init__(self,color,initial_position):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([30,30])

        self.image.fill(color)

        self.rect=self.image.get_rect()

        self.rect.topleft=initial_position

screen=pygame.display.set_mode([640,480])

screen.fill([255,255,255])

b=Temp([255,0,0],[50,100])

screen.blit(b.image,b.rect)

pygame.display.update()

while True:

    for event in pygame.event.get():

        if event.type==pygame.QUIT:

            sys.exit()

(2)做一个精灵,显示内容为某一图片,这里以前面用过的小车图片为例,代码如下:
import pygame,sys

pygame.init()

class Car(pygame.sprite.Sprite):

    def __init__(self,filename,initial_position):

        pygame.sprite.Sprite.__init__(self)

        self.image=pygame.image.load(filename)

        self.rect=self.image.get_rect()

        #self.rect.topleft=initial_position

        self.rect.bottomright=initial_position

        print self.rect.right

         

screen=pygame.display.set_mode([640,480])

screen.fill([255,255,255])

fi='ok1.jpg'

b=Car(fi,[150,100])

screen.blit(b.image,b.rect)

pygame.display.update()

while True:

    for event in pygame.event.get():

        if event.type==pygame.QUIT:

            sys.exit()

这段代码与(1)的不同之处在于self.image定义为pygame.image.load(filename),用来显示filename文件,本代码使用了ok1.jpg文件,并定义了小车右底角的显示位置是[150,100]。

三、学习精灵组

(1)使用精灵在屏幕上放多个图像,这种方法没用利用精灵组的概念,而是利用了list来生成每一个精灵。Cargroup用来存储不同位置的Car,screen.blit(carlist.image,carlist.rect)逐个显示每一个精灵。具体见代码:

import pygame,sys

pygame.init()

class Car(pygame.sprite.Sprite):

    def __init__(self,filename,initial_position):

        pygame.sprite.Sprite.__init__(self)

        self.image=pygame.image.load(filename)

        self.rect=self.image.get_rect()

        self.rect.bottomright=initial_position
         

screen=pygame.display.set_mode([640,480])

screen.fill([255,255,255])

fi='ok1.jpg'

locationgroup=([150,200],[350,360],[250,280])

Cargroup=[]

for lo in locationgroup:

    Cargroup.append(Car(fi,lo))

for carlist in Cargroup:

    screen.blit(carlist.image,carlist.rect)

pygame.display.update()

while True:

    for event in pygame.event.get():

        if event.type==pygame.QUIT:

            sys.exit()

具体效果见图:

pygame学习笔记(5):游戏精灵

(2)使用精灵组来实现多个图像。上面精灵是存在一个列表中,很方便,就是有点不太好用。除了精灵,pygame还提供了精灵组,它很适合处理精灵列表,有添加,移除,绘制,更新等方法。具体如下:http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite
Group.sprites 精灵组
Group.copy 复制
Group.add 添加
Group.remove 移除
Group.has 判断精灵组成员
Group.update 更新
Group.draw 位块显示
Group.clear - 绘制背景
Group.empty 清空
同样还是上面的这个例子,这里用精灵组来实现。

import pygame,sys

pygame.init()

class Car(pygame.sprite.Sprite):

    def __init__(self,filename,initial_position):

        pygame.sprite.Sprite.__init__(self)

        self.image=pygame.image.load(filename)

        self.rect=self.image.get_rect()

        self.rect.bottomright=initial_position

screen=pygame.display.set_mode([640,480])

screen.fill([255,255,255])

fi='ok1.jpg'

locationgroup=([150,200],[350,360],[250,280])

Cargroup=pygame.sprite.Group()

for lo in locationgroup:

    Cargroup.add(Car(fi,lo))
for carlist in Cargroup.sprites():

    screen.blit(carlist.image,carlist.rect)

pygame.display.update()

while True:

    for event in pygame.event.get():

        if event.type==pygame.QUIT:

            sys.exit()

两个例子都是在[150,200],[350,360],[250,280]三个位置显示三辆小车,不同之处第一个用的是list,第二个用的是精灵组。差别就在几句话上,一是Cargroup=pygame.sprite.Group()定义Cargroup为精灵组,二是Cargroup.add(Car(fi,lo))用add代替了append,三是for carlist in Cargroup.sprites()这句中逐个显示精灵,这里试了一下,直接用for carlist in Cargroup也是可以的。精灵组的代码是高度优化过了,常常比列表还快。插入和删除都是常见的操作,代码还可以避免内存在循环中反复消耗。

四、动画

利用精灵组做动画会显得比较方便,这里我们首先让上面的三辆小车运动起来。
(1)三辆小车以不同的速度前行,利用random.choice随机生成[-10,-1]之间的值作为速度让小车从下向上运动,并且当到达顶部时,再从底部出现。代码如下:

import pygame,sys

from random import *

pygame.init()

class Car(pygame.sprite.Sprite):

    def __init__(self,filename,initial_position,speed):

        pygame.sprite.Sprite.__init__(self)

        self.image=pygame.image.load(filename)

        self.rect=self.image.get_rect()

        self.rect.topleft=initial_position

        self.speed=speed

    def move(self):

        self.rect=self.rect.move(self.speed)

        if self.rect.bottom < 0:   #当小车底部到达窗口顶部时,让小车从下面出来     

            self.rect.top=480

screen=pygame.display.set_mode([640,480])

screen.fill([255,255,255])

fi='ok1.jpg'

locationgroup=([150,200],[350,300],[250,200])

Cargroup=pygame.sprite.Group()

for lo in locationgroup:

    speed=[0,choice([-10,-1])]

    Cargroup.add(Car(fi,lo,speed))
while True:

    for event in pygame.event.get():

        if event.type==pygame.QUIT:

            sys.exit()

    pygame.time.delay(20)

    screen.fill([255,255,255])

    for carlist in Cargroup.sprites():

        carlist.move()

        screen.blit(carlist.image,carlist.rect)

    pygame.display.update()

(2)可以通过左右键控制三辆小车的左右移动,按左键向左移动,当到达最左边时,不再移动,按右键向右移动,当到达最右边时,不再移动。具体代码如下:

import pygame,sys

from random import *

pygame.init()

class Car(pygame.sprite.Sprite):

    def __init__(self,filename,initial_position,speed):

        pygame.sprite.Sprite.__init__(self)

        self.image=pygame.image.load(filename)

        self.rect=self.image.get_rect()

        self.rect.topleft=initial_position

        self.speed=speed

    def move(self):

        self.rect=self.rect.move(self.speed)

        if self.rect.bottom < 0:        

            self.rect.top=480

    def moveleft(self):

        self.rect.left=self.rect.left-10

        if self.rect.left<0:

            self.rect.left=0

    def moveright(self):

        self.rect.right=self.rect.right+10

        if self.rect.right>640:

            self.rect.right=640

screen=pygame.display.set_mode([640,480])

screen.fill([255,255,255])

fi='ok1.jpg'

locationgroup=([150,200],[350,300],[250,200])

Cargroup=pygame.sprite.Group()

for lo in locationgroup:

    speed=[0,choice([-10,-1])]

    Cargroup.add(Car(fi,lo,speed))
while True:

    for event in pygame.event.get():

        if event.type==pygame.QUIT:

            sys.exit()

        elif event.type == pygame.KEYDOWN:

            if event.key==pygame.K_LEFT:

                for carlist in Cargroup.sprites():

                    carlist.moveleft()

                    screen.blit(carlist.image,carlist.rect)

            if event.key==pygame.K_RIGHT:

                for carlist in Cargroup.sprites():

                    carlist.moveright()

                    screen.blit(carlist.image,carlist.rect)

    pygame.time.delay(20)

    screen.fill([255,255,255])

    for carlist in Cargroup.sprites():

        carlist.move()

        screen.blit(carlist.image,carlist.rect)

    pygame.display.update()
Python 相关文章推荐
python代码检查工具pylint 让你的python更规范
Sep 05 Python
python采集百度百科的方法
Jun 05 Python
解决Python 遍历字典时删除元素报异常的问题
Sep 11 Python
Python实现修改文件内容的方法分析
Mar 25 Python
python单线程文件传输的实例(C/S)
Feb 13 Python
python基于SMTP协议发送邮件
May 31 Python
对Python函数设计规范详解
Jul 19 Python
python查看数据类型的方法
Oct 12 Python
Python发送邮件的实例代码讲解
Oct 16 Python
Python: 传递列表副本方式
Dec 19 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
关于ResNeXt网络的pytorch实现
Jan 14 Python
pygame学习笔记(4):声音控制
Apr 15 #Python
Python的Django框架使用入门指引
Apr 15 #Python
python中xrange用法分析
Apr 15 #Python
pygame学习笔记(3):运动速率、时间、事件、文字
Apr 15 #Python
pygame学习笔记(2):画点的三种方法和动画实例
Apr 15 #Python
python实现telnet客户端的方法
Apr 15 #Python
pygame学习笔记(1):矩形、圆型画图实例
Apr 15 #Python
You might like
php数组函数序列之array_slice() - 在数组中根据条件取出一段值,并返回
2011/11/07 PHP
PHP 读取大文件的X行到Y行内容的实现代码
2013/06/24 PHP
php判断页面是否是微信打开的示例(微信打开网页)
2014/04/25 PHP
phpmyadmin配置文件现在需要绝密的短密码(blowfish_secret)的2种解决方法
2014/05/07 PHP
PHP的消息通信机制测试实例
2016/11/10 PHP
php中钩子(hook)的原理与简单应用demo示例
2019/09/03 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
JavaScript获取客户端计算机硬件及系统等信息的方法
2014/01/02 Javascript
移动节点的jquery代码
2014/01/13 Javascript
使用jQuery制作遮罩层弹出效果的极简实例分享
2016/05/12 Javascript
JS克隆,属性,数组,对象,函数实例分析
2016/11/26 Javascript
Angular中$state.go页面跳转并传递参数的方法
2017/05/09 Javascript
使用D3.js构建实时图形的示例代码
2018/08/28 Javascript
JavaScript实现无限级递归树的示例代码
2019/03/29 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
vue从后台渲染文章列表以及根据id跳转文章详情详解
2020/12/14 Vue.js
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
将Python中的数据存储到系统本地的简单方法
2015/04/11 Python
Python代码调试的几种方法总结
2015/04/15 Python
Python 提取dict转换为xml/json/table并输出的实现代码
2016/08/28 Python
Pycharm学习教程(3) 代码运行调试
2017/05/03 Python
安装Python的教程-Windows
2017/07/22 Python
深入理解Python分布式爬虫原理
2017/11/23 Python
利用Pandas读取文件路径或文件名称包含中文的csv文件方法
2018/07/04 Python
Python restful框架接口开发实现
2020/04/13 Python
Python脚本实现Zabbix多行日志监控过程解析
2020/08/26 Python
html5中svg canvas和图片之间相互转化思路代码
2014/01/24 HTML / CSS
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
法国在线药房:DoctiPharma
2020/10/21 全球购物
2015毕业实习推荐信
2015/03/23 职场文书
2015年大学生入党自荐书
2015/03/24 职场文书
五一放假通知怎么写
2015/08/18 职场文书
小组口号霸气押韵
2015/12/24 职场文书
2016年六一文艺汇演开幕词
2016/03/04 职场文书
TypeScript中条件类型精读与实践记录
2021/10/05 Javascript
Python利用zhdate模块实现农历日期处理
2022/03/31 Python