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获取文件版本信息、公司名和产品名的方法
Oct 05 Python
Python中用于返回绝对值的abs()方法
May 14 Python
初步讲解Python中的元组概念
May 21 Python
python中解析json格式文件的方法示例
May 03 Python
Python中最大最小赋值小技巧(分享)
Dec 23 Python
python抓取网站的图片并下载到本地的方法
May 22 Python
python 多线程中子线程和主线程相互通信方法
Nov 09 Python
如何用python写一个简单的词法分析器
Dec 18 Python
基于python实现高速视频传输程序
May 05 Python
python中时间转换datetime和pd.to_datetime详析
Aug 11 Python
基于Python和C++实现删除链表的节点
Jul 06 Python
scrapy与selenium结合爬取数据(爬取动态网站)的示例代码
Sep 28 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
ThinkPHP实现分页功能
2017/04/28 PHP
PHP-FPM和Nginx的通信机制详解
2019/02/01 PHP
PHP设计模式之抽象工厂模式实例分析
2019/03/25 PHP
关于Laravel参数验证的一些疑与惑
2019/11/19 PHP
js通过地址栏给action传值(中文乱码全是问号)
2013/05/02 Javascript
setTimeout自动触发一个js的方法
2014/01/15 Javascript
JSON+HTML实现国家省市联动选择效果
2014/05/18 Javascript
Bootstrap富文本组件wysiwyg数据保存到mysql的方法
2016/05/09 Javascript
js数组常用操作方法小结(增加,删除,合并,分割等)
2016/08/02 Javascript
Easyui的组合框的取值与赋值
2016/10/28 Javascript
CSS+jQuery实现简单的折叠菜单
2016/12/20 Javascript
vue2中filter()的实现代码
2017/07/09 Javascript
javascript简写常用的12个技巧(可以大大减少你的js代码量)
2020/03/28 Javascript
javascript中的this作用域详解
2019/07/15 Javascript
Vue 使用Props属性实现父子组件的动态传值详解
2019/11/13 Javascript
基于vue.js实现购物车
2020/01/15 Javascript
Vue使用自定义指令实现拖拽行为实例分析
2020/06/06 Javascript
[02:02]DOTA2英雄基础教程 斯拉达
2013/12/11 DOTA
python解析模块(ConfigParser)使用方法
2013/12/10 Python
老生常谈python的私有公有属性(必看篇)
2017/06/09 Python
详解用TensorFlow实现逻辑回归算法
2018/05/02 Python
python微信公众号之关键词自动回复
2018/06/15 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
Python线程池模块ThreadPoolExecutor用法分析
2018/12/28 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
Python + OpenCV 实现LBP特征提取的示例代码
2019/07/11 Python
python第三方库学习笔记
2020/02/07 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的示例代码
2021/02/24 HTML / CSS
HTML5 与 XHTML2
2008/10/17 HTML / CSS
全球性的在线商店:Vogca
2019/05/10 全球购物
房地产员工找工作的自我评价
2013/11/15 职场文书
会计应聘求职信范文
2013/12/17 职场文书
陈欧的广告词
2014/03/18 职场文书
创业计划书之便利店
2019/09/05 职场文书
Python WSGI 规范简介
2021/04/11 Python
MySQL创建管理RANGE分区
2022/04/13 MySQL