基於py的外星人小遊戲
阿新 • • 發佈:2020-12-16
外星人小遊戲對於py的語言結構的理解有很大的幫助,對於程式碼的重構,函式,類等部分都有涉及。
alien_invasion.py
import sys import pygame from ship import Ship from settings import Settings from game_functions import check_key_events, update_screen, update_bullets, create_fleet, update_alien from pygame.sprite import Group from game_states importGame_Stats from botton import Button from scoreboard import Scoreboard def run_game(): # 初始化遊戲並建立一個螢幕物件 pygame.init() ai_settings = Settings() screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height)) pygame.display.set_caption("Alien Invasion") ship= Ship(screen, ai_settings) bullets = Group() aliens = Group() create_fleet(ai_settings, screen, ship, aliens) stats = Game_Stats(ai_settings) sb = Scoreboard(ai_settings, screen, stats) play_button = Button(ai_settings, screen, "Play") # 開始遊戲的主迴圈01 while True:# 監視鍵盤和鍵盤 check_key_events(ai_settings, screen, ship, bullets, stats, play_button, aliens,sb) if stats.game_active: ship.update() update_bullets(bullets, ai_settings, screen, ship, aliens,stats,sb) update_alien(ai_settings, stats, screen, ship, aliens, bullets) update_screen(ai_settings, screen, ship, aliens, bullets, stats, play_button, sb) run_game()
game_functions.py
import sys import pygame from bullet import Bullet from alien import Alien from ship import Ship from time import sleep from game_states import Game_Stats def fire_bullet(ai_settings, screen, ship, bullets): if len(bullets) <= ai_settings.bullet_allowed: new_bullet = Bullet(ai_settings, screen, ship) bullets.add(new_bullet) def check_key_events(ai_settings, screen, ship, bullets, stats, play_button, aliens,sb): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: 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_UP: ship.moving_up = True elif event.key == pygame.K_DOWN: ship.moving_down = True elif event.key == pygame.K_SPACE: fire_bullet(ai_settings, screen, ship, bullets) elif event.key == pygame.K_q: sys.exit() elif event.type == pygame.KEYUP: if event.key == pygame.K_RIGHT: ship.moving_right = False elif event.key == pygame.K_LEFT: ship.moving_left = False elif event.key == pygame.K_UP: ship.moving_up = False elif event.key == pygame.K_DOWN: ship.moving_down = False elif event.type == pygame.MOUSEBUTTONDOWN: mouse_x, mouse_y = pygame.mouse.get_pos() check_play_button(ai_settings, stats, play_button, mouse_x, mouse_y, aliens, screen, bullets, ship,sb) def check_play_button(ai_settings, stats, play_button, mouse_x, mouse_y, aliens, screen, bullets, ship,sb): if play_button.rect.collidepoint(mouse_x, mouse_y) and not stats.game_active: ai_settings.initialize_dynamic_settings() stats.reset_stats() stats.game_active = True sb.prep_score() sb.prep_high_score() sb.prep_level() aliens.empty() bullets.empty() create_fleet(ai_settings, screen, ship, aliens) ship.center_ship() pygame.mouse.set_visible(False) def update_bullets(bullets, ai_settings, screen, ship, aliens,stats,sb): bullets.update() for bullet in bullets.copy(): if bullet.rect.bottom <= 0: bullets.remove(bullet) check_bullet_alien_collisions(bullets, ai_settings, screen, ship, aliens,stats,sb) def check_bullet_alien_collisions(bullets, ai_settings, screen, ship, aliens,stats,sb): # 判斷外星人是否被全部消滅 if len(aliens) == 0: bullets.empty() ai_settings.increase_speed() stats.level+=1 sb.prep_level() create_fleet(ai_settings, screen, ship, aliens) collisions = pygame.sprite.groupcollide(bullets, aliens, True, True) if collisions: for aliens in collisions.values(): stats.score+=ai_settings.alien_points*len(aliens) sb.prep_score() check_high_score(stats,sb) def get_numberx(ai_setting, alien_width): available_space_x = ai_setting.screen_width - 2 * alien_width number_aliens_x = int(available_space_x / (2 * alien_width)) return number_aliens_x def get_numbery(ai_setting, alien_height, ship_height): available_space_y = ai_setting.screen_height - 2 * alien_height - ship_height number_aliens_y = int(available_space_y / (2 * alien_height)) return number_aliens_y def create_alien(ai_setting, screen, aliens, alien_numberx, alien_numbery): alien = Alien(ai_setting, screen) alien_width = alien.rect.width alien_height = alien.rect.height alien.x = alien_width + 2 * alien_width * alien_numberx alien.y = 2 * alien_height + 2 * alien_numbery * alien_height alien.rect.x = alien.x alien.rect.y = alien.y aliens.add(alien) def create_fleet(ai_settings, screen, ship, aliens): alien = Alien(ai_settings, screen) numberys = get_numbery(ai_settings, alien.rect.height, ship.rect.height) numberxs = get_numberx(ai_settings, alien.rect.width) for numbery in range(numberys): for numberx in range(numberxs): create_alien(ai_settings, screen, aliens, numberx, numbery) def check_fleet_edges(ai_settings, aliens): for alien in aliens.sprites(): if alien.check_edge(): 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 * ai_settings.fleet_direction def ship_hit(ai_settings, stats, screen, ship, aliens, bullets): if stats.ship_left > 0: stats.ship_left -= 1 bullets.empty() aliens.empty() stats.score=0 create_fleet(ai_settings, screen, ship, aliens) ship.center_ship() sleep(0.5) else: stats.game_active = False pygame.mouse.set_visible(True) def check_high_score(stats,sb): if stats.score> stats.high_score: stats.high_score=stats.score sb.prep_high_score() def check_alien_bottom(ai_settings, stats, screen, ship, aliens, bullets): screen_rect = screen.get_rect() for alien in aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: ship_hit(ai_settings, stats, screen, ship, aliens, bullets) break def update_alien(ai_settings, stats, screen, ship, aliens, bullets): check_fleet_edges(ai_settings, aliens) check_alien_bottom(ai_settings, stats, screen, ship, aliens, bullets) aliens.update() if pygame.sprite.spritecollideany(ship, aliens): ship_hit(ai_settings, stats, screen, ship, aliens, bullets) def update_screen(ai_settings, screen, ship, aliens, bullets, stats, play_button,sb): screen.fill(ai_settings.bg_color) sb.show_score() ship.blitme() aliens.draw(screen) for bullet in bullets.sprites(): bullet.draw_bullet() if not stats.game_active: play_button.draw_button() pygame.display.flip()
game_status.py
class Game_Stats(): '''統計遊戲資訊''' def __init__(self, ai_settings): self.ai_settings = ai_settings self.game_active = False self.reset_stats() self.high_score=0 self.level=0 def reset_stats(self): self.ship_left = self.ai_settings.ship_limit self.score = 0
score_board.py
import pygame class Scoreboard(): def __init__(self, ai_settings, screen, stats): self.screen = screen self.screen_rect = screen.get_rect() self.ai_settings = ai_settings self.stats = stats # 顯示得分的字型 self.text_color = (30, 30, 30) self.font = pygame.font.SysFont(None, 48) # 準備初始得分影象 self.prep_score() self.prep_high_score() self.prep_level() def prep_score(self): score_str = str(self.stats.score) self.score_image = self.font.render(score_str, True, self.text_color, self.ai_settings.bg_color) # 將得分顯示在右上角 self.score_rect = self.score_image.get_rect() self.score_rect.right = self.screen_rect.right - 20 self.score_rect.top = 20 def show_score(self): self.screen.blit(self.score_image, self.score_rect) self.screen.blit(self.high_score_image,self.high_score_rect) self.screen.blit(self.level_image,self.level_rect) def prep_high_score(self): high_score=self.stats.high_score high_score_str="{:,}".format(high_score) self.high_score_image = self.font.render(high_score_str,True,self.text_color,self.ai_settings.bg_color) self.high_score_rect=self.high_score_image.get_rect() self.high_score_rect.centerx=self.screen_rect.centerx self.high_score_rect.top=self.score_rect.top def prep_level(self): self.level_image=self.font.render(str(self.stats.level),True,self.text_color,self.ai_settings.bg_color) self.level_rect=self.level_image.get_rect() self.level_rect.right=self.score_rect.right self.level_rect.top=self.score_rect.bottom+10
bullet.py
import sys import pygame from pygame.sprite import Sprite class Bullet(Sprite): def __init__(self, ai_settings, screen, ship): super().__init__() self.screen = screen self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height) self.rect.centerx = ship.rect.centerx self.rect.top = ship.rect.top self.y = float(self.rect.y) self.color = ai_settings.bullet_color self.speed_factor = ai_settings.bullet_speed_factor def update(self): self.y -= self.speed_factor self.rect.y = self.y def draw_bullet(self): pygame.draw.rect(self.screen, self.color, self.rect)
settings.py
class Settings(): '''儲存外星人入侵的所有設定''' def __init__(self): '''初始化所有遊戲設定''' # 螢幕設定 self.screen_width = 1200 self.screen_height = 800 self.bg_color = (230, 230, 230) self.ship_speed_factor = 1.5 # 子彈設定 self.bullet_speed_factor = 1 self.bullet_width = 20 self.bullet_height = 100 self.bullet_color = (230, 0, 0) self.bullet_allowed = 3 # 外星人設定 self.alien_speed_factor = 0.5 self.fleet_drop_speed = 5 self.fleet_direction = 1 # 飛船命數 self.ship_limit = 3 # 加快遊戲速度 self.speed_scale = 1.1 self.alien_score_scale=2 self.initialize_dynamic_settings() def initialize_dynamic_settings(self): self.ship_speed_factor = 1.5 self.bullet_speed_factor = 1 self.alien_speed_factor = 0.5 self.alien_points = 1 # fleet_direction self.fleet_direction = 1 def increase_speed(self): self.ship_speed_factor *= self.speed_scale self.bullet_speed_factor *= self.speed_scale self.alien_speed_factor *= self.speed_scale self.fleet_drop_speed *= self.speed_scale self.alien_points=int(self.alien_points*self.alien_score_scale) print(self.alien_points)
ship.py
import pygame class Ship(): def __init__(self, screen, ai_settings): self.screen = screen self.ai_settings = ai_settings self.image = pygame.image.load('D:\pygame\plane.jpg') self.rect = self.image.get_rect() self.screen_rect = screen.get_rect() self.rect.centerx = self.screen_rect.centerx self.height = self.rect.height self.rect.bottom = self.screen_rect.bottom self.center = float(self.rect.centerx) self.moving_right = False self.moving_left = False self.moving_up = False self.moving_down = False def update(self): if self.moving_right and self.rect.right < self.screen_rect.right: self.rect.centerx += self.ai_settings.ship_speed_factor if self.moving_left and self.rect.left > self.screen_rect.left: self.rect.centerx -= self.ai_settings.ship_speed_factor if self.moving_up and self.rect.top > self.screen_rect.top: self.rect.bottom -= self.ai_settings.ship_speed_factor if self.moving_down and self.rect.bottom < self.screen_rect.bottom: self.rect.bottom += self.ai_settings.ship_speed_factor def blitme(self): self.screen.blit(self.image, self.rect) def center_ship(self): self.rect.centerx = self.screen_rect.centerx self.rect.bottom = self.screen_rect.bottom
allien.py
import pygame from pygame.sprite import Sprite class Alien(Sprite): def __init__(self, ai_settings, screen): super().__init__() self.screen = screen self.ai_settings = ai_settings self.image = pygame.image.load('D:\pygame\clien2.jpg') 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 blitme(self): self.screen.blit(self.image, self.rect) def update(self): self.x = self.x + (self.ai_settings.alien_speed_factor * self.ai_settings.fleet_direction) self.rect.x = self.x def check_edge(self): screen_rect = self.screen.get_rect() if self.rect.right >= screen_rect.right: return True elif self.rect.left <= 0: return True
結果展示: