Python 外星人入侵游戏(二):外星人(上)

您所在的位置:网站首页 外星人图像怎么画 Python 外星人入侵游戏(二):外星人(上)

Python 外星人入侵游戏(二):外星人(上)

2024-07-01 16:07| 来源: 网络整理| 查看: 265

来源:《Python编程:从入门到实践》

文章目录 12 创建第一个外星人2.1 创建Alien类2.2 创建Alien实例2.3 让外星人出现在屏幕上 3 创建一群外星人3.1 确定一行可容纳多少个外星人3.2 创建多行外星人3.3 创建外星人群3.4 重构create_fleet()3.5 添加行 4 让外星人群移动4.1 向右移动外星人4.2 创建表示外星人移动方向的设置4.3 检查外星人是否撞到了屏幕边缘4.4 向下移动外星人群并改变移动方向 5 射杀外星人5.1 检测子弹与外星人的碰撞5.2 为测试创建大子弹5.3 生成新的外星人群5.4 提高子弹的速度5.5 重构update_bullets()

1 在这部分将给游戏添加外星人下面开始工作之前,先添加一个结束游戏的快捷键Q:要不每次运行游戏时,都必须用鼠标来关闭它,实在麻烦

game_functions.py

def check_keydown_events(event, ai_settings, screen, ship, bullets): --snip-- elif event.key == pygame.K_q: sys.exit() 2 创建第一个外星人 在屏幕上放置外星人与放置飞船类似每个外星人的行为都有Alien类控制,我们将像创建Ship类那样创建这个类外星人图像可在本书配套资源找到,将其保存在文件夹images中 2.1 创建Alien类

alien.py

import pygame from pygame.sprite import Sprite class Alien(Sprite): """表示单个外星人的类""" def __init__(self, ai_settings, screen): """初始化外星人并设置其起始位置""" super().__init__() self.screen = screen self.ai_settings = ai_settings # 加载外星人图像,并设置其rect属性 self.image = pygame.image.load('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) def blitme(self): """在指定位置绘制外星人""" self.screen.blit(self.image, self.rect) 除位置不同外,大部分代码都与Ship类相似每个外星人最初都位于屏幕左上角附近,每个外星人的左边距都设置为外星人的宽度,并将上边距设置为外星人的高度 2.2 创建Alien实例

alien_invasion.py

--snip-- from alien import Alien import game_functions as gf def run_game(): --snip-- # 创建一个外星人 aline = Alien(ai_settings, screen) # 开始游戏的主循环 while True: gf.check_events(ai_settings, screen, ship, bullets) ship.update() gf.update_bullets(bullets) gf.update_screen(ai_settings, screen, ship, alien, bullets) run_game() 值得注意的,修改了 对update_screen()的调用,传递了一个外星人实例 2.3 让外星人出现在屏幕上 为让外星人出现在屏幕上,在update_screen()中调用其方法blitme():

game_functions.py

def update_screen(ai_settings, screen, ship, alien, bullets): --snip-- # 在飞船和外星人后面重绘所有子弹 for bullet in bullets.sprites(): bullet.draw_bullet() ship.blitme() alien.blitme() # 让最近绘制的屏幕可见 pygame.display.flip() 先绘制飞船和子弹,再绘制外星人,让外星人在屏幕位于最前面 在这里插入图片描述 3 创建一群外星人 需要确定一行容纳多少个外星人以及要绘制多少行外星人 3.1 确定一行可容纳多少个外星人 可用于放置外星人的水平空间为屏幕宽度(ai_settings.screen_width)减去外星人宽度(alien_width)的两倍: available_space_x = ai_settings.screen_width - (2 * alien_width) 一个宽度用于放置外星人,另一个宽度为外星人右边的空白区域。确定一行可容纳多少个外星人,将可用空间除以外星人宽度的两倍 number_aliens_x = int(available_space_x / ( 2 * alien_width)) 3.2 创建多行外星人 创建一行外星人,首先在alien_invasion.py中创建一个名为aliens的空编组,用于存储全部外星人

alien_invasion.py

import pygame from pygame.sprite import Group from settings import Settings from ship import Ship import game_functions as gf def run_game(): --snip-- # 创建一艘飞船、一个子弹编组和一个外星人编组 ship = Ship(ai_settings, screen) bullets = Group() aliens = Group() # 创建外星人群 gf.create_fleet(ai_settings, screen, aliens) # 开始游戏的主循环 while True: --snip-- gf.update_screen(ai_settings, screen, ship, aliens, bullets) run_game() 由于不在alien_invasion.py中直接创建外星人,因此无需在这个文件中导入Alien类修改update_screen():

game_functions.py

def update_screen(ai_settings, screen, ship, aliens, bullets): --snip-- ship.blitme() aliens.draw(screen) # 让最近绘制的屏幕可见 pygame.display.flip() aliens.draw(screen)在屏幕上绘制编组的每个外星人 3.3 创建外星人群 现在可以创建外星人群了。下面是新函数create_fleet(),将它放在game_functions.py的末尾还需要导入Alien类

