Python代码实现飞机大战(经典)
參考資料
- 《零基礎入門學習python》
源代碼以及素材資料(圖片,音頻)可從下面的github中下載:
- 飛機大戰源代碼以及素材資料github項目地址鏈接
—————————————————————————————————————————————————————
文章目錄
- 經典飛機大戰
- 一.游戲設定
- 二.我方飛機
- 三.敵方飛機
- 四.發射子彈
- 五.發放補給包
- 六.主模塊
?
經典飛機大戰
不知道大家有沒有打過飛機,喜不喜歡打飛機。當我第一次接觸這個東西的時候,我的內心是被震撼到的。第一次接觸打飛機的時候作者本人是身心愉悅的,因為周邊的朋友都在打飛機, 每次都會下意識彼此較量一下,看誰打得更好。打飛機也是需要有一定的技巧的,熟練的朋友一把能打上半個小時,生疏的則三五分鐘就敗下陣來。
一.游戲設定
游戲界面如下圖所示
游戲的基本設定:
- 敵方共有大中小3款飛機,分為高中低三種速度;
- 子彈的射程并非全屏,而大概是屏幕長度的80%;
- 消滅小飛機需要1發子彈,中飛機需要8發,大飛機需要20發子彈;
- 每消滅一架小飛機得1000分,中飛機6000分,大飛機10000分;
- 每隔30秒有一個隨機的道具補給,分為兩種道具,全屏炸彈和雙倍子彈;
- 全屏炸彈最多只能存放3枚,雙倍子彈可以維持18秒鐘的效果;
- 游戲將根據分數來逐步提高難度,難度的提高表現為飛機數量的增多以及速度的加快。
另外還對游戲做了一些改進,比如為中飛機和大飛機增加了血槽的顯示,這樣玩家可以直觀地知道敵機快被消滅了沒有;我方有三次機會,每次被敵人消滅,新誕生的飛機會有3秒鐘的安全期;游戲結束后會顯示歷史最高分數。
這個游戲加上基本的注釋代碼量在800行左右,代碼看上去比較多,多打代碼少動腦。所以大家不要怕,越是多的代碼,邏輯就越容易看得清楚,就越好學習。好,那讓我們從無到有,從簡單到復雜來一起打造這個游戲吧!
?
二.我方飛機
首先創建一個myplane. py模塊來定義我方飛機:
import pygameclass MyPlane(pygame.sprite.Sprite):def __init__(self, bg_size):pygame.sprite.Sprite.__init__(self)self.image1 = pygame.image.load("images/me1.png").convert_alpha()self.image2 = pygame.image.load("images/me2.png").convert_alpha()self.destroy_images = []self.destroy_images.extend([\pygame.image.load("images/me_destroy_1.png").convert_alpha(), \pygame.image.load("images/me_destroy_2.png").convert_alpha(), \pygame.image.load("images/me_destroy_3.png").convert_alpha(), \pygame.image.load("images/me_destroy_4.png").convert_alpha() \])self.rect = self.image1.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.rect.left, self.rect.top = \(self.width - self.rect.width) // 2, \self.height - self.rect.height - 60self.speed = 10self.active = Trueself.invincible = Falseself.mask = pygame.mask.from_surface(self.image1)# 分別定義moveUp()、moveDown()、moveLeft()和moveRight()控制我方飛機上、下、左、右移動:def moveUp(self):if self.rect.top > 0:self.rect.top -= self.speedelse:self.rect.top = 0def moveDown(self):if self.rect.bottom < self.height - 60:self.rect.top += self.speedelse:self.rect.bottom = self.height - 60def moveLeft(self):if self.rect.left > 0:self.rect.left -= self.speedelse:self.rect.left = 0def moveRight(self):if self.rect.right < self.width:self.rect.left += self.speedelse:self.rect.right = self.widthdef reset(self):self.rect.left, self.rect.top = \(self.width - self.rect.width) // 2, \self.height - self.rect.height - 60self.active = Trueself.invincible = True- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
三.敵方飛機
既然英雄已經有了,那現在就是需要創造敵人的時候。敵機分為小、中、大三個尺寸,它們的速度依次是快、中、慢,在游戲界面的上方位置創造位置隨機的敵機,可以讓它們不在同一排出現。將敵機的定義寫在enemy. py模塊中:
import pygame from random import *class SmallEnemy(pygame.sprite.Sprite):def __init__(self, bg_size):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("images/enemy1.png").convert_alpha()self.destroy_images = []self.destroy_images.extend([ \pygame.image.load("images/enemy1_down1.png").convert_alpha(), \pygame.image.load("images/enemy1_down2.png").convert_alpha(), \pygame.image.load("images/enemy1_down3.png").convert_alpha(), \pygame.image.load("images/enemy1_down4.png").convert_alpha() \])self.rect = self.image.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.speed = 2self.active = Trueself.rect.left, self.rect.top = \randint(0, self.width - self.rect.width), \randint(-5 * self.height, 0)self.mask = pygame.mask.from_surface(self.image)def move(self):if self.rect.top < self.height:self.rect.top += self.speedelse:self.reset()def reset(self):self.active = Trueself.rect.left, self.rect.top = \randint(0, self.width - self.rect.width), \randint(-5 * self.height, 0)class MidEnemy(pygame.sprite.Sprite):energy = 8def __init__(self, bg_size):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("images/enemy2.png").convert_alpha()self.image_hit = pygame.image.load("images/enemy2_hit.png").convert_alpha()self.destroy_images = []self.destroy_images.extend([ \pygame.image.load("images/enemy2_down1.png").convert_alpha(), \pygame.image.load("images/enemy2_down2.png").convert_alpha(), \pygame.image.load("images/enemy2_down3.png").convert_alpha(), \pygame.image.load("images/enemy2_down4.png").convert_alpha() \])self.rect = self.image.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.speed = 1self.active = Trueself.rect.left, self.rect.top = \randint(0, self.width - self.rect.width), \randint(-10 * self.height, -self.height)self.mask = pygame.mask.from_surface(self.image)self.energy = MidEnemy.energyself.hit = Falsedef move(self):if self.rect.top < self.height:self.rect.top += self.speedelse:self.reset()def reset(self):self.active = Trueself.energy = MidEnemy.energyself.rect.left, self.rect.top = \randint(0, self.width - self.rect.width), \randint(-10 * self.height, -self.height)class BigEnemy(pygame.sprite.Sprite):energy = 20def __init__(self, bg_size):pygame.sprite.Sprite.__init__(self)self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()self.image_hit = pygame.image.load("images/enemy3_hit.png").convert_alpha()self.destroy_images = []self.destroy_images.extend([ \pygame.image.load("images/enemy3_down1.png").convert_alpha(), \pygame.image.load("images/enemy3_down2.png").convert_alpha(), \pygame.image.load("images/enemy3_down3.png").convert_alpha(), \pygame.image.load("images/enemy3_down4.png").convert_alpha(), \pygame.image.load("images/enemy3_down5.png").convert_alpha(), \pygame.image.load("images/enemy3_down6.png").convert_alpha() \])self.rect = self.image1.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.speed = 1self.active = Trueself.rect.left, self.rect.top = \randint(0, self.width - self.rect.width), \randint(-15 * self.height, -5 * self.height)self.mask = pygame.mask.from_surface(self.image1)self.energy = BigEnemy.energyself.hit = Falsedef move(self):if self.rect.top < self.height:self.rect.top += self.speedelse:self.reset()def reset(self):self.active = Trueself.energy = BigEnemy.energyself.rect.left, self.rect.top = \randint(0, self.width - self.rect.width), \randint(-15 * self.height, -5 * self.height)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
四.發射子彈
現在的情況是我方飛機處于落后挨打的狀態,敵強我弱,所以應該拿起武器進行反擊! 接下來定義子彈,子彈分為兩種: 一種是普通子彈一次只發射一顆; 另一種是補給發放的超級子彈一次可以發射兩顆。
我們將子彈定義為獨立的模塊bullet.py:
import pygameclass Bullet1(pygame.sprite.Sprite):def __init__(self, position):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("images/bullet1.png").convert_alpha()self.rect = self.image.get_rect()self.rect.left, self.rect.top = positionself.speed = 12self.active = Falseself.mask = pygame.mask.from_surface(self.image)def move(self):self.rect.top -= self.speedif self.rect.top < 0:self.active = Falsedef reset(self, position):self.rect.left, self.rect.top = positionself.active = Trueclass Bullet2(pygame.sprite.Sprite):def __init__(self, position):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("images/bullet2.png").convert_alpha()self.rect = self.image.get_rect()self.rect.left, self.rect.top = positionself.speed = 14self.active = Falseself.mask = pygame.mask.from_surface(self.image)def move(self):self.rect.top -= self.speedif self.rect.top < 0:self.active = Falsedef reset(self, position):self.rect.left, self.rect.top = positionself.active = True- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
五.發放補給包
游戲設計每30秒隨機發放一個補給包,可 能是超級子彈,也可能是全屏炸彈。補給包有自己的圖像和運動軌跡,不妨單獨為其定義一個模塊supply.py:
import pygame from random import *class Bullet_Supply(pygame.sprite.Sprite):def __init__(self, bg_size):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("images/bullet_supply.png").convert_alpha()self.rect = self.image.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.rect.left, self.rect.bottom = \randint(0, self.width - self.rect.width), -100self.speed = 5self.active = Falseself.mask = pygame.mask.from_surface(self.image)def move(self):if self.rect.top < self.height:self.rect.top += self.speedelse:self.active = Falsedef reset(self):self.active = Trueself.rect.left, self.rect.bottom = \randint(0, self.width - self.rect.width), -100class Bomb_Supply(pygame.sprite.Sprite):def __init__(self, bg_size):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("images/bomb_supply.png").convert_alpha()self.rect = self.image.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.rect.left, self.rect.bottom = \randint(0, self.width - self.rect.width), -100self.speed = 5self.active = Falseself.mask = pygame.mask.from_surface(self.image)def move(self):if self.rect.top < self.height:self.rect.top += self.speedelse:self.active = Falsedef reset(self):self.active = Trueself.rect.left, self.rect.bottom = \randint(0, self.width - self.rect.width), -100- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
六.主模塊
所有的模塊都到齊了,接下來就該實現我們的主模塊了
# main.py import pygame import sys import traceback import myplane import enemy import bullet import supplyfrom pygame.locals import * from random import *pygame.init() pygame.mixer.init()bg_size = width, height = 480, 700 screen = pygame.display.set_mode(bg_size) pygame.display.set_caption("飛機大戰 -- FishC Demo")background = pygame.image.load("images/background.png").convert()BLACK = (0, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) RED = (255, 0, 0)# 載入游戲音樂 pygame.mixer.music.load("sound/game_music.ogg") pygame.mixer.music.set_volume(0.2) bullet_sound = pygame.mixer.Sound("sound/bullet.wav") bullet_sound.set_volume(0.2) bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav") bomb_sound.set_volume(0.2) supply_sound = pygame.mixer.Sound("sound/supply.wav") supply_sound.set_volume(0.2) get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav") get_bomb_sound.set_volume(0.2) get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav") get_bullet_sound.set_volume(0.2) upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav") upgrade_sound.set_volume(0.2) enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav") enemy3_fly_sound.set_volume(0.2) enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav") enemy1_down_sound.set_volume(0.2) enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav") enemy2_down_sound.set_volume(0.2) enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav") enemy3_down_sound.set_volume(0.5) me_down_sound = pygame.mixer.Sound("sound/me_down.wav") me_down_sound.set_volume(0.2)def add_small_enemies(group1, group2, num):for i in range(num):e1 = enemy.SmallEnemy(bg_size)group1.add(e1)group2.add(e1)def add_mid_enemies(group1, group2, num):for i in range(num):e2 = enemy.MidEnemy(bg_size)group1.add(e2)group2.add(e2)def add_big_enemies(group1, group2, num):for i in range(num):e3 = enemy.BigEnemy(bg_size)group1.add(e3)group2.add(e3)def inc_speed(target, inc):for each in target:each.speed += incdef main():pygame.mixer.music.play(-1)# 生成我方飛機me = myplane.MyPlane(bg_size)enemies = pygame.sprite.Group()# 生成敵方小型飛機small_enemies = pygame.sprite.Group()add_small_enemies(small_enemies, enemies, 15)# 生成敵方中型飛機mid_enemies = pygame.sprite.Group()add_mid_enemies(mid_enemies, enemies, 4)# 生成敵方大型飛機big_enemies = pygame.sprite.Group()add_big_enemies(big_enemies, enemies, 2)# 生成普通子彈bullet1 = []bullet1_index = 0BULLET1_NUM = 4for i in range(BULLET1_NUM):bullet1.append(bullet.Bullet1(me.rect.midtop))# 生成超級子彈bullet2 = []bullet2_index = 0BULLET2_NUM = 8for i in range(BULLET2_NUM // 2):bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery)))bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))clock = pygame.time.Clock()# 中彈圖片索引e1_destroy_index = 0e2_destroy_index = 0e3_destroy_index = 0me_destroy_index = 0# 統計得分score = 0score_font = pygame.font.Font("font/font.ttf", 36)# 標志是否暫停游戲paused = Falsepause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()paused_rect = pause_nor_image.get_rect()paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10paused_image = pause_nor_image# 設置難度級別level = 1# 全屏炸彈bomb_image = pygame.image.load("images/bomb.png").convert_alpha()bomb_rect = bomb_image.get_rect()bomb_font = pygame.font.Font("font/font.ttf", 48)bomb_num = 3# 每30秒發放一個補給包bullet_supply = supply.Bullet_Supply(bg_size)bomb_supply = supply.Bomb_Supply(bg_size)SUPPLY_TIME = USEREVENTpygame.time.set_timer(SUPPLY_TIME, 30 * 1000)# 超級子彈定時器DOUBLE_BULLET_TIME = USEREVENT + 1# 標志是否使用超級子彈is_double_bullet = False# 解除我方無敵狀態定時器INVINCIBLE_TIME = USEREVENT + 2# 生命數量life_image = pygame.image.load("images/life.png").convert_alpha()life_rect = life_image.get_rect()life_num = 3# 用于阻止重復打開記錄文件recorded = False# 游戲結束畫面gameover_font = pygame.font.Font("font/font.TTF", 48)again_image = pygame.image.load("images/again.png").convert_alpha()again_rect = again_image.get_rect()gameover_image = pygame.image.load("images/gameover.png").convert_alpha()gameover_rect = gameover_image.get_rect()# 用于切換圖片switch_image = True# 用于延遲delay = 100running = Truewhile running:for event in pygame.event.get():if event.type == QUIT:pygame.quit()sys.exit()elif event.type == MOUSEBUTTONDOWN:if event.button == 1 and paused_rect.collidepoint(event.pos):paused = not pausedif paused:pygame.time.set_timer(SUPPLY_TIME, 0)pygame.mixer.music.pause()pygame.mixer.pause()else:pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)pygame.mixer.music.unpause()pygame.mixer.unpause()elif event.type == MOUSEMOTION:if paused_rect.collidepoint(event.pos):if paused:paused_image = resume_pressed_imageelse:paused_image = pause_pressed_imageelse:if paused:paused_image = resume_nor_imageelse:paused_image = pause_nor_imageelif event.type == KEYDOWN:if event.key == K_SPACE:if bomb_num:bomb_num -= 1bomb_sound.play()for each in enemies:if each.rect.bottom > 0:each.active = Falseelif event.type == SUPPLY_TIME:supply_sound.play()if choice([True, False]):bomb_supply.reset()else:bullet_supply.reset()elif event.type == DOUBLE_BULLET_TIME:is_double_bullet = Falsepygame.time.set_timer(DOUBLE_BULLET_TIME, 0)elif event.type == INVINCIBLE_TIME:me.invincible = Falsepygame.time.set_timer(INVINCIBLE_TIME, 0)# 根據用戶的得分增加難度if level == 1 and score > 50000:level = 2upgrade_sound.play()# 增加3架小型敵機、2架中型敵機和1架大型敵機add_small_enemies(small_enemies, enemies, 3)add_mid_enemies(mid_enemies, enemies, 2)add_big_enemies(big_enemies, enemies, 1)# 提升小型敵機的速度inc_speed(small_enemies, 1)elif level == 2 and score > 300000:level = 3upgrade_sound.play()# 增加5架小型敵機、3架中型敵機和2架大型敵機add_small_enemies(small_enemies, enemies, 5)add_mid_enemies(mid_enemies, enemies, 3)add_big_enemies(big_enemies, enemies, 2)# 提升小型敵機的速度inc_speed(small_enemies, 1)inc_speed(mid_enemies, 1)elif level == 3 and score > 600000:level = 4upgrade_sound.play()# 增加5架小型敵機、3架中型敵機和2架大型敵機add_small_enemies(small_enemies, enemies, 5)add_mid_enemies(mid_enemies, enemies, 3)add_big_enemies(big_enemies, enemies, 2)# 提升小型敵機的速度inc_speed(small_enemies, 1)inc_speed(mid_enemies, 1)elif level == 4 and score > 1000000:level = 5upgrade_sound.play()# 增加5架小型敵機、3架中型敵機和2架大型敵機add_small_enemies(small_enemies, enemies, 5)add_mid_enemies(mid_enemies, enemies, 3)add_big_enemies(big_enemies, enemies, 2)# 提升小型敵機的速度inc_speed(small_enemies, 1)inc_speed(mid_enemies, 1)screen.blit(background, (0, 0))if life_num and not paused:# 檢測用戶的鍵盤操作key_pressed = pygame.key.get_pressed()if key_pressed[K_w] or key_pressed[K_UP]:me.moveUp()if key_pressed[K_s] or key_pressed[K_DOWN]:me.moveDown()if key_pressed[K_a] or key_pressed[K_LEFT]:me.moveLeft()if key_pressed[K_d] or key_pressed[K_RIGHT]:me.moveRight()# 繪制全屏炸彈補給并檢測是否獲得if bomb_supply.active:bomb_supply.move()screen.blit(bomb_supply.image, bomb_supply.rect)if pygame.sprite.collide_mask(bomb_supply, me):get_bomb_sound.play()if bomb_num < 3:bomb_num += 1bomb_supply.active = False# 繪制超級子彈補給并檢測是否獲得if bullet_supply.active:bullet_supply.move()screen.blit(bullet_supply.image, bullet_supply.rect)if pygame.sprite.collide_mask(bullet_supply, me):get_bullet_sound.play()is_double_bullet = Truepygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)bullet_supply.active = False# 發射子彈if not (delay % 10):bullet_sound.play()if is_double_bullet:bullets = bullet2bullets[bullet2_index].reset((me.rect.centerx - 33, me.rect.centery))bullets[bullet2_index + 1].reset((me.rect.centerx + 30, me.rect.centery))bullet2_index = (bullet2_index + 2) % BULLET2_NUMelse:bullets = bullet1bullets[bullet1_index].reset(me.rect.midtop)bullet1_index = (bullet1_index + 1) % BULLET1_NUM# 檢測子彈是否擊中敵機for b in bullets:if b.active:b.move()screen.blit(b.image, b.rect)enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)if enemy_hit:b.active = Falsefor e in enemy_hit:if e in mid_enemies or e in big_enemies:e.hit = Truee.energy -= 1if e.energy == 0:e.active = Falseelse:e.active = False# 繪制大型敵機for each in big_enemies:if each.active:each.move()if each.hit:screen.blit(each.image_hit, each.rect)each.hit = Falseelse:if switch_image:screen.blit(each.image1, each.rect)else:screen.blit(each.image2, each.rect)# 繪制血槽pygame.draw.line(screen, BLACK, \(each.rect.left, each.rect.top - 5), \(each.rect.right, each.rect.top - 5), \2)# 當生命大于20%顯示綠色,否則顯示紅色energy_remain = each.energy / enemy.BigEnemy.energyif energy_remain > 0.2:energy_color = GREENelse:energy_color = REDpygame.draw.line(screen, energy_color, \(each.rect.left, each.rect.top - 5), \(each.rect.left + each.rect.width * energy_remain, \each.rect.top - 5), 2)# 即將出現在畫面中,播放音效if each.rect.bottom == -50:enemy3_fly_sound.play(-1)else:# 毀滅if not (delay % 3):if e3_destroy_index == 0:enemy3_down_sound.play()screen.blit(each.destroy_images[e3_destroy_index], each.rect)e3_destroy_index = (e3_destroy_index + 1) % 6if e3_destroy_index == 0:enemy3_fly_sound.stop()score += 10000each.reset()# 繪制中型敵機:for each in mid_enemies:if each.active:each.move()if each.hit:screen.blit(each.image_hit, each.rect)each.hit = Falseelse:screen.blit(each.image, each.rect)# 繪制血槽pygame.draw.line(screen, BLACK, \(each.rect.left, each.rect.top - 5), \(each.rect.right, each.rect.top - 5), \2)# 當生命大于20%顯示綠色,否則顯示紅色energy_remain = each.energy / enemy.MidEnemy.energyif energy_remain > 0.2:energy_color = GREENelse:energy_color = REDpygame.draw.line(screen, energy_color, \(each.rect.left, each.rect.top - 5), \(each.rect.left + each.rect.width * energy_remain, \each.rect.top - 5), 2)else:# 毀滅if not (delay % 3):if e2_destroy_index == 0:enemy2_down_sound.play()screen.blit(each.destroy_images[e2_destroy_index], each.rect)e2_destroy_index = (e2_destroy_index + 1) % 4if e2_destroy_index == 0:score += 6000each.reset()# 繪制小型敵機:for each in small_enemies:if each.active:each.move()screen.blit(each.image, each.rect)else:# 毀滅if not (delay % 3):if e1_destroy_index == 0:enemy1_down_sound.play()screen.blit(each.destroy_images[e1_destroy_index], each.rect)e1_destroy_index = (e1_destroy_index + 1) % 4if e1_destroy_index == 0:score += 1000each.reset()# 檢測我方飛機是否被撞enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)if enemies_down and not me.invincible:me.active = Falsefor e in enemies_down:e.active = False# 繪制我方飛機if me.active:if switch_image:screen.blit(me.image1, me.rect)else:screen.blit(me.image2, me.rect)else:# 毀滅if not (delay % 3):if me_destroy_index == 0:me_down_sound.play()screen.blit(me.destroy_images[me_destroy_index], me.rect)me_destroy_index = (me_destroy_index + 1) % 4if me_destroy_index == 0:life_num -= 1me.reset()pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)# 繪制全屏炸彈數量bomb_text = bomb_font.render("× %d" % bomb_num, True, WHITE)text_rect = bomb_text.get_rect()screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))# 繪制剩余生命數量if life_num:for i in range(life_num):screen.blit(life_image, \(width - 10 - (i + 1) * life_rect.width, \height - 10 - life_rect.height))# 繪制得分score_text = score_font.render("Score : %s" % str(score), True, WHITE)screen.blit(score_text, (10, 5))# 繪制游戲結束畫面elif life_num == 0:# 背景音樂停止pygame.mixer.music.stop()# 停止全部音效pygame.mixer.stop()# 停止發放補給pygame.time.set_timer(SUPPLY_TIME, 0)if not recorded:recorded = True# 讀取歷史最高得分with open("record.txt", "r") as f:record_score = int(f.read())# 如果玩家得分高于歷史最高得分,則存檔if score > record_score:with open("record.txt", "w") as f:f.write(str(score))# 繪制結束畫面record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255))screen.blit(record_score_text, (50, 50))gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))gameover_text1_rect = gameover_text1.get_rect()gameover_text1_rect.left, gameover_text1_rect.top = \(width - gameover_text1_rect.width) // 2, height // 3screen.blit(gameover_text1, gameover_text1_rect)gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))gameover_text2_rect = gameover_text2.get_rect()gameover_text2_rect.left, gameover_text2_rect.top = \(width - gameover_text2_rect.width) // 2, \gameover_text1_rect.bottom + 10screen.blit(gameover_text2, gameover_text2_rect)again_rect.left, again_rect.top = \(width - again_rect.width) // 2, \gameover_text2_rect.bottom + 50screen.blit(again_image, again_rect)gameover_rect.left, gameover_rect.top = \(width - again_rect.width) // 2, \again_rect.bottom + 10screen.blit(gameover_image, gameover_rect)# 檢測用戶的鼠標操作# 如果用戶按下鼠標左鍵if pygame.mouse.get_pressed()[0]:# 獲取鼠標坐標pos = pygame.mouse.get_pos()# 如果用戶點擊“重新開始”if again_rect.left < pos[0] < again_rect.right and \again_rect.top < pos[1] < again_rect.bottom:# 調用main函數,重新開始游戲main()# 如果用戶點擊“結束游戲”elif gameover_rect.left < pos[0] < gameover_rect.right and \gameover_rect.top < pos[1] < gameover_rect.bottom:# 退出游戲pygame.quit()sys.exit()# 繪制暫停按鈕screen.blit(paused_image, paused_rect)# 切換圖片if not (delay % 5):switch_image = not switch_imagedelay -= 1if not delay:delay = 100pygame.display.flip()clock.tick(60)if __name__ == "__main__":try:main()except SystemExit:passexcept:traceback.print_exc()pygame.quit()input()- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
切記:?所有的模塊應該放在同一個文件夾下
最后運行我們的主模塊就大功告成了!
下面是運行結果:
來源:https://blog.csdn.net/qq_43328040/article/details/106853332#_15
總結
以上是生活随笔為你收集整理的Python代码实现飞机大战(经典)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科兴中维属于哪家上市公司
- 下一篇: 影响20号胶价格的因素有很多,这些因素需