模块一:外星人管理与碰撞系统
目标:生成动态外星人群,处理移动、触边检测与子弹碰撞。
# alien.py(基础外星人类)
class Alien(Sprite):
def __init__(self, game):
super().__init__()
self.screen = game.screen
self.image = pygame.image.load('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 update(self):
"""水平移动外星人"""
self.x += self.settings.alien_speed * self.settings.fleet_direction
self.rect.x = self.x
def check_edges(self):
"""检测是否触边"""
screen_rect = self.screen.get_rect()
return self.rect.right >= screen_rect.right or self.rect.left <= 0
# alien_invasion.py(外星人群管理)
class AlienInvasion:
def _create_fleet(self):
"""生成多行多列外星人"""
alien = Alien(self)
alien_width, alien_height = alien.rect.size
available_space_x = self.settings.screen_width - 2 * alien_width
number_aliens_x = available_space_x // (2 * alien_width)
available_space_y = self.settings.screen_height - 3 * alien_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 _check_fleet_edges(self):
"""触边后下移并反向"""
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
def _change_fleet_direction(self):
"""下移并反转方向"""
for alien in self.aliens.sprites():
alien.rect.y += self.settings.fleet_drop_speed
self.settings.fleet_direction *= -1
def _check_collisions(self):
"""子弹与外星人碰撞检测"""
collisions = pygame.sprite.groupcollide(
self.bullets, self.aliens, True, True
)
if collisions:
self.stats.score += self.settings.alien_points * sum(len(v) for v in collisions.values())
self.sb.prep_score()
self._check_high_score()
模块二:计分系统与游戏统计
目标:实时跟踪得分、最高分、剩余生命与关卡进度。
# game_stats.py
class GameStats:
def __init__(self, game):
self.settings = game.settings
self.reset_stats()
self.high_score = 0
self._load_high_score() # 从文件加载历史最高分
def reset_stats(self):
self.ships_left = self.settings.ship_limit
self.score = 0
self.level = 1
def _load_high_score(self):
try:
with open("high_score.txt", "r") as f:
self.high_score = int(f.read())
except FileNotFoundError:
pass # 首次运行无文件则保持0
# scoreboard.py(UI渲染)
class Scoreboard:
def __init__(self, game):
self.screen = game.screen
self.stats = game.stats
self.text_color = (255, 255, 255)
self.font = pygame.font.SysFont("Consolas", 32)
self.prep_score()
self.prep_high_score()
self.prep_level()
self.prep_ships()
def prep_score(self):
"""格式化得分并渲染图像"""
rounded_score = round(self.stats.score, -1)
score_str = f"Score: {rounded_score:,}"
self.score_image = self.font.render(score_str, True, self.text_color)
self.score_rect = self.score_image.get_rect(right=self.screen_rect.right - 20, top=20)
def prep_high_score(self):
"""渲染最高分"""
high_score_str = f"High Score: {self.stats.high_score:,}"
self.high_score_image = self.font.render(high_score_str, True, self.text_color)
self.high_score_rect = self.high_score_image.get_rect(centerx=self.screen_rect.centerx, top=20)
def prep_ships(self):
"""显示剩余生命图标"""
self.ships = pygame.sprite.Group()
for ship_number in range(self.stats.ships_left):
ship = Ship(self.game)
ship.rect.x = 10 + ship_number * (ship.rect.width + 5)
ship.rect.y = 10
self.ships.add(ship)
模块三:菜单、音效与暂停功能
目标:实现主菜单界面、音效播放和游戏暂停逻辑。
# button.py(菜单按钮)
class Button:
def __init__(self, game, msg, y_offset=0):
self.screen = game.screen
self.rect = pygame.Rect(0, 0, 200, 50)
self.rect.center = game.screen_rect.center
self.rect.y += y_offset
self._prep_msg(msg)
def _prep_msg(self, msg):
"""渲染按钮文字"""
self.msg_image = pygame.font.SysFont("Consolas", 36).render(msg, True, (255, 255, 255))
self.msg_image_rect = self.msg_image.get_rect(center=self.rect.center)
def draw(self):
"""绘制按钮"""
self.screen.fill((0, 135, 0), self.rect) # 绿色背景
self.screen.blit(self.msg_image, self.msg_image_rect)
# alien_invasion.py(音效与状态管理)
class AlienInvasion:
def _load_sounds(self):
"""加载所有音效资源"""
self.bg_music = pygame.mixer.Sound('sounds/bg_music.mp3')
self.shoot_sound = pygame.mixer.Sound('sounds/shoot.wav')
self.explosion_sound = pygame.mixer.Sound('sounds/explosion.wav')
self.bg_music.set_volume(0.3)
self.bg_music.play(-1) # 循环播放背景音乐
def _check_events(self):
"""处理菜单事件"""
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_p: # 按P键暂停
self.paused = not self.paused
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
self._check_play_button(mouse_pos) # 点击Play按钮
def _update_screen(self):
"""动态绘制界面"""
self.screen.fill(self.settings.bg_color)
if self.game_active:
self.ship.blitme()
self.bullets.draw(self.screen)
self.aliens.draw(self.screen)
self.sb.show_score()
else:
self.play_button.draw() # 显示主菜单
pygame.display.flip()
模块四:多样化敌人与技能系统
目标:扩展敌人类型,实现护盾、炸弹等特殊技能。
# alien.py(扩展敌人)
class ShieldAlien(Alien):
def __init__(self, game):
super().__init__(game)
self.image = pygame.image.load('images/shield_alien.bmp')
self.shield = 2 # 护盾层数
def hit(self):
"""被击中时减少护盾"""
self.shield -= 1
if self.shield <= 0:
self.kill()
class ShootingAlien(Alien):
def __init__(self, game):
super().__init__(game)
self.shoot_cooldown = 2000 # 射击间隔(毫秒)
self.last_shot = pygame.time.get_ticks()
def try_shoot(self):
"""尝试发射子弹"""
current_time = pygame.time.get_ticks()
if current_time - self.last_shot > self.shoot_cooldown:
self.last_shot = current_time
return AlienBullet(self.rect.center) # 返回子弹对象
# ship.py(技能实现)
class Ship:
def __init__(self, game):
# ...原有代码...
self.shield_active = False
self.shield_start_time = 0
self.bomb_count = 3 # 初始炸弹数量
def activate_shield(self):
"""激活护盾(持续5秒)"""
if not self.shield_active:
self.shield_active = True
self.shield_start_time = pygame.time.get_ticks()
def use_bomb(self):
"""使用炸弹清屏"""
if self.bomb_count > 0:
self.bomb_count -= 1
self.game.aliens.empty()
self.game.bullets.empty()
系统整合与交互逻辑
1. 初始化流程:
class AlienInvasion:
def __init__(self):
pygame.init()
self.settings = Settings()
self.stats = GameStats(self)
self.sb = Scoreboard(self)
self.ship = Ship(self)
self.aliens = pygame.sprite.Group()
self.bullets = pygame.sprite.Group()
self._create_fleet() # 生成初始外星人群
self._load_sounds()
self.play_button = Button(self, "Play", y_offset=-50)
self.quit_button = Button(self, "Quit", y_offset=50)
2. 主游戏循环:
def run_game(self):
while True:
self._check_events()
if self.game_active and not self.paused:
self.ship.update()
self._update_bullets()
self._update_aliens()
self._check_collisions()
self._check_aliens_bottom() # 检测外星人触底
self._update_screen()
关键设计总结
1. 模块化架构:各功能(外星人、计分、菜单、技能)独立实现,通过主类协调。
2. 事件驱动:统一事件循环处理输入、状态切换与资源更新。
3. 资源管理:集中加载图像、音效,支持动态替换(如护盾外星人图片)。
4. 可扩展性:通过继承(ShieldAlien)和组合(Scoreboard)灵活扩展功能。
调试与优化策略
1. 性能监控:使用 pygame.time.Clock() 控制帧率,避免CPU过载。
2. 碰撞优化:利用 pygame.sprite.Group 的批量检测代替逐元素遍历。
3. 内存管理:及时销毁越界子弹和死亡外星人,减少资源占用。
4. 平衡性调整:在 Settings 类中集中定义速度、生命值等参数,便于快速迭代。