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_y
和number_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)
现在我们运行程序,会发现外星人在碰到边缘以后会向下移并反向。
后续内容详见下节博客。
本文来自作者:CK_0ff,转载请注明原文链接:https://www.cnblogs.com/Ck-0ff/p/15856967.html