@Python编程从入门到实践 Python项目练习

四、创建Ship类

建立ship.py,创建Ship类,管理飞船行为。

  1. # ship.py
  2. import pygame
  3. class Ship():
  4. def __init__(self, ai_settings, screen):
  5. """初始化飞船并设置其初始位置"""
  6. self.screen = screen
  7. self.ai_settings = ai_settings
  8. # 加载飞船图像
  9. self.image = pygame.image.load('images/ship.bmp')
  10. self.image = pygame.transform.scale(self.image, (37*2, 34*2))
  11. # 获取其外接矩形(rect为surface矩形属性)
  12. self.rect = self.image.get_rect()
  13. self.screen_rect = screen.get_rect()
  14. # 将每艘新飞船放在屏幕底部中央
  15. self.rect.centerx = self.screen_rect.centerx
  16. self.rect.bottom = self.screen_rect.bottom
  17. # 在飞船的属性center中存储小数值
  18. self.center_x = float(self.rect.centerx)
  19. self.center_y = float(self.rect.centery)
  20. # 移动标志
  21. self.moving_right = False
  22. self.moving_left = False
  23. self.moving_up = False
  24. self.moving_down = False
  25. def update(self):
  26. """根据移动标志调整飞船到位置"""
  27. # 更新飞船的center值, 而不是rect
  28. if self.moving_right and self.rect.right < self.screen_rect.right:
  29. self.center_x += self.ai_settings.ship_speed_factor
  30. if self.moving_left and self.rect.left > 0:
  31. self.center_x -= self.ai_settings.ship_speed_factor
  32. if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
  33. self.center_y += self.ai_settings.ship_speed_factor
  34. if self.moving_up and self.rect.top > self.screen_rect.top:
  35. self.center_y -= self.ai_settings.ship_speed_factor
  36. # 根据self.center更新rect对象
  37. self.rect.centerx = self.center_x
  38. self.rect.centery = self.center_y
  39. def blitme(self):
  40. """在指定位置绘制飞船"""
  41. self.screen.blit(self.image, self.rect)
  42. def center_ship(self):
  43. """让飞船在屏幕上居中"""
  44. self.center_x = self.screen_rect.centerx
  45. ship_half_width = self.rect.bottom - self.center_y
  46. self.center_y = self.screen_rect.bottom - ship_half_width

五、创建Bullet类

建立bullet.py,创建Bullet类,继承pygame.sprite中的Sprite类,作为游戏中的子弹元素。

  1. # settings.py
  2. import pygame
  3. from pygame.sprite import Sprite
  4. class Bullet(Sprite):
  5. """一个对子弹发射进行管理的类"""
  6. def __init__(self, ai_settings, screen, ship):
  7. super(Bullet, self).__init__()
  8. self.screen = screen
  9. # 在(0, 0)处创建一个表示子弹的矩形,将初始位置放在(0,0)
  10. self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
  11. ai_settings.bullet_height)
  12. # 重设子弹位置
  13. self.rect.centerx = ship.rect.centerx
  14. # self.rect.centery = ship.rect.centery
  15. self.rect.top = ship.rect.top
  16. # 存储用小数表示的子弹位置
  17. self.y = float(self.rect.y)
  18. self.color = ai_settings.bullet_color
  19. self.speed_factor = ai_settings.bullet_speed_factor
  20. def update(self):
  21. """向上移动子弹"""
  22. # 更新表示子弹的小数值
  23. self.y -= self.speed_factor
  24. # 更新表示子弹的rect的位置
  25. self.rect.y = self.y
  26. def draw_bullet(self):
  27. """在屏幕上绘制子弹"""
  28. pygame.draw.rect(self.screen, self.color, self.rect)

六、创建game_functions模块

