|
| 1 | +import pygame, random |
| 2 | +from sys import exit |
| 3 | +from pygame.locals import * |
| 4 | +from pl_model import * |
| 5 | + |
| 6 | +# 设置屏幕的宽度 |
| 7 | +SCREEN_WIDTH = 450 |
| 8 | +# 设置屏幕的高度 |
| 9 | +SCREEN_HEIGHT = 600 |
| 10 | +# 初始化窗口 |
| 11 | +pygame.init() |
| 12 | +# 设置窗口标题 |
| 13 | +pygame.display.set_caption("飞机大战") |
| 14 | +# 设置屏幕大小 |
| 15 | +screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) |
| 16 | +# 隐藏光标 |
| 17 | +pygame.mouse.set_visible(False) |
| 18 | +# 设置背景 |
| 19 | +bg = pygame.image.load("resources/image/bg.png") |
| 20 | +# 设置游戏结束的图片 |
| 21 | +bg_game_over = pygame.image.load("resources/image/bg_game_over.png") |
| 22 | +# 加载飞机资源图片 |
| 23 | +img_plane = pygame.image.load("resources/image/shoot.png") |
| 24 | +img_start = pygame.image.load("resources/image/start.png") |
| 25 | +img_pause = pygame.image.load("resources/image/pause.png") |
| 26 | +img_icon = pygame.image.load("resources/image/plane.png").convert_alpha() |
| 27 | +# 顺便设置窗口 |
| 28 | +pygame.display.set_icon(img_icon) |
| 29 | +# 初始化飞机区域 |
| 30 | +player_rect = [] |
| 31 | +player_rect.append(pygame.Rect(0, 99, 102, 126)) |
| 32 | +player_rect.append(pygame.Rect(165, 360, 102, 126)) |
| 33 | +# 玩家爆炸图片 |
| 34 | +player_rect.append(pygame.Rect(165, 234, 102, 126)) |
| 35 | +player_rect.append(pygame.Rect(330, 624, 102, 126)) |
| 36 | +player_rect.append(pygame.Rect(330, 498, 102, 126)) |
| 37 | +player_rect.append(pygame.Rect(432, 624, 102, 126)) |
| 38 | +# 初始化位置 |
| 39 | +player_pos = [200, 450] |
| 40 | +# 生成玩家类 |
| 41 | +player = Player(img_plane, player_rect, player_pos) |
| 42 | +# 设置子弹框 |
| 43 | +bullet_rect = pygame.Rect(1004, 987, 9, 21) |
| 44 | +# 加载子弹图片 |
| 45 | +bullet_img = img_plane.subsurface(bullet_rect) |
| 46 | +# 设置敌人框 |
| 47 | +enemy_rect = pygame.Rect(534, 612, 57, 43) |
| 48 | +# 设置敌人图片 |
| 49 | +enemy_img = img_plane.subsurface(enemy_rect) |
| 50 | +# 设置敌人被击图片 |
| 51 | +enemy_explosion_imgs = [] |
| 52 | +enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(267, 347, 57, 43))) |
| 53 | +enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(873, 697, 57, 43))) |
| 54 | +enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(267, 296, 57, 43))) |
| 55 | +enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(930, 697, 57, 43))) |
| 56 | +# 设置敌机精灵组 |
| 57 | +enemies = pygame.sprite.Group() |
| 58 | +# 设置敌机被击精灵组 |
| 59 | +enemies_explosion = pygame.sprite.Group() |
| 60 | +# 设置射击频率 |
| 61 | +shoot_frequency = 0 |
| 62 | +# 设置敌机频率 |
| 63 | +enemy_frequency = 0 |
| 64 | +# 设置玩家被击的图片顺序 |
| 65 | +player_explosion_index = 16 |
| 66 | +score = 0 |
| 67 | +running = True |
| 68 | +is_pause = False |
| 69 | +is_game_over = False |
| 70 | +clock = pygame.time.Clock() |
| 71 | + |
| 72 | +# 开始游戏循环 |
| 73 | +while running: |
| 74 | + # 设置游戏帧率为 60 |
| 75 | + clock.tick(60) |
| 76 | + if not is_pause and not is_game_over: |
| 77 | + if not player.is_hit: |
| 78 | + # 设置连续射击,因为每秒 60 帧,15/60=0.25 秒发一次子弹 |
| 79 | + if shoot_frequency % 15 == 0: |
| 80 | + player.shoot(bullet_img) |
| 81 | + shoot_frequency += 1 |
| 82 | + # 当设置的射击频率大于 15,置零 |
| 83 | + if shoot_frequency >= 15: |
| 84 | + shoot_frequency = 0 |
| 85 | + # 控制生成敌机的频率 |
| 86 | + if enemy_frequency % 50 == 0: |
| 87 | + # 设置敌机的出现的位置 |
| 88 | + enemy_pos = [random.randint(0, SCREEN_WIDTH - enemy_rect.width), 0] |
| 89 | + enemy = Enemy(enemy_img, enemy_explosion_imgs, enemy_pos) |
| 90 | + enemies.add(enemy) |
| 91 | + enemy_frequency += 1 |
| 92 | + if enemy_frequency >= 100: |
| 93 | + enemy_frequency = 0 |
| 94 | + # 控制子弹的显示运行 |
| 95 | + for bullet in player.bullets: |
| 96 | + bullet.move() |
| 97 | + if bullet.rect.bottom < 0: |
| 98 | + player.bullets.remove(bullet) |
| 99 | + # 控制敌机的运行 |
| 100 | + for enemy in enemies: |
| 101 | + enemy.move() |
| 102 | + # 判断敌机是否与玩家飞机碰撞 |
| 103 | + if pygame.sprite.collide_circle(enemy, player): |
| 104 | + enemies_explosion.add(enemy) |
| 105 | + enemies.remove(enemy) |
| 106 | + player.is_hit = True |
| 107 | + # 设置玩家的飞机被毁 |
| 108 | + is_game_over = True |
| 109 | + # 判断敌机是否在界面 |
| 110 | + if enemy.rect.top < 0: |
| 111 | + enemies.remove(enemy) |
| 112 | + # 设置敌机与玩家的飞机子弹相碰时,返回被击的敌机实例 |
| 113 | + enemy_explosion = pygame.sprite.groupcollide(enemies, player.bullets, 1, 1) |
| 114 | + for enemy in enemy_explosion: |
| 115 | + enemies_explosion.add(enemy) |
| 116 | + # 绘制屏幕 |
| 117 | + screen.fill(0) |
| 118 | + # 加入背景图片 |
| 119 | + screen.blit(bg, (0, 0)) |
| 120 | + # 添加玩家飞机图片到屏幕 |
| 121 | + if not player.is_hit: |
| 122 | + screen.blit(player.image[int(player.img_index)], player.rect) |
| 123 | + player.img_index = shoot_frequency / 8 |
| 124 | + else: |
| 125 | + if player_explosion_index > 47: |
| 126 | + is_game_over = True |
| 127 | + else: |
| 128 | + player.img_index = player_explosion_index / 8 |
| 129 | + screen.blit(player.image[int(player.img_index)], player.rect) |
| 130 | + player_explosion_index += 1 |
| 131 | + # 敌机被子弹击中的效果显示 |
| 132 | + for enemy in enemies_explosion: |
| 133 | + if enemy.explosion_index == 0: |
| 134 | + pass |
| 135 | + if enemy.explosion_index > 7: |
| 136 | + enemies_explosion.remove(enemy) |
| 137 | + score += 100 |
| 138 | + continue |
| 139 | + # 敌机被击时显示图片 |
| 140 | + screen.blit(enemy.explosion_img[int(enemy.explosion_index / 2)], enemy.rect) |
| 141 | + enemy.explosion_index += 1 |
| 142 | + # 显示子弹 |
| 143 | + player.bullets.draw(screen) |
| 144 | + # 显示敌机 |
| 145 | + enemies.draw(screen) |
| 146 | + # 分数的显示效果 |
| 147 | + score_font = pygame.font.Font(None, 36) |
| 148 | + score_text = score_font.render(str(score), True, (128, 128, 128)) |
| 149 | + # 设置文字框 |
| 150 | + text_rect = score_text.get_rect() |
| 151 | + # 放置文字的位置 |
| 152 | + text_rect.topleft = [20, 10] |
| 153 | + # 显示出分数 |
| 154 | + screen.blit(score_text, text_rect) |
| 155 | + left, middle, right = pygame.mouse.get_pressed() |
| 156 | + # 暂停游戏 |
| 157 | + if right == True and not is_game_over: |
| 158 | + is_pause = True |
| 159 | + if left == True: |
| 160 | + # 重置游戏 |
| 161 | + if is_game_over: |
| 162 | + is_game_over = False |
| 163 | + player_rect = [] |
| 164 | + player_rect.append(pygame.Rect(0, 99, 102, 126)) |
| 165 | + player_rect.append(pygame.Rect(165, 360, 102, 126)) |
| 166 | + player_rect.append(pygame.Rect(165, 234, 102, 126)) |
| 167 | + player_rect.append(pygame.Rect(330, 624, 102, 126)) |
| 168 | + player_rect.append(pygame.Rect(330, 498, 102, 126)) |
| 169 | + player_rect.append(pygame.Rect(432, 624, 102, 126)) |
| 170 | + player = Player(img_plane, player_rect, player_pos) |
| 171 | + bullet_rect = pygame.Rect(1004, 987, 9, 21) |
| 172 | + bullet_img = img_plane.subsurface(bullet_rect) |
| 173 | + enemy_rect = pygame.Rect(534, 612, 57, 43) |
| 174 | + enemy_img = img_plane.subsurface(enemy_rect) |
| 175 | + enemy_explosion_imgs = [] |
| 176 | + enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(267, 347, 57, 43))) |
| 177 | + enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(873, 697, 57, 43))) |
| 178 | + enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(267, 296, 57, 43))) |
| 179 | + enemy_explosion_imgs.append(img_plane.subsurface(pygame.Rect(930, 697, 57, 43))) |
| 180 | + enemies = pygame.sprite.Group() |
| 181 | + enemies_explosion = pygame.sprite.Group() |
| 182 | + score = 0 |
| 183 | + shoot_frequency = 0 |
| 184 | + enemy_frequency = 0 |
| 185 | + player_explosion_index = 16 |
| 186 | + # 继续游戏 |
| 187 | + if is_pause: |
| 188 | + is_pause = False |
| 189 | + # 游戏结束 |
| 190 | + if is_game_over: |
| 191 | + font = pygame.font.SysFont("微软雅黑", 48) |
| 192 | + text = font.render("Score: " + str(score), True, (255, 0, 0)) |
| 193 | + text_rect = text.get_rect() |
| 194 | + text_rect.centerx = screen.get_rect().centerx |
| 195 | + text_rect.centery = screen.get_rect().centery + 70 |
| 196 | + # 显示游戏结束画面 |
| 197 | + screen.blit(bg_game_over, (0, 0)) |
| 198 | + # 显示分数 |
| 199 | + screen.blit(text, text_rect) |
| 200 | + font = pygame.font.SysFont("微软雅黑", 40) |
| 201 | + text = font.render("Press Left Mouse to Restart", True, (255, 0, 0)) |
| 202 | + text_rect = text.get_rect() |
| 203 | + text_rect.centerx = screen.get_rect().centerx |
| 204 | + text_rect.centery = screen.get_rect().centery + 150 |
| 205 | + screen.blit(text, text_rect) |
| 206 | + # 刷新屏幕 |
| 207 | + pygame.display.update() |
| 208 | + # 处理游戏退出 |
| 209 | + for event in pygame.event.get(): |
| 210 | + if event.type == pygame.QUIT: |
| 211 | + pygame.quit() |
| 212 | + exit() |
| 213 | + if not is_pause and not is_game_over: |
| 214 | + key = pygame.key.get_pressed() |
| 215 | + if key[K_w] or key[K_UP]: |
| 216 | + player.moveUp() |
| 217 | + if key[K_s] or key[K_DOWN]: |
| 218 | + player.moveDown() |
| 219 | + if key[K_a] or key[K_LEFT]: |
| 220 | + player.moveLeft() |
| 221 | + if key[K_d] or key[K_RIGHT]: |
| 222 | + player.moveRight() |
| 223 | + |
| 224 | +while 1: |
| 225 | + for event in pygame.event.get(): |
| 226 | + if event.type == pygame.QUIT: |
| 227 | + pygame.quit() |
| 228 | + exit() |
| 229 | + # 刷新屏幕 |
| 230 | + pygame.display.update() |
0 commit comments