来源于《Python编程从入门到实践》的13章外星人来了。

此为第二阶段:

Python-项目实战-《外星人入侵》Pygame小游戏-阶段一:武装飞船(含教程)_Kox233的博客-CSDN博客


目录

程序描述:

开发步骤:

1)创建第一个外星人

1.1)创建 Alien 类

1.2)创建 Alien 实例

2)创建一群外星人

2.1)创建一行外星人

2.2)重构_create_fleet()

2.3)添加行

3)让外星人群移动

3.1)向右移动外星人群

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

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

3.4)向下移动外星人群并改变移动方向

4)射杀外星人

4.1)检测子弹与外星人的碰撞

4.2)生成新的外星人群

4.3)提高子弹速度

4.4)重构_update_bullets()

5)结束游戏

代码:

alien.py

alen_invasion.py

bullet.py

game_stats.py

settings.py

ship.py


程序描述:

此程序为《外星人入侵》开发的第二个阶段。

主要功能是生成一群外星人,这群外星人能够向两边和下面移动,玩家可以用子弹攻击外星人。被击中的外星人将会被删除。

开发步骤:

1)创建第一个外星人

所需素材图片:

alien.bmp

1.1)创建 Alien 类

编写Alien类并将其保存为文件 alien.py

alien.py

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""表示单个外星人的类"""def __init__(self, ai_game):"""初始化外星人并设置其起始位置"""super().__init__()self.screen = ai_game.screen# 加载外星人图像并设置其 rect 属性self.image = pygame.image.load('images/alien.bmp')self.rect = self.image.get_rect()# 让每个外星人最初都在屏幕左上角附近。self.rect.x = self.rect.widthself.rect.y = self.rect.height# 存储外星人的精确水平位置self.x = float(self.rect.x)

1.2)创建 Alien 实例

下面是 alien_invasion.py 中修改后的 import 语句:

alien_invasion.py

下面是修改后的方法__init__():

alien_invasion.py

创建了一个用于存储外星人群的编组,还调用了接下来将编写的方法_create_fleet()。

下面是新编写的方法_create_fleet():

alien_invasion.py

要让外星人现身,需要在_update_screen()中对外星人编组调用方法draw():

alien_invasion.py

现在屏幕上就能够显示一个外星人了。

2)创建一群外星人

要绘制一群外星人,需要确定一行能容纳多少个外星人以及要绘制多少行。我们将首先计算外星人的水平间距并创建一行外星人,在确定可用的垂直空间并创建整群外星人。

2.1)创建一行外星人

重写_create_fleet()使其创建一行外星人:

alien_invasion.py

 如果现在运行游戏将会看到一行外星人

2.2)重构_create_fleet()

alien_invasion.py

2.3)添加行

alien_invasion.py

现在运行将会看到一群外星人

3)让外星人群移动

接下来将让外星在屏幕上向右移动,撞到屏幕边缘后下移一定的量,再沿相反的方向移动。我们将不断移动所有外星人,直到外星人被全部消灭,或者有外星人撞上飞船或抵达屏幕底端。

3.1)向右移动外星人群

为移动外星人群,将使用 alien.py 中的方法 update()。首先,添加一共控制外星人速度的设置:

settings.py

再使用这个设置来实现 update():

alien.py

调用更新每个外星人位置的办法:

alien_invasion.py

新建一给名为_update_aliens()的方法,来管理外星人群的移动。放在方法_update_bullets()的后面。

alien_invasion.py

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

实现外星人撞到右边缘后向下移动、再向左移动设置:

settings.py

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

编写一个方法来检查外星人是否撞到了屏幕边缘,还需修改 update()让每个外星人都沿正确的方向移动。这些代码位于 Alien 类中:

alien.py

3.4)向下移动外星人群并改变移动方向

有外星人到达屏幕边缘时,需要将整群外行星下移,并改变它们的方向。通过编写方法_check_fleet_edges()和_change_fleet_direction(),并且修改_update_aliens()。这些新方法将放在_create_alien()后面:

alien_invasion.py

修改_update_aliens():

alien_invasion.py

如果现在运行这个游戏,外星人群将在屏幕上来回移动,并在抵达屏幕边缘后向下移动。

4)射杀外星人

子弹能够击中外星人 。

4.1)检测子弹与外星人的碰撞

在方法_update_bullets()末尾,添加如下检查子弹和外星人碰撞的代码:

alien_invasion.py

如果现在运行这个游戏,被击中的外星人将会消失。

4.2)生成新的外星人群

这个游戏的一个重要特点是,外星人无穷无尽:一群外星人被消灭后,又会出现另一群外星人。在_update_bullets()末尾执行这项任务:

alien_invasion.py

 现在,当前这群外星人被消灭干净后,将立刻出现一群新的外星人。

4.3)提高子弹速度

要修改子弹的速度,可调整 settings.py 中 bullet_speed 的值。下面将 bullet_speed 的值调整到1.5:

settings.py

4.4)重构_update_bullets()

下面来重构_update_bullets(),使其不再执行那么多任务。为此,将处理子弹和外星人碰撞的代码移到一个独立的方法中:

alien_invasion.py

5)结束游戏

限制玩家可使用的飞船数,在玩家用光所有的飞船后,游戏将结束。


网卡导致从这后面的数据全丢失了,所以我就只能跳过这部分直接给完成后的代码了。


代码:

alien.py

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""表示单个外星人的类"""def __init__(self, ai_game):"""初始化外星人并设置其起始位置"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settings# 加载外星人图像并设置其 rect 属性self.image = pygame.image.load('images/alien.bmp')self.rect = self.image.get_rect()# 让每个外星人最初都在屏幕左上角附近。self.rect.x = self.rect.widthself.rect.y = self.rect.height# 存储外星人的精确水平位置self.x = float(self.rect.x)def check_edges(self):"""如果外星人位于屏幕边缘,就返回True"""screen_rect = self.screen.get_rect()if self.rect.right >= screen_rect.right or self.rect.left <= 0:return Truedef update(self):"""向左或向右移动外星人"""self.x += (self.settings.alien_speed * self.settings.fleet_direction)self.rect.x = self.x

alen_invasion.py

import sys
from time import sleepimport pygamefrom settings import Settings
from game_stats import GameStats
from ship import Ship
from bullet import Bullet
from alien import Alien# 管理游戏资源和行为的类
class AlienInvasion:# 初始化游戏并创建游戏资源def __init__(self):pygame.init()self.settings = Settings()# 全屏模式# self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)# self.settings.screen_width = self.screen.get_rect().width# self.settings.screen_height = self.screen.get_rect().height# pygame.display.set_caption("Alien Invasion")# 创建一个用于存储游戏统计信息的实例self.stats = GameStats(self)# 游戏窗口尺寸self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))self.ship = Ship(self)self.bullets = pygame.sprite.Group()self.aliens = pygame.sprite.Group()self._create_fleet()def _create_fleet(self):"""创建外星人群"""# 创建一个外星人并计算一行可容纳多少个外星人# 外星人的间距为外星人宽度alien = Alien(self)alien_width, alien_height = alien.rect.sizeavailable_space_x = self.settings.screen_width - (2 * alien_width)number_aliens_x = available_space_x // (2 * alien_width)# 计算屏幕可容纳多少行外星人ship_height = self.ship.rect.heightavailable_space_y = (self.settings.screen_height - (3 * alien_height) - ship_height)number_rows = available_space_y // (2 * alien_height)# 创建外星人群for row_number in range(number_rows):for alien_number in range(number_aliens_x):self._create_alien(alien_number, row_number)def _create_alien(self, alien_number, row_number):"""创建一个外星人并将其放在当前行"""alien = Alien(self)alien_width, alien_height = alien.rect.sizealien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberself.aliens.add(alien)# 开始游戏的主循环def run_game(self):while True:self._check_events()if self.stats.game_active:self.ship.update()self._update_bullets()self._update_aliens()self._update_screen()# 响应键盘和鼠标事件def _check_events(self):for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:self._check_keydown_events(event)elif event.type == pygame.KEYUP:self._check_keyup_events(event)# 响应按键def _check_keydown_events(self, event):if event.key == pygame.K_RIGHT:# 向右移动飞船self.ship.moving_right = Trueelif event.key == pygame.K_LEFT:# 向左移动飞船self.ship.moving_left = Trueelif event.key == pygame.K_q:sys.exit()elif event.key == pygame.K_SPACE:self._fire_bullet()# 响应松开def _check_keyup_events(self, event):if event.key == pygame.K_RIGHT:self.ship.moving_right = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = False# 创建一颗子弹,并将其加入编组 bullets 中def _fire_bullet(self):if len(self.bullets) < self.settings.bullets_allowed:new_bullet = Bullet(self)self.bullets.add(new_bullet)# 更新子弹位置并删除消失的子弹def _update_bullets(self):# 更新子弹位置self.bullets.update()# 删除消失的子弹for bullet in self.bullets.copy():if bullet.rect.bottom <= 0:self.bullets.remove(bullet)print(len(self.bullets))self._check_bullet_alien_collisions()def _check_bullet_alien_collisions(self):"""响应子弹和外星人碰撞"""# 删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)if not self.aliens:# 删除现有的子弹并新建一群外星人self.bullets.empty()self._create_fleet()def _update_aliens(self):"""检查是否所有外星人位于屏幕边缘,并更新正群外星人位置"""self._check_fleet_edges()self.aliens.update()# 检测外星人和飞船之间的碰撞if pygame.sprite.spritecollideany(self.ship, self.aliens):self._ship_hit()# 检查是否有外星人到达了屏幕底端self._check_aliens_bottom()def _ship_hit(self):"""响应飞船被外星人撞到"""if self.stats.ships_left > 0:# 将 ships_left 减1self.stats.ships_left -= 1# 清空余下的外星人和子弹self.aliens.empty()self.bullets.empty()# 创建一群新的外星人,并将飞船放到屏幕底端的中央self._create_fleet()self.ship.center_ship()# 暂停1sleep(0.5)else:self.stats.game_active = Falsedef _check_aliens_bottom(self):"""检查是否有外星人到达了屏幕底端"""screen_rect = self.screen.get_rect()for alien in self.aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:# 像飞船被撞到一样处理self._ship_hit()breakdef _check_fleet_edges(self):"""有外星人到达边缘时采取相应的措施"""for alien in self.aliens.sprites():if alien.check_edges():self._change_fleet_direction()breakdef _change_fleet_direction(self):"""将整群外星人下移,并改变它们的方向"""for alien in self.aliens.sprites():alien.rect.y += self.settings.fleet_drop_speedself.settings.fleet_direction *= -1# 更新屏幕上的图像,切换到新屏幕def _update_screen(self):self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self.aliens.draw(self.screen)# 让最近绘制的屏幕可见pygame.display.flip()# 创建游戏实例并运行游戏
if __name__ == '__main__':ai = AlienInvasion()ai.run_game()

bullet.py

import pygame
from pygame.sprite import Sprite# 管理飞船所发射子弹的类
class Bullet(Sprite):# 在飞船当前为止创建一个子弹对象def __init__(self, ai_game):super().__init__()self.screen = ai_game.screenself.settings = ai_game.settingsself.color = self.settings.bullet_color# 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置self.rect = pygame.Rect(0, 0, self.settings.bullet_width, self.settings.bullet_height)self.rect.midtop = ai_game.ship.rect.midtop# 存储用小数表示的子弹位置self.y = float(self.rect.y)# 向上移动子弹def update(self):# 更新表示子弹位置的小数值self.y -= self.settings.bullet_speed# 更新表示子弹的 rect 的位置self.rect.y = self.y# 在屏幕上绘制子弹def draw_bullet(self):pygame.draw.rect(self.screen, self.color, self.rect)

game_stats.py

class GameStats:""""跟踪游戏的统计信息"""def __init__(self, ai_game):"""初始化统计信息"""self.settings = ai_game.settingsself.reset_stats()# 游戏刚启动时处于活动状态self.game_active = Truedef reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.settings.ship_limit