创建game_functions.py 模块,存储函数,让alien_invasion中主代码更易懂。

  1. #game_functions.py
  2. import sys
  3. import pygame
  4. from bullet import Bullet
  5. from passenger import Passenger
  6. from time import sleep
  7. def check_keydown_events(event, ai_settings, screen, ship, bullet_group):
  8. """响应按键"""
  9. if event.key == pygame.K_RIGHT:
  10. ship.moving_right = True
  11. elif event.key == pygame.K_LEFT:
  12. ship.moving_left = True
  13. elif event.key == pygame.K_UP:
  14. ship.moving_up = True
  15. elif event.key == pygame.K_DOWN:
  16. ship.moving_down = True
  17. elif event.key == pygame.K_SPACE:
  18. fire_bullet(ai_settings, screen, ship, bullet_group)
  19. elif event.key == pygame.K_ESCAPE:
  20. sys.exit()
  21. def fire_bullet(ai_settings, screen, ship, bullet_group):
  22. """如果没有到达限制,就发射一颗子弹"""
  23. # 创建一颗子弹,并将其加入到编组bullets中
  24. if len(bullet_group) < ai_settings.bullet_group_allowed:
  25. new_bullet = Bullet(ai_settings, screen, ship)
  26. bullet_group.add(new_bullet)
  27. def check_keyup_events(event, ship):
  28. """松开按键"""
  29. if event.key == pygame.K_RIGHT:
  30. ship.moving_right = False
  31. elif event.key == pygame.K_LEFT:
  32. ship.moving_left = False
  33. elif event.key == pygame.K_UP:
  34. ship.moving_up = False
  35. elif event.key == pygame.K_DOWN:
  36. ship.moving_down = False
  37. def check_events(ai_settings, screen, ship, bullet_group):
  38. """响应按键和鼠标事件"""
  39. for event in pygame.event.get():
  40. if event.type == pygame.QUIT:
  41. sys.exit()
  42. # 按下
  43. elif event.type == pygame.KEYDOWN:
  44. check_keydown_events(event, ai_settings, screen, ship, bullet_group)
  45. # 松开
  46. elif event.type == pygame.KEYUP:
  47. check_keyup_events(event, ship)
  48. def update_screen(ai_settings, screen, ship, passenger_group, bullet_group):
  49. """更新屏幕上的图像,并切换到新屏幕"""
  50. # 每次循环时(即打开游戏运行)重绘屏幕
  51. screen.fill(ai_settings.bg_color)
  52. # 绘制子弹
  53. for bullet in bullet_group:
  54. bullet.draw_bullet()
  55. ship.blitme()
  56. for i in passenger_group:
  57. i.blitme()
  58. #passenger_group.draw(screen)
  59. # 更新屏幕(隐藏旧屏,更新新屏)
  60. pygame.display.flip()
  61. def update_bullet_group(ai_settings, screen, ship, passenger_group, bullet_group ):
  62. """更新子弹的位置,并删除已消失的子弹"""
  63. # 更新子弹的位置
  64. bullet_group.update()
  65. # 删除已消失的子弹
  66. for bullet in bullet_group.copy():
  67. if bullet.rect.top <= 0:
  68. bullet_group.remove(bullet)
  69. check_bullet_passenger_collisions(ai_settings, screen, ship, passenger_group,
  70. bullet_group)
  71. def check_bullet_passenger_collisions(ai_settings,screen, ship, passenger_group,
  72. bullet_group):
  73. # 检查是否有子弹击中了乘客
  74. # 如果是这样,就删除相应的子弹和乘客
  75. # groupcollide()返回字典,实参为True即删除发生碰撞的子弹或外星人
  76. collisions = pygame.sprite.groupcollide(bullet_group, passenger_group, False, True)
  77. if len(passenger_group) == 0:
  78. # 删除现有子弹并新建一波新的乘客
  79. bullet_group.empty()
  80. create_fleet(ai_settings, screen, ship, passenger_group)
  81. def get_number_passenger_x(ai_settings, passenger_width):
  82. """计算每行可以容纳多少个乘客"""
  83. available_space_x = ai_settings.screen_width - 2 * passenger_width
  84. number_passenger_x = int(available_space_x / (2 * passenger_width))
  85. return number_passenger_x
  86. def get_number_rows(ai_settings, ship_height, passenger_height):
  87. """计算屏幕可以容纳多少行的乘客"""
  88. available_space_y = (ai_settings.screen_height - passenger_height - ship_height)
  89. number_rows = int(available_space_y / (1.5 * passenger_height))
  90. return number_rows
  91. def create_passenger(ai_settings, screen, passenger_group, passenger_number, row_number):
  92. """创建一个乘客并将其放在当前行"""
  93. passenger = Passenger(ai_settings, screen)
  94. passenger_width = passenger.rect.width
  95. passenger.x = passenger_width + 2 * passenger_width * passenger_number
  96. passenger.rect.x = passenger.x
  97. passenger.rect.y = 0.5 * passenger.rect.height + 1.5 * passenger.rect.height * row_number
  98. passenger_group.add(passenger)
  99. def create_fleet(ai_settings, screen, ship, passgener_group):
  100. """创建乘客群"""
  101. # 创建一个乘客,并计算一行可以容纳多少人
  102. passenger = Passenger(ai_settings, screen)
  103. number_passenger_x = get_number_passenger_x(ai_settings, passenger.rect.width)
  104. number_rows = get_number_rows(ai_settings, ship.rect.height, passenger.rect.height)
  105. # 创建乘客群
  106. for row_number in range(number_rows):
  107. for passenger_number in range(number_passenger_x):
  108. create_passenger(ai_settings, screen, passgener_group, passenger_number,
  109. row_number)
  110. def change_fleet_direction(ai_settings, passenger_group):
  111. """将整群乘客下移,并改变它们的方向"""
  112. for passenger in passenger_group.sprites():
  113. passenger.rect.y += ai_settings.fleet_drop_speed
  114. ai_settings.fleet_direction *= -1
  115. def check_fleet_edges(ai_settings, passenger_group):
  116. """有外星人到达边缘时采取相应的措施"""
  117. for passenger in passenger_group.sprites():
  118. if passenger.check_edges():
  119. change_fleet_direction(ai_settings, passenger_group)
  120. break
  121. def ship_hit(ai_settings, stats, screen, ship, passenger_group, bullet_group):
  122. """响应被乘客撞到的飞船"""
  123. if stats.ships_left > 0:
  124. # 讲ship_left减一
  125. stats.ships_left -= 1
  126. # 清空乘客列表和子弹列表
  127. passenger_group.empty()
  128. bullet_group.empty()
  129. # 创建一群新的外星人,并讲飞船放在屏幕底部中央
  130. create_fleet(ai_settings, screen, ship, passenger_group)
  131. ship.center_ship()
  132. # 暂停
  133. sleep(0.5)
  134. else:
  135. stats.game_active = False
  136. def check_passenger_group_bottom(ai_settings, stats, screen, ship, passenger_group, bullet_group):
  137. """检查是否有外星人到达屏幕底端"""
  138. screen_rect = screen.get_rect()
  139. for passenger in passenger_group.sprites():
  140. if passenger.rect.bottom >= screen_rect.bottom:
  141. # 像飞船被撞到一样进行处理
  142. ship_hit(ai_settings, stats, screen, ship, passenger_group, bullet_group)
  143. break
  144. def update_passenger_group(ai_settings, stats, screen, ship, passenger_group, bullet_group):
  145. """检查是否有乘客在边缘,并更新乘客群中所有乘客的位置"""
  146. check_fleet_edges(ai_settings, passenger_group)
  147. passenger_group.update()
  148. # 检测外星人和飞船之间的碰撞
  149. if pygame.sprite.spritecollideany(ship, passenger_group):
  150. ship_hit(ai_settings, stats, screen, ship, passenger_group, bullet_group)
  151. # 检查是否有外星让到达屏幕底端
  152. check_passenger_group_bottom(ai_settings, stats, screen, ship, passenger_group, bullet_group)

