【Pygame 课堂】第8课—— 火力全开
游戏中的几个主要角色我们都有了,接下来就是去完善它们,用它们来组成一个完整的游戏。
首先我们要处理的是子弹。只有一发子弹显然是不够的,群众表示要火力全开!
所以,我们要有一个list,这里list里面存放着一些Bullet的对象。但一个list的Bullet都按之前的方法创建是不行的,那样所有的子弹都会在同一时间发射出去,同时到达屏幕上方,又同时再次发射,这样的视觉效果和一发子弹没什么区别。所以我们要让它们按照一定的时间间隔,一个一个地发射。
另外,之前到了屏幕顶端就回头的方法也会带来问题,重新发射的子弹会和按时发射的子弹混在一起,打乱发射的节奏。所以,子弹“回收”的方法也要改。有种最简单的方法,就是不回收,每次发射都是创建一个新的Bullet对象,飞出屏幕之后就抛弃它。这当然是可以的,但每次都要创建对象,读取图片,并在list上做添加和删除的操作。这样会比较消耗资源,在游戏开发中一般都尽量避免。即使现在这个小游戏中它还不至于影响到体验,也应该养成节约的良好习惯。
我们今天要解决的就是两个问题:定时和回收。
python中有定时运行的方法。但这里,我不打算用它。技能培训我们有现成的循环在这儿,只要设定好隔多少次循环运行,就简单地实现了定时的效果。尽管在游戏中,每次循环的时间并不相同,这么做会有潜在的问题:间隔的真实时间会受电脑运行速度的影响。但暂时你可以忽略这个细节(它是有解决办法的)。
我们设定一个变量interval_b,作为Bullet的发射间隔。在每次循环中,让interval_b递减,当减到0以下时,便运行,并重置interval_b的间隔。
interval_b = 0
while True:
interval_b -= 1
#当间隔小于0时,激活一发子弹
if interval_b < 0:
###(发射子弹代码)
interval_b = 100
关于子弹的重复利用,我们增加一个变量active,只有active为True的子弹,我们才去处理它的运动。另外,为了依次使用list中有限的子弹,还需要一个变量index_b来记录下一颗子弹是第几号。每激活发射一颗子弹,就把index_b指向它的下一号,最后一号之后再回头使用第0号。
修改一下Bullet类,增加active,并根据active的状态处理运动。增加一个restart方法,用来重新发射子弹。
class Bullet:
def __init__(self):
self.x = 0
self.y = -1
self.image = pygame.image.load('bullet.png').convert_alpha()
#默认不激活
self.active = False
def move(self):
#激活状态下,向上移动
if self.active:
self.y -= 3
#当飞出屏幕,就设为不激活
if self.y < 0:
self.active = False
def restart(self):
#重置子弹位置
mouseX, mouseY = pygame.mouse.get_pos()
self.x = mouseX – self.image.get_width() / 2
self.y = mouseY – self.image.get_height() / 2
#激活子弹
self.active = True
在游戏中创建5发子弹的list(5发足够了,只要保证你的子弹数足够在打完一轮之前到达屏幕顶端)。
#创建子弹的list
bullets = []
#向list中添加5发子弹
for i in range(5):
bullets.append(Bullet())
#子弹总数
count_b = len(bullets)
#即将激活的子弹序号
index_b = 0
#发射子弹的间隔
interval_b = 0
时间间隔到达时,restart一颗子弹,并将序号递增。
while True:
#发射间隔递减
interval_b -= 1
#当间隔小于0时,激活一发子弹技能培训
if interval_b < 0:
bullets[index_b].restart()
#重置间隔时间
interval_b = 100
#子弹序号周期性递增
index_b = (index_b + 1) % count_b
#判断每个子弹的状态
for b in bullets:
#处于激活状态的子弹,移动位置并绘制
if b.active:
b.move()
screen.blit(b.image, (b.x, b.y))
只处理active的子弹,绘制它们。
如此一来,你可以不停地向敌机开火了。根据你电脑的运行状况,适当调整一下子弹的移动速度和发射间隔,让它看起来更自然。
至于敌机的行为,比子弹要简单一些,因为不需要定时出现,所以之前用的回收方法可以继续使用,技能培训我们下次再说。
文章来源于Crossin,由课课家在线学习平台整理,转载请注明。