settings.py

# 储存游戏《外星人入侵》中所有设置的类
class Settings:# 初始化游戏设置def __init__(self):# 屏幕设置self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)# 飞船设置self.ship_speed = 1self.ship_limit = 3# 子弹设置self.bullet_speed = 1.5self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60, 60, 60)self.bullets_allowed = 3# 外星人设置self.alien_speed = 0.5self.fleet_drop_speed = 10# fleet_direction 为 1 表示向右移,为 -1 表示向左移动self.fleet_direction = 1

ship.py

import pygame# 管理飞船的类
class Ship:def __init__(self, ai_game):# 初始化飞船并设置其初始位置self.screen = ai_game.screenself.settings = ai_game.settingsself.screen_rect = ai_game.screen.get_rect()# 加载飞船图像并获取其外接矩形self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()# 对于每艘新飞船,都将其放在屏幕底部的中央self.rect.midbottom = self.screen_rect.midbottom# 在飞船的属性x中存储小数值self.x = float(self.rect.x)# 移动标志self.moving_right = Falseself.moving_left = False# 根据移动标志调整飞船位置def update(self):# 更新飞船而不是rect对象的x值if self.moving_right and self.rect.right < self.screen_rect.right:self.x += self.settings.ship_speedif self.moving_left and self.rect.left > 0:self.x -= self.settings.ship_speed# 根据self.x 更新rect对象。self.rect.x = self.x# 指定位置绘制飞船def blitme(self):self.screen.blit(self.image, self.rect)def center_ship(self):"""让飞船在屏幕底端居中"""self.rect.midbottom = self.screen_rect.midbottomself.x = float(self.rect.x)

