---恢复内容开始---
一、game_functions将各个模块的功能整合起来,供主文件调用
1 # -*- coding:utf-8 -*- 2 3 import sys 4 import pygame 5 from bullets import Bullet 6 from alien import Alien 7 from pygame.sprite import Sprite 8 import time 9 10 11 12 def check_keydown_events(ai_settings, event, screen, ship, bullets): 13 '''响应按键''' 14 if event.key == pygame.K_RIGHT: 15 '''更新移动标志''' 16 ship.moving_right = True 17 elif event.key == pygame.K_LEFT: 18 ship.moving_left = True 19 elif event.key == pygame.K_UP: 20 ship.moving_up = True 21 elif event.key == pygame.K_DOWN: 22 ship.moving_down = True 23 elif event.key == pygame.K_SPACE: 24 '''创建一个子弹,并将其加入到编组中,若未消失子弹数目小于设定值则发射''' 25 fire_bullets(ai_settings, bullets, screen, ship) 26 elif event.key == pygame.K_q: 27 sys.exit() 28 29 30 def check_keyup_events(event, ship): 31 '''响应松开按键''' 32 if event.key == pygame.K_RIGHT: 33 ship.moving_right = False 34 elif event.key == pygame.K_LEFT: 35 ship.moving_left = False 36 elif event.key == pygame.K_UP: 37 ship.moving_up = False 38 elif event.key == pygame.K_DOWN: 39 ship.moving_down = False 40 41 42 def check_events(ai_settings, screen, ship, bullets, stats, play_button, aliens, sb): 43 '''响应按键以及鼠标事件''' 44 for event in pygame.event.get(): 45 if event.type == pygame.KEYDOWN: # 对于每个按键注册为KEYDOEWN事件并判断其类型 46 check_keydown_events(ai_settings, event, screen, ship, bullets) 47 elif event.type == pygame.KEYUP: 48 check_keyup_events(event, ship) 49 elif event.type == pygame.MOUSEBUTTONDOWN: 50 mouse_x, mouse_y = pygame.mouse.get_pos() 51 check_play_button(stats, play_button, mouse_x, mouse_y, ai_settings, screen, ship, aliens, bullets, sb) 52 53 54 def check_play_button(stats, play_button, mouse_x, mouse_y, ai_settings, screen, ship, aliens, bullets, sb): 55 '''在玩家单击play按钮且此时游戏状态为False时才开始游戏''' 56 button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y) 57 if button_clicked and not stats.game_active: 58 '''重置游戏设置''' 59 ai_settings.initialize_dynamic_settings() 60 61 '''隐藏光标''' 62 pygame.mouse.set_visible(False) 63 64 '''重置游戏统计信息''' 65 stats.reset_stats() 66 stats.game_active = True 67 68 '''在点击play按钮之后清空外星人和子弹''' 69 aliens.empty() 70 bullets.empty() 71 72 '''重置记分牌图像''' 73 sb.prep_score() 74 sb.prep_level() 75 sb.prep_ships() 76 77 '''创建新外星人,并将飞船居中''' 78 create_fleet(ai_settings, screen, ship, aliens) 79 ship.center_ship() 80 81 82 def fire_bullets(ai_settings, bullets, screen, ship): 83 if len(bullets) <= ai_settings.bullet_allowed: 84 new_bullet = Bullet(ai_settings, screen, ship) 85 bullets.add(new_bullet) 86 87 88 def update_screen(ai_settings, stats, screen, ship, aliens, bullets, play_button, sb): 89 '''更新屏幕上的图像,并切换到新屏幕''' 90 screen.fill(ai_settings.bg_color) 91 92 '''在飞船和外星人后面绘制所有子弹''' 93 for bullet in bullets.sprites(): 94 bullet.draw_bullet() 95 ship.blitme() 96 aliens.draw(screen) 97 98 '''显示得分''' 99 sb.show_score() 100 101 '''在游戏非活动状态时显示play按钮''' 102 if not stats.game_active: 103 play_button.draw_button() 104 105 '''让最近的屏幕可见''' 106 pygame.display.flip() 107 108 109 def update_bullets(ai_settings, screen, ship, bullets, aliens, stats, sb): 110 '''更新子弹位置,并删除消失的子弹''' 111 bullets.update() # 更新子弹位置 112 113 '''删除消失的子弹''' 114 for bullet in bullets.copy(): 115 if bullet.rect.bottom <= 0: 116 bullets.remove(bullet) 117 118 check_bullet_alien_collisions(ai_settings, screen, ship, bullets, aliens, stats, sb) 119 120 121 def check_bullet_alien_collisions(ai_settings, screen, ship, bullets, aliens, stats, sb): 122 '''检查是否有子弹与外星人碰撞,如果碰撞,则删除响应的外星人和子弹''' 123 collisions = pygame.sprite.groupcollide(bullets, aliens, True, True) 124 125 '''子弹撞到外星人时加分并更新图像,且将每个被消灭的外星人都计入分数''' 126 '''字典collisions中,与外星人碰撞的子弹是键,其值为被子弹击中的外星人,遍历collisions中的值,将其中的每个外星人的分 127 数都记上''' 128 if collisions: 129 for aliens in collisions.values(): 130 stats.score += ai_settings.alien_points * len(aliens) 131 sb.prep_score() 132 check_highest_score(stats, sb) 133 134 if len(aliens) == 0: 135 '''删除现有的子弹并新建一批外星人''' 136 bullets.empty() 137 ai_settings.increase_speed() 138 139 '''提升等级''' 140 stats.level += 1 141 sb.prep_level() 142 143 create_fleet(ai_settings, screen, ship, aliens) 144 145 146 def get_number_aliens_x(ai_settings, alien_width): 147 '''计算每一行可以容纳多少个外星人''' 148 available_space_x = ai_settings.screen_width - 2 * alien_width 149 number_aliens_x = int(available_space_x / (2 * alien_width)) 150 return number_aliens_x 151 152 153 def create_alien(ai_settings, screen, aliens, alien_number, row_number ): 154 alien = Alien(ai_settings, screen) 155 alien_width = alien.rect.width 156 alien.x = alien_width + 2 * alien_width * alien_number 157 alien.rect.x = alien.x 158 alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number 159 aliens.add(alien) 160 161 162 def get_number_rows(ai_settings, ship_height, alien_height): 163 '''计算屏幕上能容纳多少行外星人''' 164 available_y = (ai_settings.screen_height - (3 * alien_height) - ship_height) 165 number_rows = int(available_y/(2 * alien_height)) 166 return number_rows 167 168 169 def create_fleet(ai_settings, screen, ship, aliens): 170 '''创建外星人群''' 171 '''创建一个外星人,并计算每行能容纳多少个''' 172 '''外星人间距为外星人宽''' 173 alien = Alien(ai_settings, screen) 174 number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width) 175 number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height) 176 177 178 '''创建第一行外星人''' 179 for row_number in range(number_rows): 180 for alien_number in range(number_aliens_x): 181 '''创建一个外星人并将其加入当前行''' 182 alien = Alien(ai_settings, screen) 183 create_alien(ai_settings, screen, aliens, alien_number, row_number) 184 185 186 def check_fleet_edges(ai_settings, aliens): 187 '''有外星人到达边缘时采取的措施''' 188 for alien in aliens.sprites(): 189 if alien.check_edges(): 190 change_fleet_direction(ai_settings, aliens) 191 break 192 193 194 def change_fleet_direction(ai_settings, aliens): 195 '''将整群外星人下移并改变方向''' 196 for alien in aliens.sprites(): 197 alien.rect.y += ai_settings.fleet_drop_speed 198 ai_settings.fleet_direction *= -1 199 200 201 def ship_hit(ai_settings, stats, screen, ship, aliens, bullets, sb): 202 '''响应被外星人撞到的飞船''' 203 if stats.ships_left > 0: 204 '''将ships_left减1''' 205 stats.ships_left -= 1 206 207 '''清空外星人列表和子弹列表''' 208 aliens.empty() 209 bullets.empty() 210 ship.center_ship() 211 sb.prep_ships() 212 213 '''创建一群新的外星人,并把飞船放到屏幕中央''' 214 create_fleet(ai_settings, screen, ship, aliens) 215 216 217 '''暂停一段时间''' 218 time.sleep(0.5) 219 else: 220 stats.game_active = False 221 pygame.mouse.set_visible(True) 222 223 224 def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets, sb): 225 '''检查是否有外星人到达底端''' 226 screen_rect = screen.get_rect() 227 for alien in aliens.sprites(): 228 if alien.rect.bottom >= screen_rect.bottom: 229 '''碰到底部与碰到飞船一样处理''' 230 ship_hit(ai_settings, stats, screen, ship, aliens, bullets, sb) 231 break 232 233 234 def update_aliens(ai_settings, stats, aliens, ship, screen, bullets, sb): 235 '''更新外星人位置''' 236 check_fleet_edges(ai_settings, aliens) 237 aliens.update() 238 239 '''检测外星人和飞船之间的碰撞,若为真,则停止游戏''' 240 if pygame.sprite.spritecollide(ship, aliens, True): 241 ship_hit(ai_settings, stats, screen, ship, aliens, bullets, sb) 242 243 '''检查外星人是否到达屏幕底端''' 244 check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets, sb) 245 246 247 def check_highest_score(stats, sb): 248 '''检测是否产生了最高分''' 249 if stats.score > stats.highest_score: 250 stats.highest_score = stats.score 251 sb.prep_highest_score()
二、记分板
1 # -*- coding:utf-8 -*- 2 3 class GameStats(): 4 '''跟踪游戏的统计信息''' 5 6 def __init__(self, ai_settings): 7 '''初始化统计信息''' 8 self.ai_settings = ai_settings 9 self.reset_stats() 10 self.game_active = False 11 12 '''在任何情况下都不重置游戏最高得分''' 13 self.highest_score = 0 14 15 16 def reset_stats(self): 17 '''初始化在游戏运行期间可能变化的统计信息''' 18 self.ships_left = self.ai_settings.ship_limit 19 self.score = 0 20 self.level = 1
三、设置游戏按钮
1 # -*- coding:utf-8 -*- 2 3 import pygame.font 4 5 class Button(): 6 7 def __init__(self, ai_settings, screen, msg): 8 '''初始化按钮的属性''' 9 self.screen = screen 10 self.screen_rect = screen.get_rect() 11 12 '''设置按钮的其他属性''' 13 self.width, self.height = 200, 50 14 self.button_color = (0, 255, 0) 15 self.text_color = (255, 255, 255) 16 self.font = pygame.font.SysFont(None, 48) 17 18 '''创建按钮的rect对象,并使其居中''' 19 self.rect = pygame.Rect(0, 0 , self.width, self.height) 20 self.rect.center = self.screen_rect.center 21 22 '''将字符串渲染成图片''' 23 self.prep_msg(msg) 24 25 def prep_msg(self, msg): 26 '''将msg渲染为图像,并使其在按钮上居中''' 27 self.msg_image = self.font.render(msg, True, self.text_color, self.button_color) 28 self.msg_image_rect = self.msg_image.get_rect() 29 self.msg_image_rect.center = self.rect.center 30 31 def draw_button(self): 32 '''绘制一个用背景颜色填充的按钮,然后绘制文本图像''' 33 pygame.draw.rect(self.screen, self.button_color, self.rect) 34 self.screen.blit(self.msg_image, self.msg_image_rect)
游戏可能是复杂的,但分别编写其中的一些模块,会使得整个问题变得简单。