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显示生日是星期几的方法
May 27 Python
python读取文本中数据并转化为DataFrame的实例
Apr 10 Python
django表单实现下拉框的示例讲解
May 29 Python
使用CodeMirror实现Python3在线编辑器的示例代码
Jan 14 Python
Python爬虫之UserAgent的使用实例
Feb 21 Python
python定时检测无响应进程并重启的实例代码
Apr 22 Python
在pycharm下设置自己的个性模版方法
Jul 15 Python
Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项
Oct 11 Python
Python Des加密解密如何实现软件注册码机器码
Jan 08 Python
Django中从mysql数据库中获取数据传到echarts方式
Apr 07 Python
Jupyter notebook无法导入第三方模块的解决方式
Apr 15 Python
Python解析微信dat文件的方法
Nov 30 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+javascript模拟Matrix画面
2006/10/09 PHP
PHP正确解析UTF-8字符串技巧应用
2012/11/07 PHP
基于php缓存的详解
2013/05/15 PHP
php 使用curl模拟登录人人(校内)网的简单实例
2016/06/06 PHP
Javascript面向对象编程(三) 非构造函数的继承
2011/08/28 Javascript
node.js中的buffer.length方法使用说明
2014/12/14 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
2016/05/09 Javascript
JavaScript函数中关于valueOf和toString的理解
2016/06/14 Javascript
jQuery 3.0中存在问题及解决办法
2016/07/15 Javascript
javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
2016/08/19 Javascript
关于Jquery中的事件绑定总结
2016/10/26 Javascript
js实现各种复制到剪贴板的方法(分享)
2016/10/27 Javascript
前端面试知识点锦集(JavaScript篇)
2016/12/28 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
2017/01/10 Javascript
nodejs读写json文件的简单方法(必看)
2017/03/09 NodeJs
Angularjs上传图片实例详解
2017/08/06 Javascript
利用vue+elementUI实现部分引入组件的方法详解
2017/11/22 Javascript
详解vue-cli之webpack3构建全面提速优化
2017/12/25 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
jQuery实现简单三级联动效果
2020/09/05 jQuery
Django中传递参数到URLconf的视图函数中的方法
2015/07/18 Python
Python连接mysql数据库的正确姿势
2016/02/03 Python
使用Python写一个贪吃蛇游戏实例代码
2017/08/21 Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
2017/08/24 Python
python通过elixir包操作mysql数据库实例代码
2018/01/31 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
Python发送邮件实现基础解析
2020/08/14 Python
SQL Server提供的3种恢复模型都是什么? 有什么区别?
2012/05/13 面试题
《开国大典》教学反思
2014/04/19 职场文书
反腐倡廉警示教育活动总结
2014/05/05 职场文书
离婚协议书标准格式
2014/10/04 职场文书
个人融资协议书范本两则
2014/10/15 职场文书
《悲惨世界》:比天空更广阔的是人的心灵
2020/01/16 职场文书
关于JavaScript轮播图的实现
2021/11/20 Javascript
Python调用腾讯API实现人脸身份证比对功能
2022/04/04 Python