Python学习之路日志—利用pygame开发《外星人入侵》游戏项目(3)

4.1 添加射击功能:

为了添加射击功能。我们将编写玩家按空格键时发射子弹(小矩形)的代码。子弹将在屏幕中向上穿行,抵达屏幕上边缘后消失,首先,更新settings.py来添加子弹设置:

在这里插入图片描述

如11-14行所示,这些设置创建宽3像素、高15像素的深灰色子弹。子弹的速度比飞船稍低。

下面来创建存储 Bullet 类的文件bullet.py

在这里插入图片描述

简要分析一下:

  1. Bullet 类继承了我们从模块pygame.sprite中导入的 Sprite 类。通过使用 Sprite,可将游戏中相关的元素编组,进而同时操作编组中的所有元素(第二行处)。

  2. 在12行处,我们创建了子弹的属性rect 。子弹并非基于图像的,因此我们必须使用pygame.Rect() 类从空白开始创建一个矩形。创建这个类的实例时,必须提供矩形左上角的 x 坐标和 y 坐标,还有矩形的宽度和高度。我们在(0, 0)处创建这个矩形,但接下来的两行代码将其移到了正确的位置。

  3. 子弹应从飞船顶部射出,因此我们将表示子弹的recttop属性设置为飞船的recttop属性,让子弹看起来像是从飞船中射出的(15行)。

  4. 在18行,我们将子弹的 y 坐标存储为小数值,以便能够微调子弹的速度。

  5. 在20-21行处,我们将子弹的颜色和速度设置分别存储到self.colorself.speed_factor 中。

  6. 方法update() 管理子弹的位置。发射出去后,子弹在屏幕中向上移动,这意味着y坐标将不断减小,因此为更新子弹的位置,我们从self.y 中减去self.speed_factor 的值(见26行)。接下来,我们将self.rect.y 设置为self.y 的值(见27行)。属性speed_factor 让我们能够随着游戏的进行或根据需要提高子弹的速度,以调整游戏的行为。子弹发射后,其 x 坐标始终不变,因此子弹将沿直线垂直地往上穿行。

  7. 需要绘制子弹时,我们调用draw_bullet() 。函数draw.rect() 使用存储在self.color 中的颜色填充表示子弹的rect占据的屏幕部分。


4.2 将子弹存储到编组中:

在这里插入图片描述

我们导入了pygame.sprite 中的Group类。在16行处,我们创建了一个Group实例,并将其命名为bullets 。这个编组是在 while 循环外面创建的,这样就无需每次运行该循环时都创建一个新的子弹编组。

我们将bullets传递给了check_events()update_screen() 。在check_events() 中,需要在玩家按空格键时处理bullets ;而在update_screen() 中,需要更新要绘制到屏幕上的bullets

当你对编组调用update() 时,编组将自动对其中的每个sprite调用update() ,因此代码行bullets.update() 将为编组bullets 中的每颗子弹调用bullet.update()


4.3 控制飞船发射子弹:

在这里插入图片描述

  1. 编组bullets传递给了check_keydown_events() (见第6行)。玩家按空格键时,创建一颗新子弹(一个名为new_bulletBullet 实例),并使用方法add() 将其加入到编组bullets中(见13-14行);代码bullets.add(new_bullet) 将新子弹存储到编组bullets 中。

  2. check_events() 的定义中,我们需要添加形参bullets (见23行处);调用check_keydown_events() 时,我们也需要将bullets 作为实参传递给它。

  3. 在32行处,我们给在屏幕上绘制子弹的update_screen() 添加了形参bullets 。方法bullets.sprites() 返回一个列表,其中包含编组bullets 中的所有精灵。为在屏幕上绘制发射的所有子弹,我们遍历编组bullets中的精灵,并对每个精灵都调用draw_bullet() (见35-36行)。

如图所示,如果此时运行alien_invasion.py,将能够左右移动飞船,并发射任意数量的子弹。子弹在屏幕上向上穿行,抵达屏幕顶部后消失:

在这里插入图片描述


4.4 删除已经消失的子弹:

在这里插入图片描述

在 for 循环中,不应从列表或编组中删除条目,因此必须遍历编组的副本。我们使用了方法copy() 来设置for 循环(25行处),这让我们能够在循环中修改bullets 。我们检查每颗子弹,看看它是否已从屏幕顶端消失(见第26行)。如果是这样,就将其从bullets 中删除(27行处)。在第28行,我们使用了一条 print 语句,以显示当前还有多少颗子弹, 从而核实已消失的子弹确实删除了。 如果这些代码没有问题,如下图所示,我们发射子弹后查看终端窗口时,将发现随着子弹一颗颗地在屏幕顶端消失,子弹数将逐渐降为零。运行这个游戏并确认子弹已被删除后,便可以将这条 print 语句删除:

在这里插入图片描述
在这里插入图片描述


4.5 限制子弹的数量:

首先,我们需要在settings.py中存储所允许的最大子弹数:

在这里插入图片描述

这将未消失的子弹数限制为3颗。在game_functions.pycheck_keydown_events() 中,我们在创建新子弹前检查未消失的子弹数是否小于该设置

在这里插入图片描述

玩家按空格键时,我们检查bullets 的长度。如果len(bullets) 小于3,我们就创建一个新子弹;但如果已有3颗未消失的子弹,则玩家按空格键时什么都不会发生。如下图所示,现在运行这个游戏,屏幕上最多只能有3颗子弹:

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值