专栏首页Crossin的编程教室【Pygame 第8课】 火力全开

【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的子弹,绘制它们。

如此一来,你可以不停地向敌机开火了。根据你电脑的运行状况,适当调整一下子弹的移动速度和发射间隔,让它看起来更自然。

至于敌机的行为,比子弹要简单一些,因为不需要定时出现,所以之前用的回收方法可以继续使用,我们下次再说。

PS:我们的QQ群眼看要接近满员了,所以我又新建了一个2号群,群号:156630350。继续欢迎大家来讨论。

面向零基础初学者的编程课

每天5分钟,轻松学编程

回复『 p 』查看python课程

回复『 g 』查看pygame课程

回复『 t 』查看习题

本文分享自微信公众号 - Crossin的编程教室(crossincode)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2013-08-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用 Pyqt5 制作猜数游戏 GUI

    在我们的 python 入门教程的最开始,用了一个 猜数字 的游戏作为讲解的案例。这个例子很小巧,但却能练习到 输入、输出、计算、条件判断、随机数 等知识点,所...

    Crossin先生
  • Python单例模式(Singleton)的N种实现

    很多初学者喜欢用全局变量,因为这比函数的参数传来传去更容易让人理解。确实在很多场景下用全局变量很方便。不过如果代码规模增大,并且有多个文件的时候,全局变量就会变...

    Crossin先生
  • 【Pygame 第6课】 面向对象的游戏设计

    上节课中,我们的飞机已经可以发射子弹了,尽管只有一颗。为什么我只加了一颗?试着多加几颗你就会发现,你得用好几个变量去分别记录它们的xy坐标,在主循环中判断每一颗...

    Crossin先生
  • 【强化学习】DQN 在运筹学中的应用

    前段时间给出了 Q-Learning 在排班调度中的应用,现在给出 DQN 的实现。

    阿泽 Crz
  • VR+全景播放器+头控讲解-06

    在UIView上面布局我们可以使用UIButton UIView UIImageView等,但是是在3D场景中,我们不能使用UIView,我们要使用平面几何当视...

    酷走天涯
  • 数据结构-数组

    工作了一段时间后,发现基础实在是太重要了,老话说: 万丈高楼平地起。地基不牢,肯定跑不快,天花板也愈发明显。

    用户1081422
  • 巅峰极客 第二场 WriteUp

    1 返回地址覆盖为printf(func_got)/write(1,func_got,4)来leak libc,并将printf/write返回地址设为game...

    ChaMd5安全团队
  • 司机撞小狗事件的分析

    今天我从北校区坐校车去西校区,在路上突然出现了一直很可爱的小狗,司机为了躲避小狗,采取的措施是减速,换道。

    Defu Li
  • IOS 读取设备中的所有照片

    1 class ViewController:UIViewController,UIImagePickerControllerDelegate,UINaviga...

    用户5760343
  • [论文品读]·d-vector解读(Deep Neural Networks for Small Footprint Text-Dependent Speaker Verification)

    在本文中,我们研究深度神经网络(DNNs)在小型文本相关的说话者验证任务的应用。在开发阶段,DNN经过训练,可以在帧级别对说话人进行分类。在说话人录入阶段,使用...

    小宋是呢

扫码关注云+社区

领取腾讯云代金券