game_functions.py

--snip-- from bullet import Bullet from alien import Alien --snip-- def create_fleet(ai_settings, screen, ship, aliens): """创建外星人群""" # 创建一个外星人,并计算一行可容纳多少个外星人 # 外星人间距为外星人宽度 alien = Alien(ai_settings, screen) alien_width = alien.rect.width available_space_x = ai_settings.screen_width - 2 * alien_width number_aliens_x = int(available_space_x / ( 2 * alien_width)) # 创建第一行外星人 for alien_number in range(number_aliens_x): """创建一个外星人将其放在当前行""" alien = Alien(ai_settings, screen) alien.x = alien_width + 2 * alien_width * alien_number alien.rect.x = alien.x aliens.add(alien)

在这里插入图片描述

3.4 重构create_fleet()

game_functions.py

def get_number_aliens_x(ai_settings, alien_width): """计算每行可容纳多少个外星人""" available_space_x = ai_settings.screen_width - 2 * alien_width number_aliens_x = int(available_space_x / ( 2 * alien_width)) return number_aliens_x def create_alien(ai_settings, screen, aliens, alien_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 aliens.add(alien) def create_fleet(ai_settings, screen, ship, aliens): """创建外星人群""" # 创建一个外星人,并计算一行可容纳多少个外星人 alien = Alien(ai_settings, screen) number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width) # 创建第一行外星人 for alien_number in range(number_aliens_x): create_alien(ai_settings, screen, aliens, alien_number) 3.5 添加行 创建外星人群,需要计算屏幕可容纳多少行,并对创建一行外星人的循环重复相应的次数为计算可容纳的行数: 先计算可用垂直空间:将屏幕高度减去第一行外星人的上边距(外星人高度)、飞船的高度以及最初外星人高度加上外星人间距(外星人高度的两倍): available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height) 这将在飞船上方留出一定的空白区域,给玩家留出射杀外星人的时间每行下方都要留出一定的空白区域,并将其设置为外星人的高度下面计算可容纳的行数,将可用垂直空间除以外星人高度的两倍: number_rows = int(available_space_y / (2 * alien_height)) 知道可容纳多少行后,便可重复执行创建一行外星人的代码:

game_functions.py

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): --snip-- alien.x = alien_width + 2 * alien_width * alien_number alien.rect.x = alien.x alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number aliens.add(alien) def create_fleet(ai_settings, screen, ship, aliens): --snip-- number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.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) 在create_fleet()的定义中,还增加了一个用于存储ship对象的形参,因此在alien_invasion.py中调用create_fleet()时,需要传递实参ship:

alien_invasion.py

gf.create_fleet(ai_settings, screen, ship, aliens) 现在运行这个游戏,将看到一群外星人: 在这里插入图片描述 4 让外星人群移动 下面让外星人群在屏幕上向右移动,撞到屏幕边缘后下移一定的距离,再沿反方向移动 4.1 向右移动外星人 为移动外星人,将使用alien.py中的方法update(),且对外星人群中的每个外星人都调用它。首先,添加一个控制外星人速度的设置:

settings.py

def __init__(self): --snip-- # 外星人设置 self.alien_speed_factor = 1 然后,使用这个设置来实现update():

alien.py

def update(self): """向右移动外星人""" self.x += self.ai_settings.alien_speed_factor self.rect.x = self.x 主while循环中已调用了更新ship和bullets的方法,但现在还需要更新每个外星人的位置

alien_invasion.py

# 开始游戏的主循环 while True: gf.check_events(ai_settings, screen, ship, bullets) ship.update() gf.update_bullets(bullets) gf.update_aliens(aliens) gf.update_screen(ai_settings, screen, ship, aliens, bullets) 接着再game_functions.py末尾添加新函数update_aliens():

game_functions.py

def update_aliens(aliens): """更新外星人群中所有外星人的位置""" aliens.update() 如果现在运行这个游戏,会看到外星人群向右移,并在屏幕右边缘消失 4.2 创建表示外星人移动方向的设置 下面创建让外星人撞到屏幕右边缘后向下移动、再向左移动的设置:

settings.py

def __init__(self): --snip-- # 外星人设置 self.alien_speed_factor = 1 self.fleet_drop_speed = 10 # fleet_direction为1表示向右移,为-1表示向左移 self.fleet_direction = 1 fleet_drop_speed指定了外星人撞到屏幕边缘时,外星人群向下移动的速度(将这个速度与水平速度分开是好的,这样就可以分别调整这两种速度了)要实现fleet_direction设置,可将其设置为文本值,如’left’ or ‘right’,但这样做就必须编写if-elif语句来检查外星人群的移动方向。鉴于只有这两个可能的方向,我们使用值1和-1来表示它们,并在外星人群改变方向时在这两个值之间切换 4.3 检查外星人是否撞到了屏幕边缘

alien.py

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


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3