1.1游戏中实现背景的滚动
1)创建两张背景图像精灵
- 第一张完全与屏幕重合
- 第二张在屏幕的正上方
2)两张图像一起向下方运动 - self.rect.y += self.speed
3)当任意背景精灵的self.rect.y >= 屏幕的高度说明已经移动到屏幕的下方
4)将移动到屏幕下方的这张图像设置到屏幕上方 - rect.y = -rect.height
1.2背景设计
- 初始化方法
。直接指定背景图片
。is_alt判断是否是另一张图像- False表示第一张图像,需要与屏幕重合
- True表示另一张图像,在屏幕的正上方
- update()方法
。 判断是否移出屏幕,如果是,将图像设置到屏幕的正上方,从而实现交替滚动
继承如果父类提供的方法不能满足子类的需求: - 派生一个子类
- 在子类中针对特有的需求,重写父类方法,并进行扩展
02.显示游戏背景
2.1背景精灵的基本实现
在plane_sprites 新建 Background 继承自 GameSprite
class Background(GameSprite):“””游戏背景精灵”””
def updape(self):
# 1.调用父类的方法实现
super().update()# 2. 判断是否移出屏幕,如果移出将图像设置到屏幕的上方
if self.rect.y >= SCEEN_RECT.heidht:
self.rect.y = -self.rect.height
###2.2 在plane_main.py中显示背景精灵
1.在 __create_sprites方法中创建精灵和精灵组
2.在 __update_sprites方法中,让精灵组调用 update()和 draw()方法
__create_sprites 方法
def __creat_sprite(self):
# 创建背景精灵和精灵组
bg1 = Background("./文件目录/文件名)
bg2 = Background("./文件目录/文件名)
bg2.rect.y = -bg2.rect.height
self.back_group = pygame.sprite.Group(bg1, bg2)
__update _ sprites 方法
def __update_sprites(self):
self.back_group.update()
self.back_group.draw(self.screen)
敌机出场
- 使用定时器添加敌机
- 设计 Enemy类
##01.使用定时器添加敌机
####1.1定时器
在pygame 中可以使用 pygame.time.set_tiner() 来添加定时器
所谓定时器,就是每隔一段时间,去执行一些操作
set_timer(eventid, milliseconds) => Noneset_timer可以创建一个事件
可以在游戏循环的事件监听方法中捕获到该事件
第一个参数事件代号需要基于常量 pygame.USEREVBNT来指定
。USEREVBNT 是一个整数,再增加的事件可以使用 USEREVENT + 1指定,依次类推…第二个参数是事件触发间隔的毫秒值
定时器事件的监听
- 通过 pygame.event.get()可以获取当前时刻所有的事件列表
- 遍历列表并且判断event.type 是否等于 eventid,如果相等,表示定时器事件发生
####1.2定义并监听创建敌机的定时器事件
pygame 的定时器使用套路非常固定:
1.定义定时器常量——eventid
2.在初始化方法中调用set_timer方法设置定时器事件
3.在游戏循环中监听定时器事件
1)定义事件
- 在plane_ sprites.py的顶部定义事件常量
#敌机出现事件
CREATE_ BNEMY_EVENT = pygame.USEREVBNT
##02.设计Enemy类
1.游戏启动后,每隔1秒会出现一架敌机
2.每架敌机向屏幕下方飞行,行速度各不相同
3.每架敌机出现的水平位置也不尽相同
4.当敌机从屏幕下方础不会再飞回到屏幕中
- 初始化方法
。指定敌机團片
。随机敌机的初始位置和初始速度
●写update()方法
。判断是否飞出屏幕,如果是,从精灵组删除
2.1敌机类的准备
####2.2创建敌机
演练步骤
1.在_ create_ sprites,添加敌机精灵组
- 敌机是定时被创建的,因此在初始化方法中,不需要创建敌机
2.在_ event_ handler, 创建敌机,并且添加到精灵组
●调用精灵组的add方法可以向精灵组添加精灵
3.在_ update_ sprites,让敌机精灵组调用update 和draw方法
精灵(需要派生子类)
inage记录医像数据
rect记录在屏幕上的位置
update(*args):更新精灵位置
kill():从所有组中删除
精灵组
__ init__(self,* 精灵):
add(* sprites): 向络中增加精灵
spritesl:返图所有精灵列表
update(*args):让组中所有精灵用update方法
draw(Surface): 将绝中所有精灵的inage,绘制到Surface的rect位置
####2.3随机敌机位和速度
1)导入模块
.在导入模块时,建议按照以下顺序导入
1.官方标准模块导入
2.第三方模块导入
3.应用程序模块导入
.修改plane, sprites.py增加randon 的导入
Import randon
2)随机位置
3)代码实现
修改初始化方法随机敌机出现速度和位置
def __ init__ (self):
#1.调用父类方法创建敌机精灵,并且指定我机的图像 super().__ init__ ("./图片位置/图片名") #2.设置战机的陈机初始速度1 ~ 3 self.speed = randon.randint(1, 3) #3.设置战机的创机权始位置 self.rect.botton = 0 max_x = SCREEN_RECT.width-self.rect.width self.rect.x = randon.randint(0, max_x)
####2.4移出屏幕销毁敌机
- 敌机移出屏幕之后,如果没有撞到英雄,敌机的历史使命已经终结
- 需要从敌机组删除,否则造成内存浪费
检测敌机被销毁
__ del__ 内置方法会在对象被销毁前调用,在开发中,可用于判断对象是否被销毁
def del(self):
print(“敌机挂了 %s” % self.rect)
判断敌机是否飞出屏幕,如果是,调用kill()方法从所有组中删除
def update(self):
super().update(args)
#判断敌机是否移出屏幕
if self.rect.y >= SSCREEN_RECT.height:
#将精灵从所有组中删除
self.kill()
##英雄登场
##01.设计英雄和子弹类
####英雄需求
1.游戏启动后英雄会出现在屏幕的水平中间位置,距离屏幕底部120像素
2.英雄每隔0.5秒发射一次子弹,每次连发三枚
3.英雄默认不会移动,需要通过左右方向键,控制英雄水平移动方向
####子弹需求
1.子弹从英雄的正上方发射沿直线向上方飞行
2.飞出屏幕后需要从精灵组中删除
####Hero——英雄
●初始化方法
。指定英雄图片
。初始速度=0–英雄默认静止不动
。定义bullets 子弹精灵组保存子弹精灵
●重写update0方法
。英雄需要水平移动
。并且需要保证不能移出屏幕
●增加bullets 属性,记录所有子弹精灵
●增加fire方法,用于发射子弹
##02.创建英雄
####2.1准备英雄类
- 在plane_sprites新建Hero类
- 重写初始化方法,直接指定图片名称,并且将初始速度设置为0
- 设置英雄的初始位置
| pyga.Rect |
| x,y |
| left,top,bottom,right,|
| size,width,height |
centerx = x + 0.5* width
centery = y + 0.5* width
bottom = y + height
class Hero(GameSprite):
“””英雄精灵”””
def init(self):
# 1.调用父类方法,设置image&speed
super().init(“./战机1.jpg”, 0)
# 2.设置英雄的初始位置
self.rect.centerx = SCREEN_RECT.centerx
self.rect.bottom = SCREEN_RECT.bottom - 120
####2.2绘制英雄
1.在__ create_sprites,添加精灵英雄和英雄精灵组
- 后续要针对英雄做碰撞检测以及子弹发射
- 所以英雄需要单独定义成属性
2.在_ update_ sprites,让英雄精灵组调用update和draw方法
代码实现
●修改__ create_ sprites方法如下:
self.hero_group.update()
self.hero_group.draw(self.screen)
##03.移动英雄位置
在 pygame中针对按键的捕获有两种方式
- 第一种方式判断 event.type == pygame.KEYDOWN
- 第二种方式
1.首先使用pygame.key.get()返回按键元组
2.通过按键常量,判断元组中某一个键是否被按下——如果被按下,对应值为1
●第一种方式(一按一动)
elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
print("向右移动…")
●第二种方式(可按住不放)
#返回所有按键的元组,如果某个键被按下,对应的值会是1
kwys_pressed = pygame.key.get_pressed()
#判断是否按下了方向键
if keys_pressed[pygame.K_RIGHT]:
print("向右移动…")
注:
●第一种方式 event.type 用户必须抬起按键才算一次 按键事件,操作灵活度大打折扣
●第二种方式用户可以按住方向按键不放,就能够实现持续向某一个方向移动了,操作灵活性更好
###3.1移动英雄位置
演练步骤
1.在Hero类中重写update方法
●用速度speed和英雄rect.x进行叠加
●不需要调用父类方法–父类方法只是实现了单纯的垂直运动
2.在gevent_handter方法中根据左右方向键设置英雄的速度
●向右=> speed=2
●向左=> speed=-2
●其他=> speed=0
代码演练
●在Hero类,写update()方法,根据速度水平移动英雄的飞机
def update(self):
# 英雄在水平方向的移动
self.rect.x += self.speed
●在__ event_ handler中添加移动方向
keys_pressed = pygame.key.get_pressed()
# 判断元组中对应的按键索引值 1
if keys_pressed[pygame.K_RIGHT]:
self.hero.speed = 1
elif keys_pressed[pygame.K_LEFT]:
self.hero.speed = -1
else:
self.hero.speed = 0
###3.2控制英雄运动边界
在Hero类的update()方法判断英雄是否超出屏幕边界
| pygame.Rect |
| x,y |
| left,top,bottom,right, |
| center,cernterx,centery |
| size,width,height|right = x + width 利用right属性可以非常容易的针对右侧设置精灵位置
##04.发射子弹
1.游戏启动后,英雄出现在屏幕的水平中间位置,距离屏幕底部120像
2.英雄每隔0.5秒发射次子弹,每次连发三枚子弹
3.英雄默认不会移动,需要通过左右方向键,控制英雄在水平方向移动
###4.1添加发射子弹事件
pygane的定时器使用套路手常固定:
1.义定时器常量–eventid
2.在初始化方法中,调用set _tiner方法设定时器事件
3.在游戏循环中,监听定时器事件
代码实现
●在Hero中定义fire方法
def fire(self):
print("发射子弹...)
###4.2定义子弹类
子弹需求
1.子弹从英雄的正上方发射沿直线向上方飞行
2.飞础屏幕后,需要从精灵组中删除
Bullt –子弹
●初始化方法
。指定子弹图片
。初始速度=-2–子弹需要向上方飞行
●重写update()方法
。判断是否飞出屏幕如果是,从精灵组删除
定义子弹类
●在plane sprites 新建Bullet 继承自GaneSprite
●重写初始化方法,直接指定图片名称并且设置初始速度
●写updatel)方法判断子弹飞础屏幕从精灵组删除
class Bullet(GameSprite):
"""子弹精灵"""
def __init__(self):
# 调用父类的方法,设置子弹图片,设置初始速度
super().__init__("./子弹的图片", -2)
def update(self):
# 调用父方法,让子弹研垂直方向飞行
super().update()
# 判断子弹是否飞出屏幕,如果是从精灵组删除
if self.rect.bottom < 0:
self.kill()
###4.3发射子弹
演练步骤
1.在Hero的初始化方法中创建子弹精灵组属性
2.修改plane. mainpy的_ update sprites方法让子弹精灵组调用update和draw 方法
3.实现fire()方法
●创建子弹精灵
●设置初始位置–在英雄的正上方
●将子弹添加到精灵组
代码实现
●初始化方法
# 创建子弹组
self.buttets = pygame.sprite.Group()
●修改fire()方法
def fire(self):
# 1.创建子弹精灵
bullet = Bullet()
# 2设置精灵的位置
bullet.rect.bottom = self.rect.y - 20
bullet.rect.centerx = self.rect.centerx
# 3将精灵添加精灵组
self.bullets.add(bullet)
##碰撞检测
##01.了解碰撞检测方法
pygam 提供了两个方便的方法可实现碰撞检测:
pygam.sprite.groupcpollide()两个精灵组中所有的精灵碰撞检测
groupllide(group1,group2,dokill1,dokill2,collide = None) —> Sprite_dic
如果将dokill设置为Ture则发生碰撞的精灵将被自动移除
collide参数是用于计算碰撞的回调函数
。如果没有指定,则每个精灵必须有一个rect属性
pygame.sprite.spritecollide()
*判断某个精灵和指定精灵组中的精灵的碰撞spritecollide(sprite, group, dokill, collide = None) —> Sprite_list(返回列表)
(dokill英雄飞机与敌机的碰撞检测,为Ture同归于尽,False安然无恙)






