---恢复内容开始---
一、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 += 1141 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_width149 number_aliens_x = int(available_space_x / (2 * alien_width))150 return number_aliens_x151 152 153 def create_alien(ai_settings, screen, aliens, alien_number, row_number ):154 alien = Alien(ai_settings, screen)155 alien_width = alien.rect.width156 alien.x = alien_width + 2 * alien_width * alien_number157 alien.rect.x = alien.x158 alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number159 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_rows167 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 break192 193 194 def change_fleet_direction(ai_settings, aliens):195 '''将整群外星人下移并改变方向'''196 for alien in aliens.sprites():197 alien.rect.y += ai_settings.fleet_drop_speed198 ai_settings.fleet_direction *= -1199 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 -= 1206 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 = False221 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 break232 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.score251 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 = False11 12 '''在任何情况下都不重置游戏最高得分'''13 self.highest_score = 014 15 16 def reset_stats(self):17 '''初始化在游戏运行期间可能变化的统计信息'''18 self.ships_left = self.ai_settings.ship_limit19 self.score = 020 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 = screen10 self.screen_rect = screen.get_rect()11 12 '''设置按钮的其他属性'''13 self.width, self.height = 200, 5014 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.center21 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.center30 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)
游戏可能是复杂的,但分别编写其中的一些模块,会使得整个问题变得简单。