Pygame 外星人入侵(6)外星人大军

Pygame 外星人入侵(6)外星人大军


直到上一篇博文为止,我们实现了游戏屏幕的绘制、飞船的绘制、飞船的移动以及子弹的绘制和发射。

之后将要实现的是外星人的绘制。
在这里插入图片描述

大致分为这几步:
1、绘制单个外星人
2、绘制一行外星人
3、绘制一群外星人

一、绘制单个外星人

回想我们当时绘制飞船的方法,其实绘制单个外星人的方法与之类似,我们将第一个外星人创建在屏幕左上角,同时要能将这个外星人绘制到屏幕上

1、初始化外星人

新建 alien 模块,在模块中定义 Alien 类,继承自 精灵类,因为我们之后要通过编组来管理一群外星人。
首先,我们从位图中导入外星人的图像,将其初始化到屏幕左上角

# 外星人类,管理外星人的所有行为
class Alien(Sprite):
    # 初始化一只外星人,创建时使其位于屏幕的左上角附近
    def __init__(self, screen, settings):
        super(Alien, self).__init__()
        self.screen = screen
        self.settings = settings
        # 载入外星人图片
        self.image = pygame.image.load(r'images\alien.bmp')
        # 获取外星人的坐标变量
        self.rect = self.image.get_rect()
        # 通过坐标,控制外星人初始化时在屏幕左上角
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
        # 获取外星人的准确位置
        self.x = float(self.rect.x)

2、将外星人绘制到屏幕左上角

# 绘制外星人到屏幕上
def blitme(self):
    self.screen.blit(self.image, self.rect)

可以发现,其实绘制一个外星人 和 绘制飞船的逻辑是一样的,现在只要在主模块中实例化外星人对象,并修改 update_screen()函数即可显示。

3、修改update_screen()

将新创建的 外星人对象传入函数中,并在函数体中调用绘制外星人的方法

def update_screen(screen, setting, ship, bullets, alien):
    # 为纯黑的游戏屏幕填充上不一样的颜色
    screen.fill(setting.background_color)

    # 在背景之上绘制我们的飞船,注意这里的逻辑,必须是飞船在背景之后绘制,确保飞船在背景的上层
    ship.blitme()

    # 在屏幕和飞船之上,绘制子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()

    # 在屏幕上绘制外星人
    alien.blitme()

    # 刷新屏幕,使得元素能够不断刷新位置
    pygame.display.flip()

二、绘制一行外星人

我们可以在创建一个外星人的基础上,通过编组来保存一行外星人,每个外星人的横坐标以一定的规律递增,这一环节大概需要分成这样几步:
1、获取一行上能绘制多少个外星人
2、创建外星人编组
3、循环创建外星人

1、每行要绘制多少个外星人

我们希望屏幕上的外星人不要太密集,因此这样设计:
1、在屏幕两侧留出空白部分,空白部分的长度即为外星人的宽度
2、外星人之间留出间隙,间隙的宽度也是外星人的宽度

# 求出一行上可以容纳多少只外星人
def get_number_aliens_x(settings, alien_width):
    # 首先要知道一行可以容纳多少只外星人
    available_space_x = settings.screen_width - 2 * alien_width
    number_aliens_x = int(available_space_x / (2 * alien_width))
    return number_aliens_x

2、循环生成一行外星人

在求出外星人数量的基础上,循环生成一系列外星人,每一个生成的外星人的横坐标都会递增

# 创建一行外星人的方法
def create_fleet(settings, screen, aliens, ship):
    # 创建一只外星人,我们要通过这只外星人的数据来作一些处理
    alien = Alien(screen, settings)
    # 获取一行上外星人的数量
    number_aliens_x = get_number_aliens_x(settings, alien.rect.width
    # 创造一行外星人
    for alien_number in range(number_aliens_x):
        create_alien(screen, settings, aliens, alien_number)

3、修改主模块

现在我们可以生成一系列外星人了,这些外星人需要通过编组来保存,参考绘制子弹时我们用 Group 对象来保存子弹的做法,此处也可以用相同的方法。然后修改update_screen()函数,绘制编组中的每一个外星人对象。

# 初始化一个外星人队列,用于存放所有外星人
aliens = Group()
def update_screen(screen, setting, ship, bullets, aliens):
    # 为纯黑的游戏屏幕填充上不一样的颜色
    screen.fill(setting.background_color)

    # 在背景之上绘制我们的飞船,注意这里的逻辑,必须是飞船在背景之后绘制,确保飞船在背景的上层
    ship.blitme()

    # 在屏幕和飞船之上,绘制子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()

    # 在屏幕上绘制外星人
    aliens.draw(screen)

    # 刷新屏幕,使得元素能够不断刷新位置
    pygame.display.flip()

对编组调用 draw 函数会自动绘制编组内的内一个精灵对象。

至此,运行程序就可以实现在屏幕上方显示一行外星人了。

三、绘制一群外星人

1、总共要绘制多少行外星人

由于我们的屏幕有限,而且必须给飞船和外星人之间留出一定的缓冲区域,因此可以这样来设计外形大军:
1、屏幕上方留出空白,空白高度等于外星人高度
2、飞船顶部到外形大军底部之间留出缓冲区,缓冲区高度为外星人高度的2倍
3、留出飞船的高度,供飞船飞行

# 求出在屏幕上可以容纳多少行外星人
def get_number_aliens_y(settings, alien_height, ship_height):
    available_space_y = settings.screen_height - 3 * alien_height - ship_height
    number_aliens_y = int(available_space_y / (2 * alien_height))
    return number_aliens_y

2、循环绘制一群外星人

我们现在知道了每行要绘制多少外星人,以及总共要绘制多少行外星人。
现在就可以修改 create_fleet() 函数来绘制一群外星人了

# 创建一群外星人的方法
def create_fleet(settings, screen, aliens, ship):
    # 创建一只外星人,我们要通过这只外星人的数据来作一些处理
    alien = Alien(screen, settings)
    # 获取一行上外星人的数量
    number_aliens_x = get_number_aliens_x(settings, alien.rect.width)
    # 获取屏幕上总共需要多少行外星人
    number_rows = get_number_aliens_y(settings, alien.rect.height, ship.rect.height)
    for number_row in range(number_rows):
        # 创造一行外星人
        for alien_number in range(number_aliens_x):
            create_alien(screen, settings, aliens, alien_number, number_row)

同时,将生成外星人实例的方法封装起来

# 生成外星群中的每一个外星人
def create_alien(screen, settings, aliens, alien_number, number_row):
    alien = Alien(screen, settings)
    alien_width = alien.rect.width
    alien_height = alien.rect.height
    alien.x += alien_width + 2 * alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien_height + 2 * alien_height * number_row
    aliens.add(alien)

此时,我们不需要再修改主模块的代码,因为我们可以使用之前显示一行外星人时的编组来保存现在的一群外星人
在这里插入图片描述
至此,我们就完成了外星人大军的绘制。

四、小结

游戏开发到这个时期,在增加新对象新功能时,已经能很自然地联想到之前用过地模块和方法,不需要用到新东西,当时是在对前面内容充分理解的基础上。
同时,”简化“代码的习惯慢慢开始养成,做完一个功能之后,先不马上去想下一个功能如何实现,而是先将可以封装的代码封装起来。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值