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删除文件示例分享
Jan 28 Python
python基础教程之元组操作使用详解
Mar 25 Python
用Python中的字典来处理索引统计的方法
May 05 Python
Python 爬虫的工具列表大全
Jan 31 Python
python基础教程之匿名函数lambda
Jan 17 Python
Python排序搜索基本算法之选择排序实例分析
Dec 09 Python
python使用tensorflow保存、加载和使用模型的方法
Jan 31 Python
Python交互式图形编程的实现
Jul 25 Python
python连接打印机实现打印文档、图片、pdf文件等功能
Feb 07 Python
python如何实现读取并显示图片(不需要图形界面)
Jul 08 Python
详解python 支持向量机(SVM)算法
Sep 18 Python
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
Apr 21 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简单的伪原创程序,配合商城采集用的
2010/10/12 PHP
如何让CI框架支持service层
2014/10/29 PHP
PHP响应post请求上传文件的方法
2015/12/17 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
PHP的PDO预定义常量讲解
2019/01/24 PHP
PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
2019/12/04 PHP
关于js中alert弹出窗口文本换行问题简单详细说明
2012/12/11 Javascript
javascript右下角弹层及自动隐藏(自己编写)
2013/11/20 Javascript
jquery图片轮播插件仿支付宝2013版全屏图片幻灯片
2014/04/03 Javascript
5种处理js跨域问题方法汇总
2014/12/04 Javascript
jQuery中:image选择器用法实例
2015/01/03 Javascript
jquery中ajax使用error调试错误的方法
2015/02/08 Javascript
浅析js绑定事件的常用方法
2016/05/15 Javascript
全面了解函数声明与函数表达式、变量提升
2016/08/09 Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
2016/08/25 Javascript
vue params、query传参使用详解
2017/09/12 Javascript
加载 vue 远程代码的组件实例详解
2017/11/20 Javascript
angular实现页面打印局部功能的思考与方法
2018/04/13 Javascript
JS通过位运算实现权限加解密
2018/08/14 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
深入理解webpack process.env.NODE_ENV配置
2020/02/23 Javascript
[03:01]完美世界DOTA2联赛PWL S2 集锦第二期
2020/12/03 DOTA
TensorFlow神经网络优化策略学习
2018/03/09 Python
python用BeautifulSoup库简单爬虫实例分析
2018/07/30 Python
python日期相关操作实例小结
2019/06/24 Python
Python高级特性——详解多维数组切片(Slice)
2019/11/26 Python
python使用pandas抽样训练数据中某个类别实例
2020/02/28 Python
Python中无限循环需要什么条件
2020/05/27 Python
pandas实现导出数据的四种方式
2020/12/13 Python
python time.strptime格式化实例详解
2021/02/03 Python
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
对祖国的寄语大全
2014/04/11 职场文书
大学宣传委员竞选稿
2015/11/19 职场文书
2016七一建党节慰问信
2015/11/30 职场文书
2016基督教会圣诞节开幕词
2016/03/04 职场文书
详解Oracle块修改跟踪功能
2021/11/07 Oracle