diff --git a/game_functions.py b/game_functions.py new file mode 100644 index 0000000..d35f2d4 --- /dev/null +++ b/game_functions.py @@ -0,0 +1,236 @@ +import sys +from time import sleep + +import pygame + +from bullet import Bullet +from bazi import Bazi + +def check_keydown_events(event, ai_settings, screen, man, bullets): + """对按键做出反应""" + if event.key == pygame.K_RIGHT: + man.moving_right = True + elif event.key == pygame.K_LEFT: + man.moving_left = True + elif event.key == pygame.K_SPACE: + fire_bullet(ai_settings, screen, man, bullets) + elif event.key == pygame.K_q: + sys.exit() + +def check_keyup_events(event, man): + """响应按键的发布""" + if event.key == pygame.K_RIGHT: + man.moving_right = False + elif event.key == pygame.K_LEFT: + man.moving_left = False + +def check_events(ai_settings, screen, stats, sb, play_button, man, bazis, + bullets): + """响应按键和鼠标事件""" + for event in pygame.event.get(): + if event.type == pygame.QUIT: + sys.exit() + elif event.type == pygame.KEYDOWN: + check_keydown_events(event, ai_settings, screen, man, bullets) + elif event.type == pygame.KEYUP: + check_keyup_events(event, man) + elif event.type == pygame.MOUSEBUTTONDOWN: + mouse_x, mouse_y = pygame.mouse.get_pos() + check_play_button(ai_settings, screen, stats, sb, play_button, + man, bazis, bullets, mouse_x, mouse_y) + +def check_play_button(ai_settings, screen, stats, sb, play_button, man, + bazis, bullets, mouse_x, mouse_y): + """当玩家点击Play时开始一个新游戏""" + button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y) + if button_clicked and not stats.game_active: + # 重置游戏设置 + ai_settings.initialize_dynamic_settings() + + # 隐藏鼠标光标 + pygame.mouse.set_visible(False) + + # 重置游戏统计信息 + stats.reset_stats() + stats.game_active = True + + # 重置记分板图像 + sb.prep_score() + sb.prep_high_score() + sb.prep_level() + sb.prep_mans() + + # 清空靶子和子弹的名单 + bazis.empty() + bullets.empty() + + # 创建一个人并将其置于中心 + create_fleet(ai_settings, screen, man, bazis) + man.center_man() + +def fire_bullet(ai_settings, screen, man, bullets): + """发射一颗子弹,如果还没有达到极限""" + # 创建新项目符号,添加到项目符号组 + if len(bullets) < ai_settings.bullets_allowed: + new_bullet = Bullet(ai_settings, screen, man) + bullets.add(new_bullet) + +def update_screen(ai_settings, screen, stats, sb, man, bazis, bullets, + play_button): + """更新屏幕上的图像,然后切换到新屏幕。""" + # 重新绘制屏幕,每次通过循环 + screen.fill(ai_settings.bg_color) + + # 重画所有子弹,在人和靶子后面 + for bullet in bullets.sprites(): + bullet.draw_bullet() + man.blitme() + bazis.draw(screen) + + # 绘制分数信息 + sb.show_score() + + # 如果游戏处于非活动状态,则绘制播放按钮 + if not stats.game_active: + play_button.draw_button() + + # 使最近绘制的屏幕可见 + pygame.display.flip() + +def update_bullets(ai_settings, screen, stats, sb, man, bazis, bullets): + """更新子弹的位置,清除旧子弹""" + # 更新子弹位置 + bullets.update() + + # 扔掉已经消失的子弹 + for bullet in bullets.copy(): + if bullet.rect.bottom <= 0: + bullets.remove(bullet) + + check_bullet_bazi_collisions(ai_settings, screen, stats, sb, man, + bazis, bullets) + +def check_high_score(stats, sb): + """查看是否有新的高分""" + if stats.score > stats.high_score: + stats.high_score = stats.score + sb.prep_high_score() + +def check_bullet_bazi_collisions(ai_settings, screen, stats, sb, man, + bazis, bullets): + """对子弹和靶子的碰撞做出反应(碰撞检测)""" + # 移除所有碰撞的子弹和靶子 + collisions = pygame.sprite.groupcollide(bullets, bazis, True, True) + + if collisions: + for bazis in collisions.values(): + stats.score += ai_settings.bazi_points * len(bazis) + sb.prep_score() + check_high_score(stats, sb) + + if len(bazis) == 0: + # 如果靶子都被摧毁,开始一个新的关卡 + bullets.empty() + ai_settings.increase_speed() + + # 提高水平 + stats.level += 1 + sb.prep_level() + + create_fleet(ai_settings, screen, man, bazis) + +def check_fleet_edges(ai_settings, bazis): + """如果有靶子到达边缘,请做出适当的反应""" + for bazi in bazis.sprites(): + if bazi.check_edges(): + change_fleet_direction(ai_settings, bazis) + break + +def change_fleet_direction(ai_settings, bazis): + """放下整个队列,改变队列的方向""" + for bazi in bazis.sprites(): + bazi.rect.y += ai_settings.fleet_drop_speed + ai_settings.fleet_direction *= -1 + +def man_hit(ai_settings, screen, stats, sb, man, bazis, bullets): + """回应被靶子碰撞的人""" + if stats.mans_left > 0: + # 向左递减 + stats.mans_left -= 1 + + # 更新分数面板 + sb.prep_mans() + + else: + stats.game_active = False + pygame.mouse.set_visible(True) + + # 清空靶子和子弹的名单 + bazis.empty() + bullets.empty() + + # 创建一个新角色,并将人居中 + create_fleet(ai_settings, screen, man, bazis) + man.center_man() + + sleep(0.5) + +def check_bazis_bottom(ai_settings, screen, stats, sb, man, bazis, + bullets): + """检查是否有靶子到达屏幕底部""" + screen_rect = screen.get_rect() + for bazi in bazis.sprites(): + if bazi.rect.bottom >= screen_rect.bottom: + # 人被击中一样 + man_hit(ai_settings, screen, stats, sb, man, bazis, bullets) + break + +def update_bazis(ai_settings, screen, stats, sb, man, bazis, bullets): + """ + 检查靶子是否处于边缘,然后更新靶子中所有靶子的位置 + """ + check_fleet_edges(ai_settings, bazis) + bazis.update() + + # 寻找人和靶子碰撞 + if pygame.sprite.spritecollideany(man, bazis): + man_hit(ai_settings, screen, stats, sb, man, bazis, bullets) + + # 在屏幕底部寻找靶子 + check_bazis_bottom(ai_settings, screen, stats, sb, man, bazis, bullets) + +def get_number_bazis_x(ai_settings, bazi_width): + """确定排成一行的外星人的数量""" + available_space_x = ai_settings.screen_width - 1 * bazi_width + number_bazi_x = int(available_space_x / (2 * bazi_width)) + return number_bazi_x + +def get_number_rows(ai_settings, man_height, bazi_height): + """确定适合屏幕的外星人行数""" + available_space_y = (ai_settings.screen_height - + (1 * bazi_height) - man_height) + number_rows = int(available_space_y / (2 * bazi_height)) + return number_rows + +def create_bazi(ai_settings, screen, bazis, bazi_number, row_number): + """创建一个靶子,并将其放置在行中""" + bazi = Bazi(ai_settings, screen) + bazi_width = bazi.rect.width + bazi.x = bazi_width + 2 * bazi_width * bazi_number + bazi.rect.x = bazi.x + bazi.rect.y = bazi.rect.height + 2 * bazi.rect.height * row_number + bazis.add(bazi) + +def create_fleet(ai_settings, screen, man, bazis): + """创造一个完整的靶子队列""" + # 创建一个靶子,并查找一行中的靶子数量 + bazi = Bazi(ai_settings, screen) + number_bazis_x = get_number_bazis_x(ai_settings, bazi.rect.width) + number_rows = get_number_rows(ai_settings, man.rect.height, + bazi.rect.height) + + # 创造外星人舰队 + for row_number in range(number_rows): + for bazi_number in range(number_bazis_x): + create_bazi(ai_settings, screen, bazis, bazi_number, + row_number)