Pygame小游戏练习二的更多相关文章

  1. pygame小游戏之坦克大战

    以前在学校的时候无聊的学了会pygame.看了大概一周的教学视频,做出来个坦克大战的小游戏 Python3.5  pycharm import pygame,sys,time from random ...

  2. Pygame小游戏练习五

    @Python编程从入门到实践 Python项目练习 十一.显示游戏得分及最高分 创建新类Scoreboard,用以显示得分和最高分. # scoreboard.py import pygame.fo ...

  3. Pygame小游戏练习四

    @Python编程从入门到实践 Python项目练习 九.添加Play按钮 一.创建Button类 先让游戏一开始为非活动状态 # game_stats.py # --snip-- self.game ...

  4. Pygame小游戏练习一

    @Python编程从入门到实践 Python项目练习 一.安装Python包Pygame 通过pip安装包工具安装 python3 -m pip --version #查看是否安装pip 确定安装pi ...

  5. web版扫雷小游戏(二)

    接上篇~~第一次写这种技术博客,发现把自己做的东西介绍出来还是一件脑力活,不是那么轻松啊,好吧,想到哪写到哪,流水记录之,待完成之后再根据大家的意见进行修改吧. 游戏实现 根据对扫雷游戏的体验和分析, ...

  6. Pygame小游戏练习三

    @Python编程从入门到实践 Python项目练习 七.创建Passenger类 创建passenger.py文件,创建Passenger类,控制乘客属性和行为 # passenger.py imp ...

  7. 软件设计之基于Java的连连看小游戏(二)——游戏基础界面的制作及事件的添加

    上次完成到游戏首页的制作,今天完成了游戏基础界面的制作以及事件的简单添加.由于功能尚未完全实现,因此游戏界面的菜单列表只是简单地添加了一下,其余菜单列表以及倒计时等在后续的制作中逐一完善. 1.首先在 ...

  8. python小游戏-pygame模块

    一.tkinter模块的GUI 基本上使用tkinter来开发GUI应用需要以下5个步骤: 导入tkinter模块中我们需要的东西. 创建一个顶层窗口对象并用它来承载整个GUI应用. 在顶层窗口对象上 ...

  9. Python小游戏——外星人入侵(保姆级教程)第一章 01创建Pygame窗口 02创建设置类Setting()

    系列文章目录 第一章:武装飞船 01:创建Pygame窗口以及响应用户输入 02:创建设置类Setting() 一.前期准备 1.语言版本 Python3.9.0 2.编译器 Pycharm2022 ...

