Python学习笔记(十)--游戏项目(5)

添加外星人行

要创建外星人群,需要计算屏幕可容纳多少行,并对创建一行外星人的循环重复相应的次数。
为计算可容纳的行数,我们这样计算可用垂直空间:将屏幕高度减去第一行外星人的上边距(外星人高度)、飞船的高度以及最初外星人群与飞船的距离(外星人高度的两倍):

available_space_y = ai_settings.screen_height – 3 * alien_height – ship_height

这将在飞船上方留出一定的空白区域,给玩家留出射杀外星人的时间。
每行下方都要留出一定的空白区域,并将其设置为外星人的高度。为计算可容纳的行数,我们将可用垂直空间除以外星人高度的两倍(同样,如果这样的计算不对,我们马上就能发现,继而将间距调整为合理的值)。

number_rows = available_height_y / (2 * alien_height)

知道可容纳多少行后,便可重复执行创建一行外星人的代码:

def get_number_rows(ai_settings, ship_height, alien_height):
    """计算屏幕可容纳多少行外星人"""
    available_space_y = (ai_settings.screen_height -
                         (3 * alien_height) - ship_height)
    number_rows = int(available_space_y / (2 * alien_height))
    return number_rows

def create_alien(ai_settings, screen, aliens, alien_number, row_number):
    """创建一个外星人并将其放在当前行"""
    alien = Alien(ai_settings, screen)
    alien_width = alien.rect.width
    alien.x = alien_width + 2 * alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien.rect.height + 2 * alien.rect.h * row_number
    aliens.add(alien)

def create_fleet(ai_settings, screen, ship, aliens):
    """创建外星人群"""
    # 创建一个外星人,并计算一行可容纳多少个外星人
    # 外星人间距为外星人宽度
    alien = Alien(ai_settings, screen)
    alien_width = alien.rect.width
    number_aliens_x = get_number_aliens_x(ai_settings, alien_width)
    number_rows = get_number_rows(ai_settings, ship.rect.height,
                                  alien.rect.height)

    # 创建外星人群
    for row_number in range(number_rows):
        for alien_number in range(number_aliens_x):# 创建一个外星人并将其加入当前行
            create_alien(ai_settings, screen, aliens, alien_number,
                        row_number)

为计算屏幕可容纳多少行外星人,我们在函数get_number_rows()中实现了前面计算available_space_ynumber_rows的公式。

create_fleet() 的定义中, 还新增了一个用于存储ship 对象的形参, 因此在
alien_invasion.py中调用create_fleet()时,需要传递实参ship:

alien_invasion.py

# 创建外星人群
gf.create_fleet(ai_settings, screen, ship, aliens)

让外星人移动

下面来让外星人群在屏幕上向右移动,撞到屏幕边缘后下移一定的距离,再沿相反的方向移动。我们将不断地移动所有的外星人,直到所有外星人都被消灭,有外星人撞上飞船,或有外星人抵达屏幕底端。下面先来让外星人向右移动。

向右移动外星人

为移动外星人,我们将使用alien.py中的方法update(),且对外星人群中的每个外星人都调用它。

首先,添加一个控制外星人速度的设置:
settings.py

class Settings():
    """存储《外星人入侵》的所有设置的类"""
    def __init__(self):
        """初始化游戏的设置"""
        # 屏幕设置
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230, 230, 230)

        # 飞船的设置
        self.ship_speed_factor = 1.5

        # 子弹设置
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60,60,60
        
        # 外星人设置
        self.alien_speed_factor = 1

然后,使用这个设置来实现update()
alien.py


    def update(self):
        """向右移动外星人"""
        self.x += self.ai_settings.alien_speed_factor
        self.rect.x = self.x

alien_invasion.py

    # 游戏主循环
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        bullets.update()
        gf.update_aliens(aliens)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

game_functions.py

def update_aliens(aliens):
    """更新外星人群中所有的外星人的位置"""
    aliens.update()

我们对编组aliens调用方法update(),这将自动对每个外星人调用方法update()。如果你现在运行这个游戏,会看到外星人群向右移,并逐渐在屏幕右边缘消失。

创建表示外星人移动方向的设置

下面来创建让外星人撞到屏幕右边缘后向下移动、再向左移动的设置。
settings.py

# 外星人设置
        self.alien_speed_factor = 1
        self.fleet_drop_speed = 10
        # flee_direction 为1表示向右移,为-1表示向左移动
        self.fleet_diretion = 1

设置fleet_drop_speed指定了有外星人撞到屏幕边缘时,外星人群向下移动的速度。将这个速度与水平速度分开是有好处的,这样你就可以分别调整这两种速度了。

检查外星人是否撞到了屏幕边缘

现在需要编写一个方法来检查是否有外星人撞到了屏幕边缘,还需修改update(),以让每个外星人都沿正确的方向移动。

    def check_edges(self):
        """如果外星人位于屏幕边缘,就返True"""
        screen_rect =self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True

    def update(self):
        """向左或者向右移动外星人"""
        self.x += (self.ai_settings.alien_speed_factor *
                        self.ai_settings.fleet_direction)
        self.rect.x = self.x

有外星人到达屏幕边缘时,需要将整群外星人下移,并改变它们的移动方向。我们需要对game_functions.py做重大修改,因为我们要在这里检查是否有外星人到达了左边缘或右边缘。为此,我们编写函数check_fleet_edges()change_fleet_direction(),并对update_aliens()进行修改:
game_functions.py

def check_fleet_edges(ai_settings, aliens):
    """有外星人到达边缘时采取响应的措施"""
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings, aliens)
            break


def change_fleet_direction(ai_settings, aliens):
    """将整群外星人下移,并改变他们的方向"""
    for alien in aliens.sprites():
        alien.rect.y += ai_settings.fleet_drop_speed
    ai_settings.fleet_direction *= -1

def update_aliens(ai_settings, aliens):
    """检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""
    check_fleet_edges(ai_settings, aliens)
    aliens.update()

我们修改了函数update_aliens(),在其中通过调用check_fleet_edges()来确定是否有外星人位于屏幕边缘。现在,函数update_aliens()包含形参ai_settings,因此我们调用它时指定了与ai_settings对应的实参:
alien_invasion.py

# 游戏主循环
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_aliens(ai_settings, aliens)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

现在我们运行程序,会发现外星人在碰到边缘以后会向下移并反向。
在这里插入图片描述
后续内容详见下节博客。

posted @ 2022-01-30 15:33  CK_0ff  阅读(53)  评论(0编辑  收藏  举报