Python-项目实战-《外星人入侵》Pygame小游戏-阶段二:外星人来了相关推荐

  1. 视频教程-python项目之学员CRM管理系统开发阶段二-Python

    python项目之学员CRM管理系统开发阶段二 TriAquae开源运维软件创始人,混迹IT运维领域多年,曾就职于松下.国政通.飞信.中金.NOKIA等公司,维护过少至几十台,多至数万台设备的IT系统 ...

  2. python项目之学员CRM管理系统开发阶段二-李杰-专题视频课程

    python项目之学员CRM管理系统开发阶段二-3394人已学习 课程介绍         面向初级开发一套含有角色,权限,内容为一体的学员管理,抛弃传统的每个页面繁琐的增删改查,开发公共组件,使得开 ...

  3. python《打气球》小游戏(二)

    欢迎加入我们卧虎藏龙的python讨论qq群:729683466 导语 ss 学会了画气球 现在,我们可以学一学打气球 以及生成五颜六色的气球 最后 还给大家准备了一道课后题哦 代码及相关资源获取 1 ...

  4. python写一个游戏多少代码-Python项目实战之猜数字游戏(含实现代码)

    猜数字游戏,旨在提高初学者对 Python 变量类型以及循环结构的使用. 此游戏的游戏规则如下:程序随机内置一个位于一定范围内的数字作为猜测的结果,由用户猜测此数字.用户每猜测一次,由系统提示猜测结果 ...

  5. python猜密码游戏规则_【python笔记 三 】python脚本实战---数字密码小游戏

    描述:A输入一个数值,输入时该数值已隐藏无法看到,让B猜该数字为多少,数值过小或过大都会提示,并会在最后猜对时统计出共猜了几次. 脚本内容: #!/usr/bin/env python #FileNa ...

  6. python项目实战三个小实例

    1.   让用户输入圆的半径,告诉用户圆的面积: import math while True:     # 用户输入     r = input("请输入圆的半径:")     ...

  7. Python编写微信打飞机小游戏(十一)

    如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...

  8. Python编写微信打飞机小游戏(三)

    如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...

  9. Python编写微信打飞机小游戏(八)

    如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...