随机推荐

  1. ICEM—奇葩

    原视频下载地址:https://yunpan.cn/cSsbI89zP9Z4K  访问密码 a287

  2. 如何查看appPackage和启动appActivity

    安装apk,模拟器或真机中在前台运行该应用程序,获取appPackage,即应用包名 appPackage:  adb shell dumpsys activity | find "mFoc ...

  3. Centos - php5.4升级到7.1 yum安装

    查看当前 PHP 版本 1 php -v 查看当前 PHP 相关的安装包,删除之 1 2 3 4 5 yum list installed | grep php   yum remove php   ...

  4. Thymeleaf th:include、th:replace引用

    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" ...

  5. Eclipse的下载地址

    下载地址:http://eclipse.org/

  6. shared pointer

    #include <string>#include <fstream>#include <memory>#include <cstdio> class ...

  7. 分布式存储——Build up a High Availability Distributed Key-Value Store

    原文链接 Preface There are many awesome and powerful distributed NoSQL in the world, like Couchbase, Mon ...

  8. easy-mock 本地部署

    前言 为什么要本地部署 easy-mock呢? easy-mock官网经常挂,太浪费时间了: 公司突然不给上外网,太垃圾了: 就是想要折腾自己,太爱学习了(哈哈哈): Easy-mock 官网 安装需 ...

  9. Python排序算法之选择排序定义与用法示例

    Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...

  10. python之inspect模块

      inspect模块主要提供了四种用处: 1.对是否是模块.框架.函数进行类型检查 2.获取源码 3.获取类或者函数的参数信息 4.解析堆栈 回到顶部 一.type and members 1. i ...