AlienInvasion.py 1 """ 2 BlackAlien名称是因为飞船是黑色的 3 该文件是alien invasion的主程序 4 """ 5 6 from settings import Settings 7 from ship import Ship 8 from game_function import * 9 from pygame.sprite import Group 10 from bullet import * 11 from game_stats import GameStats 12 13 14 def run_game(): 15 pygame.init() 16 settings = Settings() 17 screen = pygame.display.set_mode((settings.screen_width, settings.screen_height)) 18 ship = Ship(screen) 19 bullets = Group() 20 aliens = Group() 21 stats = GameStats(settings) 22 23 pygame.display.set_caption(‘Alien invasion‘) 24 screen.fill(settings.screen_bg_color) 25 create_fleet(settings, screen, aliens, ship) 26 27 while True: 28 check_events(settings, screen, ship, bullets) 29 30 if stats.game_active: 31 ship.update_ship(settings) 32 update_bullets(bullets, aliens, settings, screen, ship) 33 update_screen(settings, screen, ship, bullets, aliens) 34 update_aliens(settings, aliens, ship, stats, bullets, screen) 35 bullets.update() 36 37 run_game()
alien.py 1 import pygame 2 from pygame.sprite import Sprite 3 4 5 class Alien(Sprite): 6 """ 7 创建的外星人的类 8 """ 9 10 def __init__(self, ai_setting, screen): 11 super().__init__() 12 13 self.screen = screen 14 self.ai_setting = ai_setting 15 16 # 加载图像 17 self.image = pygame.image.load(‘images/alien.png‘) 18 self.rect = self.image.get_rect() 19 20 # 设置外星人的位置 21 self.rect.x = self.ai_setting.screen_width - self.rect.width*2 22 self.rect.y = self.rect.height 23 # rect(self.rect.height, self.rect.width) 24 25 def blitme(self): 26 self.screen.blit(self.image, self.rect) 27 28 def check_edges(self): 29 """ 30 检查alien是否碰触到屏幕的边缘 31 :return: 32 """ 33 screen_rect = self.screen.get_rect() 34 if self.rect.top <= 0: 35 return True 36 elif self.rect.bottom >= screen_rect.bottom: 37 return True 38 39 def update(self): 40 self.rect.y += self.ai_setting.alien_move_speed_factor * self.ai_setting.fleet_move_direction
bullet.py 1 """ 2 定义bullte对象,通过调用Sprite 3 """ 4 import pygame 5 from pygame.sprite import Sprite 6 7 8 class Bullet(Sprite): 9 def __init__(self, ai_settings, screen, ship): 10 super().__init__() 11 self.screen = screen 12 13 # 先创建一个子弹,然后放到固定的位置 14 self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height) 15 self.rect.centery = ship.rect.centery 16 self.rect.left = ship.rect.right 17 self.color = ai_settings.bullet_color 18 self.speed_factor = ai_settings.bullet_speed_factor 19 20 def update(self): 21 """ 22 更新子弹的位置 23 :return: 0 24 """ 25 self.rect.x += self.speed_factor 26 27 def draw_bullet(self): 28 pygame.draw.rect(self.screen, self.color, self.rect)
game_function.py 1 import pygame 2 import sys 3 from bullet import Bullet 4 from alien import Alien 5 from time import sleep 6 7 8 """用于执行游戏的功能 9 1.用于检测按键事件,按上键向上边移动,按下键向下边移动 10 2.防止飞船移动出主窗口; 11 3.可以设置飞船的移动速度; 12 """ 13 14 15 def check_events(ai_settings, screen, ship, bullets): 16 for event in pygame.event.get(): 17 # 通过循环来不停获取事件 18 19 # 1.退出的情况 20 if event.type == pygame.QUIT: 21 sys.exit() 22 # 2.按下按键的情况 23 elif event.type == pygame.KEYDOWN: 24 check_key_down(event, ai_settings, screen, ship, bullets) 25 # 3.按键弹起来的情况 26 elif event.type == pygame.KEYUP: 27 check_key_up(event, ship) 28 29 30 def check_key_down(event, ai_settings, screen, ship, bullets): 31 """处理按下按键的情况""" 32 if event.key == pygame.K_q: 33 sys.exit() 34 elif event.key == pygame.K_UP: 35 ship.up_moving = True 36 elif event.key == pygame.K_DOWN: 37 ship.down_moving = True 38 elif event.key == pygame.K_SPACE: 39 # 创建一个bullet的对象,限制子弹的数量 40 if len(bullets) < ai_settings.bullet_allowed: 41 new_bullet = Bullet(ai_settings, screen, ship) 42 bullets.add(new_bullet) 43 44 45 def check_key_up(event, ship): 46 """处理按键弹起的情况""" 47 if event.key == pygame.K_UP: 48 ship.up_moving = False 49 elif event.key == pygame.K_DOWN: 50 ship.down_moving = False 51 52 53 def update_screen(ai_settings, screen, ship, bullets, aliens): 54 screen.fill(ai_settings.screen_bg_color) 55 ship.blit_black_ship() 56 aliens.draw(screen) 57 58 # 在飞船和外星人后面绘制所有的子弹 59 for bullet in bullets.sprites(): 60 bullet.draw_bullet() 61 62 pygame.display.flip() 63 64 65 def update_bullets(bullets, aliens, ai_settings, screen, ship): 66 bullets.update() 67 # 删除已经消失的子弹 68 for bullet in bullets.copy(): 69 if bullet.rect.left > ai_settings.screen_width: 70 bullets.remove(bullet) 71 72 check_bullet_alien_collisions(ai_settings, screen, ship, aliens, bullets) 73 74 75 def check_bullet_alien_collisions(ai_settings, screen, ship, aliens, bullets): 76 # 检查是否有子弹击中alien,击中删除两个 77 pygame.sprite.groupcollide(bullets, aliens, True, True) 78 79 # 如果外星人为空,就创建一波新的外星人 80 if len(aliens) == 0: 81 bullets.empty() 82 create_fleet(ai_settings, screen, aliens, ship) 83 84 85 def get_alien_number(ai_settings, alien_height): 86 """ 87 获取能够容纳的外星人的个数 88 :param ai_settings: 89 :param alien_height: 90 :return: 91 """ 92 available_space_y = ai_settings.screen_height - 2 * alien_height 93 number_alien_y = int(available_space_y / (2 * alien_height)) 94 return number_alien_y 95 96 97 def get_alien_row(ai_settings, ship_width, alien_width): 98 """ 99 :param ai_settings: 100 :param alien_width: 101 :return: 可以容纳的列=screen_width-ship_width-aline_width*3 (预留2倍的外星人的宽度+右边外星人的宽度) 102 """ 103 alien_num_in_row = int((ai_settings.screen_width - ship_width - 15*alien_width)/(2*alien_width)) 104 return alien_num_in_row 105 106 107 def create_alien(ai_settings, screen, aliens, alien_number,row): 108 """ 109 :param ai_settings: 110 :param screen: 111 :param aliens: 112 :param alien_number 113 :return: 114 """ 115 alien = Alien(ai_settings,screen) 116 alien_height = alien.rect.height 117 118 alien.rect.y = alien_height + alien_number*alien.rect.height*2 119 120 # 每次都要更新x 坐标的值 121 alien.rect.x = ai_settings.screen_width - alien.rect.width*row*2 122 aliens.add(alien) 123 124 125 def create_fleet(ai_settings, screen, aliens, ship): 126 """ 创建外星人群""" 127 ‘‘‘创建一个外星人,并且计算可以容纳多少个‘‘‘ 128 ‘‘‘外星人间距为外星人的宽度‘‘‘ 129 alien = Alien(ai_settings, screen) 130 alien_height = alien.rect.height 131 alien_numbers = get_alien_number(ai_settings, alien_height) 132 133 # 确认可以容纳多少个row的外星人 134 ship_width = ship.rect.width 135 alien_width = alien.rect.width 136 alien_num_in_row = get_alien_row(ai_settings, ship_width, alien_width) 137 # print("可用的row",alien_num_in_row,sep=‘ | ‘) 138 139 for row in range(1, alien_num_in_row+1): 140 for alien_number in range(alien_numbers): 141 create_alien(ai_settings, screen, aliens, alien_number, row) 142 143 144 def check_fleet_edges(ai_settings, aliens): 145 """ 146 检查fleet中是否有超过screen的,如果只要有一个就改变整个队列的方向 147 :return: 148 """ 149 for alien in aliens.sprites(): 150 if alien.check_edges(): 151 change_fleet_direction(ai_settings, aliens) 152 break 153 154 155 def change_fleet_direction(ai_settings, aliens): 156 ai_settings.fleet_move_direction *= -1 157 158 # 向下移动一格 159 for alien in aliens.sprites(): 160 alien.rect.x -= ai_settings.alien_drop_speed_factor 161 162 163 def update_aliens(ai_settings, aliens, ship, stats, bullets, screen): 164 if check_fleet_edges(ai_settings, aliens): 165 change_fleet_direction(ai_settings, aliens) 166 167 ship_hit(ai_settings, ship, stats, bullets, screen, aliens) 168 169 170 def ship_hit(ai_settings, ship, stats, bullets, screen, aliens): 171 aliens.update() 172 173 # 检测外星人是否和飞船相撞,以及是否到达了底部 174 if pygame.sprite.spritecollideany(ship, aliens) or check_aliens_reach_bottom(aliens, screen): 175 stats.ship_left -= 1 176 print("Ship hit!!!") 177 178 # 一旦撞上后就清空外星人和子弹,然后重建外星人,并且将飞船放置到中间的位置 179 aliens.empty() 180 bullets.empty() 181 sleep(0.5) 182 ship.rect.y = ai_settings.screen_height/2 183 create_fleet(ai_settings, screen, aliens, ship) 184 185 if stats.ship_left == 0: 186 print("GAME OVER!") 187 stats.game_active = False 188 189 190 def check_aliens_reach_bottom(aliens, screen): 191 """检查飞船是否到达了底部""" 192 screen_rect = screen.get_rect() 193 for alien in aliens.sprites(): 194 while alien.rect.left <= screen_rect.left: 195 print("超过范围!") 196 return True 197 else: 198 return False
game_stats.py 1 class GameStats(object): 2 """ 3 用于记录游戏中的各个状态 4 """ 5 6 def __init__(self, ai_settings): 7 self.ai_settings = ai_settings 8 self.ship_left = ai_settings.ship_limit 9 self.reset_stats() 10 self.game_active = True 11 12 def reset_stats(self): 13 """初始化游戏初期的各个参数""" 14 15 self.ship_left = self.ai_settings.ship_limit
settings.py 1 """ 2 This file stores the parameters of all elements. 3 1. screen parameters; 4 2. ship parameters; 5 3. bullet parameters; 6 该类只是用来存储用到的数据 7 """ 8 9 10 class Settings(object): 11 """Store configuration parameters""" 12 13 def __init__(self): 14 # Screen configuration 15 self.caption = ‘Alien invasion‘ 16 self.screen_width = 800 17 self.screen_height = 600 18 self.screen_bg_color = 255, 255, 255 19 self.ship_move_speed = 1.5 20 self.bullet_speed_factor = 2 21 self.bullet_width = 10 22 self.bullet_height = 300 23 self.bullet_color = 255, 0, 0 24 self.bullet_allowed = 3 25 self.alien_move_speed_factor = 1 26 self.fleet_move_direction = 1 27 self.alien_drop_speed_factor = 50 28 self.ship_limit = 3
ship.py 1 """ 2 Description of ship 3 """ 4 import pygame 5 6 7 class Ship(object): 8 """Ship class""" 9 def __init__(self, screen): 10 """Initiate ship""" 11 self.screen = screen 12 self.black_ship_image = pygame.image.load(‘images/black_ship.png‘) # 这里注意路径image前面没有/ 13 # Get screen and ship rect 14 self.rect = self.black_ship_image.get_rect() 15 self.screen_rect = self.screen.get_rect() 16 self.up_moving = False 17 self.down_moving = False 18 19 # Set position of ship 20 self.rect.left = self.screen_rect.left 21 self.rect.centery = self.screen_rect.centery 22 23 # 用于来保存小数 24 self.temp_centery = float(self.screen_rect.centery) 25 26 def blit_black_ship(self): 27 """Display ship on the screen""" 28 self.screen.blit(self.black_ship_image, self.rect) 29 30 def update_ship(self, settings): 31 """用户更新飞船的位置""" 32 if self.up_moving and self.rect.top > 0: 33 self.temp_centery -= float(settings.ship_move_speed) 34 self.rect.centery = self.temp_centery 35 # print(self.rect.centery) 36 37 if self.down_moving and self.rect.bottom < self.screen_rect.bottom: 38 self.temp_centery += float(settings.ship_move_speed) 39 self.rect.centery = self.temp_centery 40 # print(self.rect.centery)
运行的效果如下:
======================================================================================================================
先到这里,后续有空再更新游戏开始、积分等功能 :)
原文地址:https://www.cnblogs.com/yangfan2018/p/9344546.html
时间: 2024-10-16 04:14:04