最新文章

  1. Tkinter的Radiobutton组件
  2. sqlplus 修改system密码_华为交换机console密码忘了如何解决 华为交换机console密码忘了解决方法【介绍】...
  3. java实现linux变量替换_linux java 配置 含环境变量 | 学步园
  4. 看完Mate 10拍下的精美空中照片后,你是否也想坐次飞机试拍下?
  5. 关于vmware卸载后重装回滚的解决方法
  6. 【爆肝帝,花费3个月整理】金九银十面试季,2020-2021字节跳动所有,软件测试面试题拿走不谢!(附详细答案解析)
  7. 《软件设计师》备考笔记
  8. 8086汇编(3、指令集)
  9. PNG透明图片叠加(Opencv实现,包括旋转缩放以及边界处理)
  10. 写给需要面试经验的交互设计师(上)
  11. hadoop基础----hadoop实战(七)-----hadoop管理工具---使用Cloudera Manager安装Hadoop---Cloudera Manager和CDH5.8离线安装
  12. C/C++实现三角函数的方法
  13. Tarena代码-一些代码碎片
  14. 【转】WinCE驱动开发问题精华集锦
  15. 抽象类,多态与鸭子类型
  16. Deprecated Gradle features were used in this build, making it incompatible with Gradle
  17. tf2加载图片数据集并训练
  18. 微软亚洲研究院院友会,AI大牛新动向|AI科技评论周刊
  19. Series(一):Series的创建方式和常用属性说明
  20. leetcode_399. 除法求值

热门文章

  1. DM7数据守护集群部署
  2. 洛谷P4113 [HEOI2012]采花 题解
  3. 【数据结构与算法】->算法-> A* 搜索算法->如何实现游戏中的寻路功能?
  4. Spring Boot 自动配置 : RedisAutoConfiguration
  5. 实现敌人(怪物)的简单AI(自动巡逻、看到玩家攻击玩家、玩家离开恢复自动巡逻)
  6. 九九乘法表 -- 2015/9/24
  7. 鸿蒙启智 博学多才,华为鸿蒙·西游远古
  8. 关于http与https的区别之处
  9. 光脚丫学LINQ(003):排序结果集
  10. 账本进化-了解区块链