From 3ad7e2a426489987abb80c57d086a17329115c2c Mon Sep 17 00:00:00 2001 From: 206530118 <3046257660@qq.com> Date: Thu, 24 Jun 2021 12:44:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=20'game=5Ffunctions.py'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game_functions.py | 409 ---------------------------------------------- 1 file changed, 409 deletions(-) delete mode 100644 game_functions.py diff --git a/game_functions.py b/game_functions.py deleted file mode 100644 index 78dcf2c..0000000 --- a/game_functions.py +++ /dev/null @@ -1,409 +0,0 @@ -import sys -import pygame -import random -import operator -import json -from bullet import Bullet -from super_bullet import SuperBullet -from alien import Alien -from alien_bullet import AlienBullet -from time import sleep -from threading import Timer - - -""" -用户操作响应 -""" - -def check_events(ai_settings, screen, ship, bullets, aliens, stats, play_button, scoreboard, alien_bullets, super_bullets, playername_inputbox): - """响应按键和鼠标事件""" - 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, ship, bullets, stats, scoreboard, super_bullets, playername_inputbox) - elif event.type == pygame.KEYUP: - check_keyup_events(event, ship) - elif event.type == pygame.MOUSEBUTTONDOWN: - mouse_x, mouse_y = pygame.mouse.get_pos() - check_playername_input(playername_inputbox, stats, mouse_x, mouse_y) - check_play_button(ai_settings, screen, ship, bullets, aliens, stats, play_button, mouse_x, mouse_y, scoreboard, alien_bullets, super_bullets, playername_inputbox) - - -def check_keydown_events(event, ai_settings, screen, ship, bullets, stats, scoreboard, super_bullets, playername_inputbox): - """响应按键按下""" - if event.key == pygame.K_RIGHT: - ship.moving_right = True - elif event.key == pygame.K_LEFT: - ship.moving_left = True - elif event.key == pygame.K_SPACE: - if stats.game_active: - fire_bullet(ai_settings, screen, ship, bullets) - elif event.key == pygame.K_UP: - if stats.game_active: - activate_super_mode(ai_settings, ship, stats, scoreboard) - elif event.key == pygame.K_LALT: - if stats.game_active: - fire_super_bullet(ai_settings, screen, ship, stats, super_bullets) - elif event.key == pygame.K_q: - sys.exit() - else: - if playername_inputbox.login == False: - playername_inputbox.key_down(event) - -def check_keyup_events(event, ship): - """响应按键松开""" - if event.key == pygame.K_RIGHT: - ship.moving_right = False - elif event.key == pygame.K_LEFT: - ship.moving_left = False - - -def check_playername_input(playername_inputbox, stats, mouse_x, mouse_y): - """检查用户点击玩家名称输入框,若点击,则清空文本""" - if playername_inputbox.rect.collidepoint(mouse_x, mouse_y) and not stats.game_active: - playername_inputbox.text = '' - -def check_play_button(ai_settings, screen, ship, bullets, aliens, stats, play_button, mouse_x, mouse_y, scoreboard, alien_bullets, super_bullets, playername_inputbox): - """检查开始游戏按钮是否被按下,并响应""" - if play_button.rect.collidepoint(mouse_x, mouse_y) and not stats.game_active: - # 隐藏光标 - pygame.mouse.set_visible(False) - # 重置游戏参数 - ai_settings.initialize_dynamic_settings() - stats.reset_stats() - # 重置记分牌 - scoreboard.prep_images() - # 设置状态为激活 - stats.game_active = True - # 清屏并创建新的一群外星人 - clear_and_create_fleet(ai_settings, screen, ship, bullets, aliens, alien_bullets, super_bullets) - if playername_inputbox.login == False: - stats.player = playername_inputbox.text - playername_inputbox.login = True - - -def fire_super_bullet(ai_settings, screen, ship, stats, super_bullets): - if stats.power >= ai_settings.points_of_power: - ai_settings.super_bullet_sound.play() - new_super_bullet = SuperBullet(ai_settings, screen, ship) - super_bullets.add(new_super_bullet) - stats.power -= ai_settings.points_of_power - - -def fire_bullet(ai_settings, screen, ship, bullets): - if len(bullets) < ai_settings.bullets_allowed: - ai_settings.bullet_sound.play() - new_bullet = Bullet(ai_settings, screen, ship) - bullets.add(new_bullet) - - -def activate_super_mode(ai_settings, ship, stats, scoreboard): - """响应进入无敌模式""" - if stats.power >= ai_settings.points_of_power: - if ship.super_mode == False: - ai_settings.super_mode_sound.play() - ship.super_mode = True - stats.power -= ai_settings.points_of_power - scoreboard.prep_power() - Timer(5, quit_super_mode, args=[ship]).start() - -def quit_super_mode(ship): - ship.super_mode = False - - -""" -子弹参数更新(包括超级子弹) -""" - -def update_bullets(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, super_bullets): - """更新子弹位置并检查碰撞""" - # 更新子弹位置 - bullets.update() - super_bullets.update() - # 删除已超出范围的子弹 - for bullet in bullets.copy(): - if bullet.rect.bottom <= 0: - bullets.remove(bullet) - for super_bullet in super_bullets.copy(): - if super_bullet.rect.bottom <= 0: - super_bullets.remove(super_bullet) - - check_bullet_alien_collision(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, super_bullets) - - -def check_bullet_alien_collision(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, super_bullets): - """响应子弹击中外星人""" - # 检查是否有子弹击中外星人,若有,删除对应的子弹与外星人 - collisions = pygame.sprite.groupcollide(bullets, aliens, True, True) - super_collisions = pygame.sprite.groupcollide(super_bullets, aliens, False, True) - - if collisions: - for aliens in collisions.values(): - stats.score += ai_settings.alien_points * len(aliens) - stats.power += ai_settings.alien_points * len(aliens) - scoreboard.prep_score() - scoreboard.prep_power() - # 检查是否打破历史记录 - check_high_score(stats, scoreboard) - - if super_collisions: - for aliens in super_collisions.values(): - stats.score += ai_settings.alien_points * len(aliens) - stats.power += ai_settings.alien_points * len(aliens) - scoreboard.prep_score() - scoreboard.prep_power() - # 检查是否打破历史记录 - check_high_score(stats, scoreboard) - - if len(aliens) == 0: - # 外星人被消灭干净,开启新等级 - start_new_level(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, super_bullets) - - -def start_new_level(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, super_bullets): - """响应外星人被消灭干净""" - ai_settings.start_new_level_sound.play() - bullets.empty() - super_bullets.empty() - ai_settings.increase_speed() - create_fleet(ai_settings, screen, ship, aliens) - stats.level += 1 - scoreboard.prep_level() - - -def check_high_score(stats, scoreboard): - """响应打破历史记录""" - if stats.score > stats.high_score: - stats.high_score = stats.score - scoreboard.prep_high_score() - - -""" -外星人参数更新 -""" - -def update_aliens(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets): - """更新所有外星人的位置""" - check_fleet_edges(ai_settings, aliens) - aliens.update() - - # 检测外星人和飞船的碰撞 - if pygame.sprite.spritecollideany(ship, aliens): - ship_hit(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets) - - check_aliens_bottom(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets) - - -def check_fleet_edges(ai_settings, aliens): - """有外星人到达屏幕边缘时采取相应措施""" - for alien in aliens.sprites(): - if alien.check_edges(): - change_fleet_direction(ai_settings, aliens) - break - -def change_fleet_direction(ai_settings, aliens): - """将外星人整体下移一行并改变移动方向""" - for alien in aliens.sprites(): - alien.rect.y += ai_settings.fleet_drop_speed - ai_settings.fleet_direction *= -1 - - -def check_aliens_bottom(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets): - """检查是否有外星人撞到屏幕底端""" - screen_rect = screen.get_rect() - for alien in aliens.sprites(): - if alien.rect.bottom >= screen_rect.bottom: - # 像飞船与外星人相撞一样处理 - ship_hit(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets) - break - -def ship_hit(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets): - """响应飞船与外星人碰撞""" - if stats.ships_left > 0: - """仍有剩余飞船,游戏继续""" - ai_settings.ship_hit_sound.play() - # 将剩余飞船数减一 - stats.ships_left -= 1 - # 清空外星人和子弹列表并创建一批新外星人 - clear_and_create_fleet(ai_settings, screen, ship, bullets, aliens, alien_bullets, super_bullets) - # 更新剩余飞船数 - scoreboard.prep_ships() - - else: - """游戏结束""" - if stats.score == stats.high_score: - ai_settings.recordbroken_sound.play() - else: - ai_settings.gameover_sound.play() - stats.game_active = False - pygame.mouse.set_visible(True) - - # 记录此次玩家得分 - new_score = { 'player': stats.player, 'score': stats.score } - stats.scores_data.append(new_score) - stats.scores_data.sort(key=lambda x:x["score"], reverse=True) - with open('scores.json', 'w') as f: - json.dump(stats.scores_data, f) - - # 打印历史得分排行榜Top10 - if len(stats.scores_data) >= 10: - leaderboard_height = 340 - else: - leaderboard_height = len(stats.scores_data) * 30 + 40 - - leaderboard_rect = pygame.Rect(450, 180, 300, leaderboard_height) - screen.fill(ai_settings.lb_bg_color, leaderboard_rect) - - # 表头 - leaderboard_font = pygame.font.SysFont("Calibri, Arial", 28) - rank_image_rect = draw_leaderboard(ai_settings.lb_text_color, ai_settings.lb_bg_color, screen, 'Rank', leaderboard_font, 500, 200) - player_image_rect = draw_leaderboard(ai_settings.lb_text_color, ai_settings.lb_bg_color, screen, 'Player', leaderboard_font, 600, 200) - score_image_rect = draw_leaderboard(ai_settings.lb_text_color, ai_settings.lb_bg_color, screen, 'Score', leaderboard_font, 700, 200) - - rank = 0 - for player_score in stats.scores_data: - """逐个显示玩家得分""" - rank += 1 - if rank > 10: - break - rank_text = str(rank) - player_text = str(player_score["player"]) - score_text = str(player_score["score"]) - y_postion = rank_image_rect.centery + 30 * rank - font = leaderboard_font - text_color = ai_settings.lb_text_color - bg_color = ai_settings.lb_bg_color - if player_score == new_score: - """当前用户的信息,样式不同""" - general_font = pygame.font.SysFont("Calibri, Arial", 32, True) - text_color = (255, 255, 0) - - draw_leaderboard(text_color, bg_color, screen, rank_text, font, rank_image_rect.centerx, y_postion) - draw_leaderboard(text_color, bg_color, screen, player_text, font, player_image_rect.centerx, y_postion) - draw_leaderboard(text_color, bg_color, screen, score_text, font, score_image_rect.centerx, y_postion) - - pygame.display.flip() - sleep(5) - - sleep(0.5) - - -def draw_leaderboard(text_color ,bg_color, screen, text, font, x, y): - """绘制排行榜的某一项""" - image = font.render(text, True, text_color, bg_color) - image_rect = image.get_rect() - image_rect.centerx = x - image_rect.centery = y - screen.blit(image, image_rect) - return image_rect - - -def clear_and_create_fleet(ai_settings, screen, ship, bullets, aliens, alien_bullets, super_bullets): - """清空外星人和子弹列表并创建一批新外星人""" - # 清空外星人和子弹列表 - bullets.empty() - super_bullets.empty() - aliens.empty() - alien_bullets.empty() - - # 创建一批新的外星人,并将飞船放到屏幕底部中央 - create_fleet(ai_settings, screen, ship, aliens) - ship.center_ship() - - -def create_fleet(ai_settings, screen, ship, aliens): - """创建外星人群""" - alien = Alien(ai_settings, screen) - number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width) - number_rows = get_number_rows(ai_settings, alien.rect.height, ship.rect.height) - for row_number in range(number_rows): - for alien_number in range(number_aliens_x): - create_alien(ai_settings, screen, aliens, alien_number, row_number) - -def get_number_aliens_x(ai_settings, alien_width): - """计算一行可容纳多少外星人""" - available_space_x = ai_settings.screen_width - 2 * alien_width - number_aliens_x = int(available_space_x / (2 * alien_width)) - return number_aliens_x - -def get_number_rows(ai_settings, alien_height, ship_height): - """计算可容纳多少行外星人""" - available_space_y = ai_settings.screen_height - 6 * alien_height - ship_height - number_rows = int(available_space_y / (2 * alien_height)) - return number_rows - -def create_alien(ai_settings, screen, aliens, alien_number, row_number): - """创建一个外星人并把它加入当前行""" - alien = Alien(ai_settings, screen) - alien_width = alien.rect.width - alien_height = alien.rect.height - alien.x = alien_width + 2 * alien_width * alien_number - alien.rect.x = alien.x - alien.rect.y = alien_height + 2 * alien_height * row_number - aliens.add(alien) - - -""" -外星人子弹更新 -""" - -def update_aliens_fire_bullet(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets): - """更新外星人发射的子弹""" - for alien in aliens.sprites(): - flag_is_last_line = True - for alien_next in aliens.sprites(): - if (alien.rect.y + alien.rect.height * 2 == alien_next.rect.y - and alien.rect.x == alien_next.rect.x): - flag_is_last_line = False - break - if flag_is_last_line: - """外星人有一定的概率发射子弹""" - if random.randint(0,3000) < 1: - new_alien_bullet = AlienBullet(ai_settings, screen, alien) - alien_bullets.add(new_alien_bullet) - - check_alien_bullet_ship_collision(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets) - alien_bullets.update() - - -def check_alien_bullet_ship_collision(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets): - """响应外星人子弹击中飞船""" - for alien_bullet in alien_bullets.sprites(): - if alien_bullet.rect.colliderect(ship.rect) and not ship.super_mode: - ship_hit(ai_settings, screen, ship, bullets, aliens, stats, scoreboard, alien_bullets, super_bullets) - break - - -""" -屏幕更新 -""" - -def update_screen(ai_settings, screen, ship, bullets, aliens, stats, play_button, scoreboard, alien_bullets, super_bullets, playername_inputbox): - """更新屏幕上的图像,并切换到新屏幕""" - # 重绘屏幕 - screen.fill(ai_settings.bg_color) - if playername_inputbox.login == False: - playername_inputbox.draw_inputbox() - - # 绘制全部子弹 - for bullet in bullets.sprites(): - bullet.draw_bullet() - for alien_bullet in alien_bullets.sprites(): - alien_bullet.draw_alien_bullet() - for super_bullet in super_bullets.sprites(): - super_bullet.draw_bullet() - # 绘制玩家飞船 - ship.blitme() - # 绘制全部外星人 - aliens.draw(screen) - scoreboard.ships.draw(screen) - # 显示得分 - scoreboard.show_score() - - # 如果游戏处于非活动状态,就显示Play按钮 - if stats.game_active == False: - play_button.draw_button() - - # 让最近绘制的屏幕可见 - pygame.display.flip()