小甲魚python-pygame-3 飛機大戰遊戲
1.載入基礎環境(背景音樂、音效、圖片)
# -*- coding: utf-8 -*-n# main.pynimport pygamenimport sysnimport tracebacknfrom pygame.locals import *nfrom random import *nn# import myplanen# import bulletn# import enemyn# import supplynnpygame.init()npygame.mixer.init()nnbg_size = width, height = 480, 700nscreen = pygame.display.set_mode(bg_size)npygame.display.set_caption("飛機大戰 -- FishC Demo")nnbackground = pygame.image.load("images/background.png").convert()nn# 載入遊戲音樂npygame.mixer.music.load("sound/game_music.ogg")npygame.mixer.music.set_volume(0.2)nbullet_sound = pygame.mixer.Sound("sound/bullet.wav")nbullet_sound.set_volume(0.2)nbomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")nbomb_sound.set_volume(0.2)nsupply_sound = pygame.mixer.Sound("sound/supply.wav")nsupply_sound.set_volume(0.2)nget_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")nget_bomb_sound.set_volume(0.2)nget_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")nget_bullet_sound.set_volume(0.2)nupgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")nupgrade_sound.set_volume(0.2)nenemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")nenemy3_fly_sound.set_volume(0.2)nenemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")nenemy1_down_sound.set_volume(0.1)nenemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")nenemy2_down_sound.set_volume(0.2)nenemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")nenemy3_down_sound.set_volume(0.5)nme_down_sound = pygame.mixer.Sound("sound/me_down.wav")nme_down_sound.set_volume(0.2)nndef main():n pygame.mixer.music.play(-1)nn clock = pygame.time.Clock()nn running = Truenn while running:n for event in pygame.event.get():n if event.type == QUIT:n pygame.quit()n sys.exit()nn screen.blit(background, (0, 0))nn pygame.display.flip()n clock.tick(60)n nif __name__ == "__main__":n try:n main()n except SystemExit:n passn except:n traceback.print_exc()n pygame.quit()n input()n
2.增加敵機和我機的模塊,並加入到場景
主模塊
# -*- coding: utf-8 -*-n# main.pynimport pygamenimport sysnimport tracebacknimport myplanenimport enemynnfrom pygame.locals import *nfrom random import *nnpygame.init()npygame.mixer.init()nnbg_size = width, height = 480, 700nscreen = pygame.display.set_mode(bg_size)npygame.display.set_caption("飛機大戰 -- FishC Demo")nnbackground = pygame.image.load("images/background.png").convert()nn# 載入遊戲音樂npygame.mixer.music.load("sound/game_music.ogg")npygame.mixer.music.set_volume(0.2)nbullet_sound = pygame.mixer.Sound("sound/bullet.wav")nbullet_sound.set_volume(0.2)nbomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")nbomb_sound.set_volume(0.2)nsupply_sound = pygame.mixer.Sound("sound/supply.wav")nsupply_sound.set_volume(0.2)nget_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")nget_bomb_sound.set_volume(0.2)nget_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")nget_bullet_sound.set_volume(0.2)nupgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")nupgrade_sound.set_volume(0.2)nenemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")nenemy3_fly_sound.set_volume(0.2)nenemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")nenemy1_down_sound.set_volume(0.1)nenemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")nenemy2_down_sound.set_volume(0.2)nenemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")nenemy3_down_sound.set_volume(0.5)nme_down_sound = pygame.mixer.Sound("sound/me_down.wav")nme_down_sound.set_volume(0.2)nnndef add_small_enemies(group1, group2, num):n for i in range(num):n e1 = enemy.SmallEnemy(bg_size)n group1.add(e1)n group2.add(e1)nndef add_mid_enemies(group1, group2, num):n for i in range(num):n e2 = enemy.MidEnemy(bg_size)n group1.add(e2)n group2.add(e2)nndef add_big_enemies(group1, group2, num):n for i in range(num):n e3 = enemy.BigEnemy(bg_size)n group1.add(e3)n group2.add(e3)n nndef main():n pygame.mixer.music.play(-1)nn # 生成我方飛機n me = myplane.MyPlane(bg_size)nn enemies = pygame.sprite.Group()nn # 生成敵方小型飛機n small_enemies = pygame.sprite.Group()n add_small_enemies(small_enemies, enemies, 15)nn # 生成敵方中型飛機n mid_enemies = pygame.sprite.Group()n add_mid_enemies(mid_enemies, enemies, 4)nn # 生成敵方大型飛機n big_enemies = pygame.sprite.Group()n add_big_enemies(big_enemies, enemies, 2)nn clock = pygame.time.Clock()nn # 用於切換圖片n switch_image = Truenn # 用於延遲n delay = 100nn running = Truenn while running:n for event in pygame.event.get():n if event.type == QUIT:n pygame.quit()n sys.exit()nn # 檢測用戶的鍵盤操作n key_pressed = pygame.key.get_pressed()nn if key_pressed[K_w] or key_pressed[K_UP]:n me.moveUp()n if key_pressed[K_s] or key_pressed[K_DOWN]:n me.moveDown()n if key_pressed[K_a] or key_pressed[K_LEFT]:n me.moveLeft()n if key_pressed[K_d] or key_pressed[K_RIGHT]:n me.moveRight()n n screen.blit(background, (0, 0))nn # 繪製大型敵機n for each in big_enemies:n each.move()n if switch_image:n screen.blit(each.image1, each.rect)n else:n screen.blit(each.image2, each.rect)n # 即將出現在畫面中,播放音效n if each.rect.bottom > -50:n enemy3_fly_sound.play()nn # 繪製中型敵機:n for each in mid_enemies:n each.move()n screen.blit(each.image, each.rect)nn # 繪製小型敵機:n for each in small_enemies:n each.move()n screen.blit(each.image, each.rect)n n # 繪製我方飛機 通過切換圖片實現發動機噴氣效果n if switch_image:n screen.blit(me.image1, me.rect)n else:n screen.blit(me.image2, me.rect)nn # 切換圖片n if not(delay % 5):n switch_image = not switch_imagenn delay -= 1n if not delay:n delay = 100nn pygame.display.flip()n clock.tick(60)n nif __name__ == "__main__":n try:n main()n except SystemExit:n passn except:n traceback.print_exc()n pygame.quit()n input()n
我機模塊
import pygamennclass MyPlane(pygame.sprite.Sprite):n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image1 = pygame.image.load("images/me1.png").convert_alpha()n self.image2 = pygame.image.load("images/me2.png").convert_alpha()n self.rect = self.image1.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.rect.left, self.rect.top = n (self.width - self.rect.width) // 2, n self.height - self.rect.height - 60 # 我機初始位置n self.speed = 10nn def moveUp(self):n if self.rect.top > 0:n self.rect.top -= self.speedn else:n self.rect.top = 0nn def moveDown(self):n if self.rect.bottom < self.height - 60:n self.rect.top += self.speedn else:n self.rect.bottom = self.height - 60nn def moveLeft(self):n if self.rect.left > 0:n self.rect.left -= self.speedn else:n self.rect.left = 0nn def moveRight(self):n if self.rect.right < self.width:n self.rect.left += self.speedn else:n self.rect.right = self.widthn
敵機模塊
import pygamenfrom random import *nnclass SmallEnemy(pygame.sprite.Sprite):n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/enemy1.png").convert_alpha()n self.rect = self.image.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.speed = 2n self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-5 * self.height, 0)nn def move(self):n if self.rect.top < self.height:n self.rect.top += self.speedn else:n self.reset()nn def reset(self):n self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-5 * self.height, 0)nnnclass MidEnemy(pygame.sprite.Sprite):n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/enemy2.png").convert_alpha()n self.rect = self.image.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.speed = 1n self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-10 * self.height, -self.height)nn def move(self):n if self.rect.top < self.height:n self.rect.top += self.speedn else:n self.reset()nn def reset(self):n self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-10 * self.height, -self.height)nnnclass BigEnemy(pygame.sprite.Sprite):n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()n self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()n self.rect = self.image1.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.speed = 1n self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-15 * self.height, -5 * self.height)nn def move(self):n if self.rect.top < self.height:n self.rect.top += self.speedn else:n self.reset()nn def reset(self):n self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-15 * self.height, -5 * self.height)n
3.添加碰撞效果及子彈相關代碼
主模塊
# -*- coding: utf-8 -*-n# main.pynimport pygamenimport sysnimport tracebacknimport myplanenimport enemynimport bulletnnfrom pygame.locals import *nfrom random import *nnpygame.init()npygame.mixer.init()nnbg_size = width, height = 480, 700nscreen = pygame.display.set_mode(bg_size)npygame.display.set_caption("飛機大戰 -- FishC Demo")nnbackground = pygame.image.load("images/background.png").convert()nnBLACK = (0, 0, 0)nGREEN = (0, 255, 0)nRED = (255, 0, 0)nn# 載入遊戲音樂npygame.mixer.music.load("sound/game_music.ogg")npygame.mixer.music.set_volume(0.2)nbullet_sound = pygame.mixer.Sound("sound/bullet.wav")nbullet_sound.set_volume(0.2)nbomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")nbomb_sound.set_volume(0.2)nsupply_sound = pygame.mixer.Sound("sound/supply.wav")nsupply_sound.set_volume(0.2)nget_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")nget_bomb_sound.set_volume(0.2)nget_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")nget_bullet_sound.set_volume(0.2)nupgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")nupgrade_sound.set_volume(0.2)nenemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")nenemy3_fly_sound.set_volume(0.2)nenemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")nenemy1_down_sound.set_volume(0.2)nenemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")nenemy2_down_sound.set_volume(0.2)nenemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")nenemy3_down_sound.set_volume(0.5)nme_down_sound = pygame.mixer.Sound("sound/me_down.wav")nme_down_sound.set_volume(0.2)nnndef add_small_enemies(group1, group2, num):n for i in range(num):n e1 = enemy.SmallEnemy(bg_size)n group1.add(e1)n group2.add(e1)nndef add_mid_enemies(group1, group2, num):n for i in range(num):n e2 = enemy.MidEnemy(bg_size)n group1.add(e2)n group2.add(e2)nndef add_big_enemies(group1, group2, num):n for i in range(num):n e3 = enemy.BigEnemy(bg_size)n group1.add(e3)n group2.add(e3)n nndef main():n pygame.mixer.music.play(-1)nn # 生成我方飛機n me = myplane.MyPlane(bg_size)nn enemies = pygame.sprite.Group()nn # 生成敵方小型飛機n small_enemies = pygame.sprite.Group()n add_small_enemies(small_enemies, enemies, 15)nn # 生成敵方中型飛機n mid_enemies = pygame.sprite.Group()n add_mid_enemies(mid_enemies, enemies, 4)nn # 生成敵方大型飛機n big_enemies = pygame.sprite.Group()n add_big_enemies(big_enemies, enemies, 2)nn # 生成普通子彈n bullet1 = []n bullet1_index = 0n BULLET1_NUM = 4n for i in range(BULLET1_NUM):n bullet1.append(bullet.Bullet1(me.rect.midtop))nn clock = pygame.time.Clock()nn # 中彈圖片索引n e1_destroy_index = 0n e2_destroy_index = 0n e3_destroy_index = 0n me_destroy_index = 0nn # 用於切換圖片n switch_image = Truenn # 用於延遲n delay = 100nn running = Truenn while running:n for event in pygame.event.get():n if event.type == QUIT:n pygame.quit()n sys.exit()nn # 檢測用戶的鍵盤操作n key_pressed = pygame.key.get_pressed()nn if key_pressed[K_w] or key_pressed[K_UP]:n me.moveUp()n if key_pressed[K_s] or key_pressed[K_DOWN]:n me.moveDown()n if key_pressed[K_a] or key_pressed[K_LEFT]:n me.moveLeft()n if key_pressed[K_d] or key_pressed[K_RIGHT]:n me.moveRight()n n screen.blit(background, (0, 0))nn # 發射子彈n if not(delay % 10):n bullet1[bullet1_index].reset(me.rect.midtop)n bullet1_index = (bullet1_index + 1) % BULLET1_NUMnn # 檢測子彈是否擊中敵機n for b in bullet1:n if b.active:n b.move()n screen.blit(b.image, b.rect)n enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)n if enemy_hit:n b.active = Falsen for e in enemy_hit:n if e in mid_enemies or e in big_enemies:n e.hit = Truen e.energy -= 1n if e.energy == 0:n e.active = Falsen else:n e.active = Falsen n # 繪製大型敵機n for each in big_enemies:n if each.active:n each.move()n if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n if switch_image:n screen.blit(each.image1, each.rect)n else:n screen.blit(each.image2, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.BigEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n n # 即將出現在畫面中,播放音效n if each.rect.bottom == -50:n enemy3_fly_sound.play(-1) # -1代表循環播放音樂n else:n # 毀滅n if not(delay % 3):n if e3_destroy_index == 0:n enemy3_down_sound.play()n screen.blit(each.destroy_images[e3_destroy_index], each.rect)n e3_destroy_index = (e3_destroy_index + 1) % 6n if e3_destroy_index == 0:n enemy3_fly_sound.stop() # 被擊中停止播放音效n each.reset()nn # 繪製中型敵機:n for each in mid_enemies:n if each.active:n each.move()nn if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n screen.blit(each.image, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.MidEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n else:n # 毀滅n if not(delay % 3):n if e2_destroy_index == 0:n enemy2_down_sound.play()n screen.blit(each.destroy_images[e2_destroy_index], each.rect)n e2_destroy_index = (e2_destroy_index + 1) % 4n if e2_destroy_index == 0:n each.reset()nn # 繪製小型敵機:n for each in small_enemies:n if each.active:n each.move()n screen.blit(each.image, each.rect)n else:n # 毀滅n if not(delay % 3):n if e1_destroy_index == 0:n enemy1_down_sound.play()n screen.blit(each.destroy_images[e1_destroy_index], each.rect)n e1_destroy_index = (e1_destroy_index + 1) % 4n if e1_destroy_index == 0:n each.reset()nn # 檢測我方飛機是否被撞n enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)n if enemies_down:n # me.active = Falsen for e in enemies_down:n e.active = Falsen n # 繪製我方飛機n if me.active:n if switch_image:n screen.blit(me.image1, me.rect)n else:n screen.blit(me.image2, me.rect)n else:n # 毀滅n if not(delay % 3):n if me_destroy_index == 0:n me_down_sound.play()n screen.blit(me.destroy_images[me_destroy_index], me.rect)n me_destroy_index = (me_destroy_index + 1) % 4n if me_destroy_index == 0:n print("Game Over!")n running = Falsenn # 切換圖片n if not(delay % 5):n switch_image = not switch_imagenn delay -= 1n if not delay:n delay = 100nn pygame.display.flip()n clock.tick(60)n nif __name__ == "__main__":n try:n main()n except SystemExit:n passn except:n traceback.print_exc()n pygame.quit()n input()n
修改我機模塊
import pygamennclass MyPlane(pygame.sprite.Sprite):n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image1 = pygame.image.load("images/me1.png").convert_alpha()n self.image2 = pygame.image.load("images/me2.png").convert_alpha()n self.destroy_images = []n self.destroy_images.extend([n pygame.image.load("images/me_destroy_1.png").convert_alpha(), n pygame.image.load("images/me_destroy_2.png").convert_alpha(), n pygame.image.load("images/me_destroy_3.png").convert_alpha(), n pygame.image.load("images/me_destroy_4.png").convert_alpha() n ])n self.rect = self.image1.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.rect.left, self.rect.top = n (self.width - self.rect.width) // 2, n self.height - self.rect.height - 60n self.speed = 10n self.active = Truen self.mask = pygame.mask.from_surface(self.image1)nn def moveUp(self):n if self.rect.top > 0:n self.rect.top -= self.speedn else:n self.rect.top = 0nn def moveDown(self):n if self.rect.bottom < self.height - 60:n self.rect.top += self.speedn else:n self.rect.bottom = self.height - 60nn def moveLeft(self):n if self.rect.left > 0:n self.rect.left -= self.speedn else:n self.rect.left = 0nn def moveRight(self):n if self.rect.right < self.width:n self.rect.left += self.speedn else:n self.rect.right = self.widthn
修改敵機模塊
import pygamenfrom random import *nnclass SmallEnemy(pygame.sprite.Sprite):n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/enemy1.png").convert_alpha()n self.destroy_images = []n self.destroy_images.extend([n pygame.image.load("images/enemy1_down1.png").convert_alpha(), n pygame.image.load("images/enemy1_down2.png").convert_alpha(), n pygame.image.load("images/enemy1_down3.png").convert_alpha(), n pygame.image.load("images/enemy1_down4.png").convert_alpha() n ])n self.rect = self.image.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.speed = 2n self.active = Truen self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-5 * self.height, 0)n self.mask = pygame.mask.from_surface(self.image)nn def move(self):n if self.rect.top < self.height:n self.rect.top += self.speedn else:n self.reset()nn def reset(self):n self.active = Truen self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-5 * self.height, 0)nnnclass MidEnemy(pygame.sprite.Sprite):n energy = 8n n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/enemy2.png").convert_alpha()n self.image_hit = pygame.image.load("images/enemy2_hit.png").convert_alpha()n self.destroy_images = []n self.destroy_images.extend([n pygame.image.load("images/enemy2_down1.png").convert_alpha(), n pygame.image.load("images/enemy2_down2.png").convert_alpha(), n pygame.image.load("images/enemy2_down3.png").convert_alpha(), n pygame.image.load("images/enemy2_down4.png").convert_alpha() n ])n self.rect = self.image.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.speed = 1n self.active = Truen self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-10 * self.height, -self.height)n self.mask = pygame.mask.from_surface(self.image)n self.energy = MidEnemy.energyn self.hit = Falsenn def move(self):n if self.rect.top < self.height:n self.rect.top += self.speedn else:n self.reset()nn def reset(self):n self.active = Truen self.energy = MidEnemy.energyn self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-10 * self.height, -self.height)nnnclass BigEnemy(pygame.sprite.Sprite):n energy = 20n n def __init__(self, bg_size):n pygame.sprite.Sprite.__init__(self)nn self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()n self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()n self.image_hit = pygame.image.load("images/enemy3_hit.png").convert_alpha()n self.destroy_images = []n self.destroy_images.extend([n pygame.image.load("images/enemy3_down1.png").convert_alpha(), n pygame.image.load("images/enemy3_down2.png").convert_alpha(), n pygame.image.load("images/enemy3_down3.png").convert_alpha(), n pygame.image.load("images/enemy3_down4.png").convert_alpha(), n pygame.image.load("images/enemy3_down5.png").convert_alpha(), n pygame.image.load("images/enemy3_down6.png").convert_alpha() n ])n self.rect = self.image1.get_rect()n self.width, self.height = bg_size[0], bg_size[1]n self.speed = 1n self.active = Truen self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-15 * self.height, -5 * self.height)n self.mask = pygame.mask.from_surface(self.image1)n self.energy = BigEnemy.energyn self.hit = Falsenn def move(self):n if self.rect.top < self.height:n self.rect.top += self.speedn else:n self.reset()nn def reset(self):n self.active = Truen self.energy = BigEnemy.energyn self.rect.left, self.rect.top = n randint(0, self.width - self.rect.width), n randint(-15 * self.height, -5 * self.height)n n
增加子彈模塊
import pygamennclass Bullet1(pygame.sprite.Sprite):n def __init__(self, position):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/bullet1.png").convert_alpha()n self.rect = self.image.get_rect()n self.rect.left, self.rect.top = positionn self.speed = 12n self.active = Truen self.mask = pygame.mask.from_surface(self.image)nn def move(self):n self.rect.top -= self.speednn if self.rect.top < 0:n self.active = Falsenn def reset(self, position):n self.rect.left, self.rect.top = positionn self.active = True n
4.增加射擊得分、全屏炸彈、遊戲暫停功能
# -*- coding: utf-8 -*-n# main.pynimport pygamenimport sysnimport tracebacknimport myplanenimport enemynimport bulletnnfrom pygame.locals import *nfrom random import *nnpygame.init()npygame.mixer.init()nnbg_size = width, height = 480, 700nscreen = pygame.display.set_mode(bg_size)npygame.display.set_caption("飛機大戰 -- FishC Demo")nnbackground = pygame.image.load("images/background.png").convert()nnBLACK = (0, 0, 0)nWHITE = (255, 255, 255)nGREEN = (0, 255, 0)nRED = (255, 0, 0)nn# 載入遊戲音樂npygame.mixer.music.load("sound/game_music.ogg")npygame.mixer.music.set_volume(0.2)nbullet_sound = pygame.mixer.Sound("sound/bullet.wav")nbullet_sound.set_volume(0.2)nbomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")nbomb_sound.set_volume(0.2)nsupply_sound = pygame.mixer.Sound("sound/supply.wav")nsupply_sound.set_volume(0.2)nget_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")nget_bomb_sound.set_volume(0.2)nget_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")nget_bullet_sound.set_volume(0.2)nupgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")nupgrade_sound.set_volume(0.2)nenemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")nenemy3_fly_sound.set_volume(0.2)nenemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")nenemy1_down_sound.set_volume(0.2)nenemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")nenemy2_down_sound.set_volume(0.2)nenemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")nenemy3_down_sound.set_volume(0.5)nme_down_sound = pygame.mixer.Sound("sound/me_down.wav")nme_down_sound.set_volume(0.2)nnndef add_small_enemies(group1, group2, num):n for i in range(num):n e1 = enemy.SmallEnemy(bg_size)n group1.add(e1)n group2.add(e1)nndef add_mid_enemies(group1, group2, num):n for i in range(num):n e2 = enemy.MidEnemy(bg_size)n group1.add(e2)n group2.add(e2)nndef add_big_enemies(group1, group2, num):n for i in range(num):n e3 = enemy.BigEnemy(bg_size)n group1.add(e3)n group2.add(e3)nndef inc_speed(target, inc):n for each in target:n each.speed += incnndef main():n pygame.mixer.music.play(-1)nn # 生成我方飛機n me = myplane.MyPlane(bg_size)nn enemies = pygame.sprite.Group()nn # 生成敵方小型飛機n small_enemies = pygame.sprite.Group()n add_small_enemies(small_enemies, enemies, 15)nn # 生成敵方中型飛機n mid_enemies = pygame.sprite.Group()n add_mid_enemies(mid_enemies, enemies, 4)nn # 生成敵方大型飛機n big_enemies = pygame.sprite.Group()n add_big_enemies(big_enemies, enemies, 2)nn # 生成普通子彈n bullet1 = []n bullet1_index = 0n BULLET1_NUM = 4n for i in range(BULLET1_NUM):n bullet1.append(bullet.Bullet1(me.rect.midtop))nn clock = pygame.time.Clock()nn # 中彈圖片索引n e1_destroy_index = 0n e2_destroy_index = 0n e3_destroy_index = 0n me_destroy_index = 0nn # 統計得分n score = 0n score_font = pygame.font.Font("font/font.ttf", 36)nn # 標誌是否暫停遊戲n paused = Falsen pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()n pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()n resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()n resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()n paused_rect = pause_nor_image.get_rect()n paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10n paused_image = pause_nor_imagenn # 設置難度級別n level = 1nn # 全屏炸彈n bomb_image = pygame.image.load("images/bomb.png").convert_alpha()n bomb_rect = bomb_image.get_rect()n bomb_font = pygame.font.Font("font/font.ttf", 48)n bomb_num = 3nn # 用於切換圖片n switch_image = Truenn # 用於延遲n delay = 100nn running = Truenn while running:n for event in pygame.event.get():n if event.type == QUIT:n pygame.quit()n sys.exit()nn elif event.type == MOUSEBUTTONDOWN:n if event.button == 1 and paused_rect.collidepoint(event.pos):n paused = not pausednn elif event.type == MOUSEMOTION:n if paused_rect.collidepoint(event.pos):n if paused:n paused_image = resume_pressed_imagen else:n paused_image = pause_pressed_imagen else:n if paused:n paused_image = resume_nor_imagen else:n paused_image = pause_nor_imagenn elif event.type == KEYDOWN:n if event.key == K_SPACE:n if bomb_num:n bomb_num -= 1n bomb_sound.play()n for each in enemies:n if each.rect.bottom > 0:n each.active = Falsen nn # 根據用戶的得分增加難度n if level == 1 and score > 50000:n level = 2n upgrade_sound.play()n # 增加3架小型敵機、2架中型敵機和1架大型敵機n add_small_enemies(small_enemies, enemies, 3)n add_mid_enemies(mid_enemies, enemies, 2)n add_big_enemies(big_enemies, enemies, 1)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n elif level == 2 and score > 300000:n level = 3n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n elif level == 3 and score > 600000:n level = 4n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n elif level == 4 and score > 1000000:n level = 5n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n nn screen.blit(background, (0, 0))n n if not paused:n # 檢測用戶的鍵盤操作n key_pressed = pygame.key.get_pressed()nn if key_pressed[K_w] or key_pressed[K_UP]:n me.moveUp()n if key_pressed[K_s] or key_pressed[K_DOWN]:n me.moveDown()n if key_pressed[K_a] or key_pressed[K_LEFT]:n me.moveLeft()n if key_pressed[K_d] or key_pressed[K_RIGHT]:n me.moveRight()nn # 發射子彈n if not(delay % 10):n bullet1[bullet1_index].reset(me.rect.midtop)n bullet1_index = (bullet1_index + 1) % BULLET1_NUMnn # 檢測子彈是否擊中敵機n for b in bullet1:n if b.active:n b.move()n screen.blit(b.image, b.rect)n enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)n if enemy_hit:n b.active = Falsen for e in enemy_hit:n if e in mid_enemies or e in big_enemies:n e.hit = Truen e.energy -= 1n if e.energy == 0:n e.active = Falsen else:n e.active = Falsen n # 繪製大型敵機n for each in big_enemies:n if each.active:n each.move()n if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n if switch_image:n screen.blit(each.image1, each.rect)n else:n screen.blit(each.image2, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.BigEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n n # 即將出現在畫面中,播放音效n if each.rect.bottom == -50:n enemy3_fly_sound.play(-1)n else:n # 毀滅n if not(delay % 3):n if e3_destroy_index == 0:n enemy3_down_sound.play()n screen.blit(each.destroy_images[e3_destroy_index], each.rect)n e3_destroy_index = (e3_destroy_index + 1) % 6n if e3_destroy_index == 0:n enemy3_fly_sound.stop()n score += 10000n each.reset()nn # 繪製中型敵機:n for each in mid_enemies:n if each.active:n each.move()nn if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n screen.blit(each.image, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.MidEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n else:n # 毀滅n if not(delay % 3):n if e2_destroy_index == 0:n enemy2_down_sound.play()n screen.blit(each.destroy_images[e2_destroy_index], each.rect)n e2_destroy_index = (e2_destroy_index + 1) % 4n if e2_destroy_index == 0:n score += 6000n each.reset()nn # 繪製小型敵機:n for each in small_enemies:n if each.active:n each.move()n screen.blit(each.image, each.rect)n else:n # 毀滅n if not(delay % 3):n if e1_destroy_index == 0:n enemy1_down_sound.play()n screen.blit(each.destroy_images[e1_destroy_index], each.rect)n e1_destroy_index = (e1_destroy_index + 1) % 4n if e1_destroy_index == 0:n score += 1000n each.reset()nn # 檢測我方飛機是否被撞n enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)n if enemies_down:n # me.active = Falsen for e in enemies_down:n e.active = Falsen n # 繪製我方飛機n if me.active:n if switch_image:n screen.blit(me.image1, me.rect)n else:n screen.blit(me.image2, me.rect)n else:n # 毀滅n if not(delay % 3):n if me_destroy_index == 0:n me_down_sound.play()n screen.blit(me.destroy_images[me_destroy_index], me.rect)n me_destroy_index = (me_destroy_index + 1) % 4n if me_destroy_index == 0:n print("Game Over!")n running = Falsenn # 繪製全屏炸彈數量n bomb_text = bomb_font.render("x %d" % bomb_num, True, WHITE)n text_rect = bomb_text.get_rect()n screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))n screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))nn # 繪製得分n score_text = score_font.render("Score : %s" % str(score), True, WHITE)n screen.blit(score_text, (10, 5))nn # 繪製暫停按鈕n screen.blit(paused_image, paused_rect)nn # 切換圖片n if not(delay % 5):n switch_image = not switch_imagenn delay -= 1n if not delay:n delay = 100nn pygame.display.flip()n clock.tick(60)n nif __name__ == "__main__":n try:n main()n except SystemExit:n passn except:n traceback.print_exc()n pygame.quit()n input()n
5.增加補給包功能(全屏炸彈和雙排子彈)
# -*- coding: utf-8 -*-n# main.pynimport pygamenimport sysnimport tracebacknimport myplanenimport enemynimport bulletnimport supplynnfrom pygame.locals import *nfrom random import *nnpygame.init()npygame.mixer.init()nnbg_size = width, height = 480, 700nscreen = pygame.display.set_mode(bg_size)npygame.display.set_caption("飛機大戰 -- FishC Demo")nnbackground = pygame.image.load("images/background.png").convert()nnBLACK = (0, 0, 0)nWHITE = (255, 255, 255)nGREEN = (0, 255, 0)nRED = (255, 0, 0)nn# 載入遊戲音樂npygame.mixer.music.load("sound/game_music.ogg")npygame.mixer.music.set_volume(0.2)nbullet_sound = pygame.mixer.Sound("sound/bullet.wav")nbullet_sound.set_volume(0.2)nbomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")nbomb_sound.set_volume(0.2)nsupply_sound = pygame.mixer.Sound("sound/supply.wav")nsupply_sound.set_volume(0.2)nget_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")nget_bomb_sound.set_volume(0.2)nget_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")nget_bullet_sound.set_volume(0.2)nupgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")nupgrade_sound.set_volume(0.2)nenemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")nenemy3_fly_sound.set_volume(0.2)nenemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")nenemy1_down_sound.set_volume(0.2)nenemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")nenemy2_down_sound.set_volume(0.2)nenemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")nenemy3_down_sound.set_volume(0.5)nme_down_sound = pygame.mixer.Sound("sound/me_down.wav")nme_down_sound.set_volume(0.2)nnndef add_small_enemies(group1, group2, num):n for i in range(num):n e1 = enemy.SmallEnemy(bg_size)n group1.add(e1)n group2.add(e1)nndef add_mid_enemies(group1, group2, num):n for i in range(num):n e2 = enemy.MidEnemy(bg_size)n group1.add(e2)n group2.add(e2)nndef add_big_enemies(group1, group2, num):n for i in range(num):n e3 = enemy.BigEnemy(bg_size)n group1.add(e3)n group2.add(e3)nndef inc_speed(target, inc):n for each in target:n each.speed += incnndef main():n pygame.mixer.music.play(-1)nn # 生成我方飛機n me = myplane.MyPlane(bg_size)nn enemies = pygame.sprite.Group()nn # 生成敵方小型飛機n small_enemies = pygame.sprite.Group()n add_small_enemies(small_enemies, enemies, 15)nn # 生成敵方中型飛機n mid_enemies = pygame.sprite.Group()n add_mid_enemies(mid_enemies, enemies, 4)nn # 生成敵方大型飛機n big_enemies = pygame.sprite.Group()n add_big_enemies(big_enemies, enemies, 2)nn # 生成普通子彈n bullet1 = []n bullet1_index = 0n BULLET1_NUM = 4n for i in range(BULLET1_NUM):n bullet1.append(bullet.Bullet1(me.rect.midtop))nn # 生成超級子彈n bullet2 = []n bullet2_index = 0n BULLET2_NUM = 8n for i in range(BULLET2_NUM//2):n bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery)))n bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery)))nn clock = pygame.time.Clock()nn # 中彈圖片索引n e1_destroy_index = 0n e2_destroy_index = 0n e3_destroy_index = 0n me_destroy_index = 0nn # 統計得分n score = 0n score_font = pygame.font.Font("font/font.ttf", 36)nn # 標誌是否暫停遊戲n paused = Falsen pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()n pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()n resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()n resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()n paused_rect = pause_nor_image.get_rect()n paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10n paused_image = pause_nor_imagenn # 設置難度級別n level = 1nn # 全屏炸彈n bomb_image = pygame.image.load("images/bomb.png").convert_alpha()n bomb_rect = bomb_image.get_rect()n bomb_font = pygame.font.Font("font/font.ttf", 48)n bomb_num = 3nn # 每30秒發放一個補給包n bullet_supply = supply.Bullet_Supply(bg_size)n bomb_supply = supply.Bomb_Supply(bg_size)n SUPPLY_TIME = USEREVENTn pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)nn # 超級子彈定時器n DOUBLE_BULLET_TIME = USEREVENT + 1nn # 標誌是否使用超級子彈n is_double_bullet = Falsenn # 用於切換圖片n switch_image = Truenn # 用於延遲n delay = 100nn running = Truenn while running:n for event in pygame.event.get():n if event.type == QUIT:n pygame.quit()n sys.exit()nn elif event.type == MOUSEBUTTONDOWN:n if event.button == 1 and paused_rect.collidepoint(event.pos):n paused = not pausedn if paused:n pygame.time.set_timer(SUPPLY_TIME, 0)n pygame.mixer.music.pause()n pygame.mixer.pause()n else:n pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)n pygame.mixer.music.unpause()n pygame.mixer.unpause()nn elif event.type == MOUSEMOTION:n if paused_rect.collidepoint(event.pos):n if paused:n paused_image = resume_pressed_imagen else:n paused_image = pause_pressed_imagen else:n if paused:n paused_image = resume_nor_imagen else:n paused_image = pause_nor_imagenn elif event.type == KEYDOWN:n if event.key == K_SPACE:n if bomb_num:n bomb_num -= 1n bomb_sound.play()n for each in enemies:n if each.rect.bottom > 0:n each.active = Falsenn elif event.type == SUPPLY_TIME:n supply_sound.play()n if choice([True, False]):n bomb_supply.reset()n else:n bullet_supply.reset()nn elif event.type == DOUBLE_BULLET_TIME:n is_double_bullet = Falsen pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)n nn # 根據用戶的得分增加難度n if level == 1 and score > 50000:n level = 2n upgrade_sound.play()n # 增加3架小型敵機、2架中型敵機和1架大型敵機n add_small_enemies(small_enemies, enemies, 3)n add_mid_enemies(mid_enemies, enemies, 2)n add_big_enemies(big_enemies, enemies, 1)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n elif level == 2 and score > 300000:n level = 3n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n elif level == 3 and score > 600000:n level = 4n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n elif level == 4 and score > 1000000:n level = 5n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n nn screen.blit(background, (0, 0))n n if not paused:n # 檢測用戶的鍵盤操作n key_pressed = pygame.key.get_pressed()nn if key_pressed[K_w] or key_pressed[K_UP]:n me.moveUp()n if key_pressed[K_s] or key_pressed[K_DOWN]:n me.moveDown()n if key_pressed[K_a] or key_pressed[K_LEFT]:n me.moveLeft()n if key_pressed[K_d] or key_pressed[K_RIGHT]:n me.moveRight()nn # 繪製全屏炸彈補給並檢測是否獲得n if bomb_supply.active:n bomb_supply.move()n screen.blit(bomb_supply.image, bomb_supply.rect)n if pygame.sprite.collide_mask(bomb_supply, me):n get_bomb_sound.play()n if bomb_num < 3:n bomb_num += 1n bomb_supply.active = Falsenn # 繪製超級子彈補給並檢測是否獲得n if bullet_supply.active:n bullet_supply.move()n screen.blit(bullet_supply.image, bullet_supply.rect)n if pygame.sprite.collide_mask(bullet_supply, me):n get_bullet_sound.play()n is_double_bullet = Truen pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)n bullet_supply.active = Falsenn # 發射子彈n if not(delay % 10):n bullet_sound.play()n if is_double_bullet:n bullets = bullet2n bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery))n bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery))n bullet2_index = (bullet2_index + 2) % BULLET2_NUMn else:n bullets = bullet1n bullets[bullet1_index].reset(me.rect.midtop)n bullet1_index = (bullet1_index + 1) % BULLET1_NUMnn n # 檢測子彈是否擊中敵機n for b in bullets:n if b.active:n b.move()n screen.blit(b.image, b.rect)n enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)n if enemy_hit:n b.active = Falsen for e in enemy_hit:n if e in mid_enemies or e in big_enemies:n e.hit = Truen e.energy -= 1n if e.energy == 0:n e.active = Falsen else:n e.active = Falsen n # 繪製大型敵機n for each in big_enemies:n if each.active:n each.move()n if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n if switch_image:n screen.blit(each.image1, each.rect)n else:n screen.blit(each.image2, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.BigEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n n # 即將出現在畫面中,播放音效n if each.rect.bottom == -50:n enemy3_fly_sound.play(-1)n else:n # 毀滅n if not(delay % 3):n if e3_destroy_index == 0:n enemy3_down_sound.play()n screen.blit(each.destroy_images[e3_destroy_index], each.rect)n e3_destroy_index = (e3_destroy_index + 1) % 6n if e3_destroy_index == 0:n enemy3_fly_sound.stop()n score += 10000n each.reset()nn # 繪製中型敵機:n for each in mid_enemies:n if each.active:n each.move()nn if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n screen.blit(each.image, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.MidEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n else:n # 毀滅n if not(delay % 3):n if e2_destroy_index == 0:n enemy2_down_sound.play()n screen.blit(each.destroy_images[e2_destroy_index], each.rect)n e2_destroy_index = (e2_destroy_index + 1) % 4n if e2_destroy_index == 0:n score += 6000n each.reset()nn # 繪製小型敵機:n for each in small_enemies:n if each.active:n each.move()n screen.blit(each.image, each.rect)n else:n # 毀滅n if not(delay % 3):n if e1_destroy_index == 0:n enemy1_down_sound.play()n screen.blit(each.destroy_images[e1_destroy_index], each.rect)n e1_destroy_index = (e1_destroy_index + 1) % 4n if e1_destroy_index == 0:n score += 1000n each.reset()nn # 檢測我方飛機是否被撞n enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)n if enemies_down:n # me.active = Falsen for e in enemies_down:n e.active = Falsen n # 繪製我方飛機n if me.active:n if switch_image:n screen.blit(me.image1, me.rect)n else:n screen.blit(me.image2, me.rect)n else:n # 毀滅n if not(delay % 3):n if me_destroy_index == 0:n me_down_sound.play()n screen.blit(me.destroy_images[me_destroy_index], me.rect)n me_destroy_index = (me_destroy_index + 1) % 4n if me_destroy_index == 0:n print("Game Over!")n running = Falsenn # 繪製全屏炸彈數量n bomb_text = bomb_font.render(" X %d" % bomb_num, True, WHITE)n text_rect = bomb_text.get_rect()n screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))n screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))nn # 繪製得分n score_text = score_font.render("Score : %s" % str(score), True, WHITE)n screen.blit(score_text, (10, 5))nn # 繪製暫停按鈕n screen.blit(paused_image, paused_rect)nn # 切換圖片n if not(delay % 5):n switch_image = not switch_imagenn delay -= 1n if not delay:n delay = 100nn pygame.display.flip()n clock.tick(60)n nif __name__ == "__main__":n try:n main()n except SystemExit:n passn except:n traceback.print_exc()n pygame.quit()n input()n
增加補給包模塊
import pygamennclass Bullet1(pygame.sprite.Sprite):n def __init__(self, position):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/bullet1.png").convert_alpha()n self.rect = self.image.get_rect()n self.rect.left, self.rect.top = positionn self.speed = 12n self.active = Falsen self.mask = pygame.mask.from_surface(self.image)nn def move(self):n self.rect.top -= self.speednn if self.rect.top < 0:n self.active = Falsenn def reset(self, position):n self.rect.left, self.rect.top = positionn self.active = Truennclass Bullet2(pygame.sprite.Sprite): # 雙排超級子彈n def __init__(self, position):n pygame.sprite.Sprite.__init__(self)nn self.image = pygame.image.load("images/bullet2.png").convert_alpha()n self.rect = self.image.get_rect()n self.rect.left, self.rect.top = positionn self.speed = 14n self.active = Falsen self.mask = pygame.mask.from_surface(self.image)nn def move(self):n self.rect.top -= self.speednn if self.rect.top < 0:n self.active = Falsenn def reset(self, position):n self.rect.left, self.rect.top = positionn self.active = Truen n
6.完善遊戲的功能(剩餘飛機、撞到敵人會掉血、讀取寫入歷史最高分、根據得分增加難度)
# -*- coding: utf-8 -*-n# main.pynimport pygamenimport sysnimport tracebacknimport myplanenimport enemynimport bulletnimport supplynnfrom pygame.locals import *nfrom random import *nnpygame.init()npygame.mixer.init()nnbg_size = width, height = 480, 700nscreen = pygame.display.set_mode(bg_size)npygame.display.set_caption("飛機大戰 -- FishC Demo")nnbackground = pygame.image.load("images/background.png").convert()nnBLACK = (0, 0, 0)nWHITE = (255, 255, 255)nGREEN = (0, 255, 0)nRED = (255, 0, 0)nn# 載入遊戲音樂npygame.mixer.music.load("sound/game_music.ogg")npygame.mixer.music.set_volume(0.2)nbullet_sound = pygame.mixer.Sound("sound/bullet.wav")nbullet_sound.set_volume(0.2)nbomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")nbomb_sound.set_volume(0.2)nsupply_sound = pygame.mixer.Sound("sound/supply.wav")nsupply_sound.set_volume(0.2)nget_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")nget_bomb_sound.set_volume(0.2)nget_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")nget_bullet_sound.set_volume(0.2)nupgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")nupgrade_sound.set_volume(0.2)nenemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")nenemy3_fly_sound.set_volume(0.2)nenemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")nenemy1_down_sound.set_volume(0.2)nenemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")nenemy2_down_sound.set_volume(0.2)nenemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")nenemy3_down_sound.set_volume(0.5)nme_down_sound = pygame.mixer.Sound("sound/me_down.wav")nme_down_sound.set_volume(0.2)nnndef add_small_enemies(group1, group2, num):n for i in range(num):n e1 = enemy.SmallEnemy(bg_size)n group1.add(e1)n group2.add(e1)nndef add_mid_enemies(group1, group2, num):n for i in range(num):n e2 = enemy.MidEnemy(bg_size)n group1.add(e2)n group2.add(e2)nndef add_big_enemies(group1, group2, num):n for i in range(num):n e3 = enemy.BigEnemy(bg_size)n group1.add(e3)n group2.add(e3)nndef inc_speed(target, inc):n for each in target:n each.speed += incnndef main():n pygame.mixer.music.play(-1)nn # 生成我方飛機n me = myplane.MyPlane(bg_size)nn enemies = pygame.sprite.Group()nn # 生成敵方小型飛機n small_enemies = pygame.sprite.Group()n add_small_enemies(small_enemies, enemies, 15)nn # 生成敵方中型飛機n mid_enemies = pygame.sprite.Group()n add_mid_enemies(mid_enemies, enemies, 4)nn # 生成敵方大型飛機n big_enemies = pygame.sprite.Group()n add_big_enemies(big_enemies, enemies, 2)nn # 生成普通子彈n bullet1 = []n bullet1_index = 0n BULLET1_NUM = 4n for i in range(BULLET1_NUM):n bullet1.append(bullet.Bullet1(me.rect.midtop))nn # 生成超級子彈n bullet2 = []n bullet2_index = 0n BULLET2_NUM = 8n for i in range(BULLET2_NUM//2):n bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery)))n bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery)))nn clock = pygame.time.Clock()nn # 中彈圖片索引n e1_destroy_index = 0n e2_destroy_index = 0n e3_destroy_index = 0n me_destroy_index = 0nn # 統計得分n score = 0n score_font = pygame.font.Font("font/font.ttf", 36)nn # 標誌是否暫停遊戲n paused = Falsen pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()n pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()n resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()n resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()n paused_rect = pause_nor_image.get_rect()n paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10n paused_image = pause_nor_imagenn # 設置難度級別n level = 1nn # 全屏炸彈n bomb_image = pygame.image.load("images/bomb.png").convert_alpha()n bomb_rect = bomb_image.get_rect()n bomb_font = pygame.font.Font("font/font.ttf", 48)n bomb_num = 3nn # 每30秒發放一個補給包n bullet_supply = supply.Bullet_Supply(bg_size)n bomb_supply = supply.Bomb_Supply(bg_size)n SUPPLY_TIME = USEREVENTn pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)nn # 超級子彈定時器n DOUBLE_BULLET_TIME = USEREVENT + 1nn # 標誌是否使用超級子彈n is_double_bullet = Falsenn # 解除我方無敵狀態定時器n INVINCIBLE_TIME = USEREVENT + 2nn # 生命數量n life_image = pygame.image.load("images/life.png").convert_alpha()n life_rect = life_image.get_rect()n life_num = 3nn # 用於阻止重複打開記錄文件n recorded = Falsenn # 遊戲結束畫面n gameover_font = pygame.font.Font("font/font.TTF", 48)n again_image = pygame.image.load("images/again.png").convert_alpha()n again_rect = again_image.get_rect()n gameover_image = pygame.image.load("images/gameover.png").convert_alpha()n gameover_rect = gameover_image.get_rect()nn # 用於切換圖片n switch_image = Truenn # 用於延遲n delay = 100nn running = Truenn while running:n for event in pygame.event.get():n if event.type == QUIT:n pygame.quit()n sys.exit()nn elif event.type == MOUSEBUTTONDOWN:n if event.button == 1 and paused_rect.collidepoint(event.pos):n paused = not pausedn if paused:n pygame.time.set_timer(SUPPLY_TIME, 0)n pygame.mixer.music.pause()n pygame.mixer.pause()n else:n pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)n pygame.mixer.music.unpause()n pygame.mixer.unpause()nn elif event.type == MOUSEMOTION:n if paused_rect.collidepoint(event.pos):n if paused:n paused_image = resume_pressed_imagen else:n paused_image = pause_pressed_imagen else:n if paused:n paused_image = resume_nor_imagen else:n paused_image = pause_nor_imagenn elif event.type == KEYDOWN:n if event.key == K_SPACE:n if bomb_num:n bomb_num -= 1n bomb_sound.play()n for each in enemies:n if each.rect.bottom > 0:n each.active = Falsenn elif event.type == SUPPLY_TIME:n supply_sound.play()n if choice([True, False]):n bomb_supply.reset()n else:n bullet_supply.reset()nn elif event.type == DOUBLE_BULLET_TIME:n is_double_bullet = Falsen pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)nn elif event.type == INVINCIBLE_TIME:n me.invincible = Falsen pygame.time.set_timer(INVINCIBLE_TIME, 0)n nn # 根據用戶的得分增加難度n if level == 1 and score > 50000:n level = 2n upgrade_sound.play()n # 增加3架小型敵機、2架中型敵機和1架大型敵機n add_small_enemies(small_enemies, enemies, 3)n add_mid_enemies(mid_enemies, enemies, 2)n add_big_enemies(big_enemies, enemies, 1)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n elif level == 2 and score > 300000:n level = 3n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n elif level == 3 and score > 600000:n level = 4n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n elif level == 4 and score > 1000000:n level = 5n upgrade_sound.play()n # 增加5架小型敵機、3架中型敵機和2架大型敵機n add_small_enemies(small_enemies, enemies, 5)n add_mid_enemies(mid_enemies, enemies, 3)n add_big_enemies(big_enemies, enemies, 2)n # 提升小型敵機的速度n inc_speed(small_enemies, 1)n inc_speed(mid_enemies, 1)n nn screen.blit(background, (0, 0))n n if life_num and not paused:n # 檢測用戶的鍵盤操作n key_pressed = pygame.key.get_pressed()nn if key_pressed[K_w] or key_pressed[K_UP]:n me.moveUp()n if key_pressed[K_s] or key_pressed[K_DOWN]:n me.moveDown()n if key_pressed[K_a] or key_pressed[K_LEFT]:n me.moveLeft()n if key_pressed[K_d] or key_pressed[K_RIGHT]:n me.moveRight()nn # 繪製全屏炸彈補給並檢測是否獲得n if bomb_supply.active:n bomb_supply.move()n screen.blit(bomb_supply.image, bomb_supply.rect)n if pygame.sprite.collide_mask(bomb_supply, me):n get_bomb_sound.play()n if bomb_num < 3:n bomb_num += 1n bomb_supply.active = Falsenn # 繪製超級子彈補給並檢測是否獲得n if bullet_supply.active:n bullet_supply.move()n screen.blit(bullet_supply.image, bullet_supply.rect)n if pygame.sprite.collide_mask(bullet_supply, me):n get_bullet_sound.play()n is_double_bullet = Truen pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)n bullet_supply.active = Falsenn # 發射子彈n if not(delay % 10):n bullet_sound.play()n if is_double_bullet:n bullets = bullet2n bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery))n bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery))n bullet2_index = (bullet2_index + 2) % BULLET2_NUMn else:n bullets = bullet1n bullets[bullet1_index].reset(me.rect.midtop)n bullet1_index = (bullet1_index + 1) % BULLET1_NUMnn n # 檢測子彈是否擊中敵機n for b in bullets:n if b.active:n b.move()n screen.blit(b.image, b.rect)n enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)n if enemy_hit:n b.active = Falsen for e in enemy_hit:n if e in mid_enemies or e in big_enemies:n e.hit = Truen e.energy -= 1n if e.energy == 0:n e.active = Falsen else:n e.active = Falsen n # 繪製大型敵機n for each in big_enemies:n if each.active:n each.move()n if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n if switch_image:n screen.blit(each.image1, each.rect)n else:n screen.blit(each.image2, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.BigEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n n # 即將出現在畫面中,播放音效n if each.rect.bottom == -50:n enemy3_fly_sound.play(-1)n else:n # 毀滅n if not(delay % 3):n if e3_destroy_index == 0:n enemy3_down_sound.play()n screen.blit(each.destroy_images[e3_destroy_index], each.rect)n e3_destroy_index = (e3_destroy_index + 1) % 6n if e3_destroy_index == 0:n enemy3_fly_sound.stop()n score += 10000n each.reset()nn # 繪製中型敵機:n for each in mid_enemies:n if each.active:n each.move()nn if each.hit:n screen.blit(each.image_hit, each.rect)n each.hit = Falsen else:n screen.blit(each.image, each.rect)nn # 繪製血槽n pygame.draw.line(screen, BLACK, n (each.rect.left, each.rect.top - 5), n (each.rect.right, each.rect.top - 5), n 2)n # 當生命大於20%顯示綠色,否則顯示紅色n energy_remain = each.energy / enemy.MidEnemy.energyn if energy_remain > 0.2:n energy_color = GREENn else:n energy_color = REDn pygame.draw.line(screen, energy_color, n (each.rect.left, each.rect.top - 5), n (each.rect.left + each.rect.width * energy_remain, n each.rect.top - 5), 2)n else:n # 毀滅n if not(delay % 3):n if e2_destroy_index == 0:n enemy2_down_sound.play()n screen.blit(each.destroy_images[e2_destroy_index], each.rect)n e2_destroy_index = (e2_destroy_index + 1) % 4n if e2_destroy_index == 0:n score += 6000n each.reset()nn # 繪製小型敵機:n for each in small_enemies:n if each.active:n each.move()n screen.blit(each.image, each.rect)n else:n # 毀滅n if not(delay % 3):n if e1_destroy_index == 0:n enemy1_down_sound.play()n screen.blit(each.destroy_images[e1_destroy_index], each.rect)n e1_destroy_index = (e1_destroy_index + 1) % 4n if e1_destroy_index == 0:n score += 1000n each.reset()nn # 檢測我方飛機是否被撞n enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)n if enemies_down and not me.invincible:n me.active = Falsen for e in enemies_down:n e.active = Falsen n # 繪製我方飛機n if me.active:n if switch_image:n screen.blit(me.image1, me.rect)n else:n screen.blit(me.image2, me.rect)n else:n # 毀滅n if not(delay % 3):n if me_destroy_index == 0:n me_down_sound.play()n screen.blit(me.destroy_images[me_destroy_index], me.rect)n me_destroy_index = (me_destroy_index + 1) % 4n if me_destroy_index == 0:n life_num -= 1n me.reset()n pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)nn # 繪製全屏炸彈數量n bomb_text = bomb_font.render(" X %d" % bomb_num, True, WHITE)n text_rect = bomb_text.get_rect()n screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))n screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))nn # 繪製剩餘生命數量n if life_num:n for i in range(life_num):n screen.blit(life_image, n (width-10-(i+1)*life_rect.width, n height-10-life_rect.height))nn # 繪製得分n score_text = score_font.render("Score : %s" % str(score), True, WHITE)n screen.blit(score_text, (10, 5))nn # 繪製遊戲結束畫面n elif life_num == 0:n # 背景音樂停止n pygame.mixer.music.stop()nn # 停止全部音效n pygame.mixer.stop()nn # 停止發放補給n pygame.time.set_timer(SUPPLY_TIME, 0)nn if not recorded:n recorded = Truen # 讀取歷史最高得分n with open("record.txt", "r") as f:n record_score = int(f.read())nn # 如果玩家得分高於歷史最高得分,則存檔n if score > record_score:n with open("record.txt", "w") as f:n f.write(str(score))nn # 繪製結束畫面n record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255))n screen.blit(record_score_text, (50, 50))n n gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))n gameover_text1_rect = gameover_text1.get_rect()n gameover_text1_rect.left, gameover_text1_rect.top = n (width - gameover_text1_rect.width) // 2, height // 3n screen.blit(gameover_text1, gameover_text1_rect)n n gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))n gameover_text2_rect = gameover_text2.get_rect()n gameover_text2_rect.left, gameover_text2_rect.top = n (width - gameover_text2_rect.width) // 2, n gameover_text1_rect.bottom + 10n screen.blit(gameover_text2, gameover_text2_rect)nn again_rect.left, again_rect.top = n (width - again_rect.width) // 2, n gameover_text2_rect.bottom + 50n screen.blit(again_image, again_rect)nn gameover_rect.left, gameover_rect.top = n (width - again_rect.width) // 2, n again_rect.bottom + 10n screen.blit(gameover_image, gameover_rect)nn # 檢測用戶的滑鼠操作n # 如果用戶按下滑鼠左鍵n if pygame.mouse.get_pressed()[0]:n # 獲取滑鼠坐標n pos = pygame.mouse.get_pos()n # 如果用戶點擊「重新開始」n if again_rect.left < pos[0] < again_rect.right and n again_rect.top < pos[1] < again_rect.bottom:n # 調用main函數,重新開始遊戲n main()n # 如果用戶點擊「結束遊戲」 n elif gameover_rect.left < pos[0] < gameover_rect.right and n gameover_rect.top < pos[1] < gameover_rect.bottom:n # 退出遊戲n pygame.quit()n sys.exit() nn # 繪製暫停按鈕n screen.blit(paused_image, paused_rect)nn # 切換圖片n if not(delay % 5):n switch_image = not switch_imagenn delay -= 1n if not delay:n delay = 100nn pygame.display.flip()n clock.tick(60)n nif __name__ == "__main__":n try:n main()n except SystemExit:n passn except:n traceback.print_exc()n pygame.quit()n input()n
最終代碼及相關資源鏈接:http://pan.baidu.com/s/1jIQnVIe 密碼:68yq
推薦閱讀:
※函數內部的變數在函數執行完後就銷毀,為什麼可變對象卻能保存上次調用時的結果呢??
※哪裡有免費的python3教程啊?最好是有例子的視頻教學
※這段python代碼的意思如何理解?
※python numpy 數組如何對每個元素進行操作?
※自學python遇到如下問題如何解決?(主要有關模塊安裝的問題)