<>前言

大家之前用python编写过飞机大战的部分代码,只能够展示英雄飞机,背景,敌机和发射子弹,今天把背景音乐,击毁敌机,爆

炸特效,得分等等相关功能一并加入进来,代码有点长,三百多行,你们要的代码来了哦?

<>编程思路

主要使用pygame库,类的创建,函数的调用等等来实现,话不多说,上程序。

<>编程实现
Python学习交流Q群:906715085#### import pygame # 导入动态模块(.dll .pyd .so) 不需要在包名后边跟模块名
from pygame.locals import * import time import random import sys #
定义常量(定义后,不再改值) WINDOW_HEIGHT = 768 WINDOW_WIDTH = 512 enemy_list = [] score = 0
is_restart= False class Map: def __init__(self, img_path, window): self.x = 0
self.bg_img1 = pygame.image.load(img_path) self.bg_img2 = pygame.image.load(
img_path) self.bg1_y = - WINDOW_HEIGHT self.bg2_y = 0 self.window = window def
move(self): # 当地图1的 y轴移动到0,则重置 if self.bg1_y >= 0: self.bg1_y = - WINDOW_HEIGHT
# 当地图2的 y轴移动到 窗口底部,则重置 if self.bg2_y >= WINDOW_HEIGHT: self.bg2_y = 0 #
每次循环都移动1个像素 self.bg1_y += 3 self.bg2_y += 3 def display(self): """贴图""" self.
window.blit(self.bg_img1, (self.x, self.bg1_y)) self.window.blit(self.bg_img2, (
self.x, self.bg2_y)) class HeroBullet: """英雄子弹类""" def __init__(self, img_path,
x, y, window): self.img = pygame.image.load(img_path) self.x = x self.y = y self
.window = window def display(self): self.window.blit(self.img, (self.x, self.y))
def move(self): """子弹向上飞行距离""" self.y -= 6 def is_hit_enemy(self, enemy): if
pygame.Rect.colliderect( pygame.Rect(self.x, self.y, 20, 31), pygame.Rect(enemy.
x, enemy.y, 100, 68) ): # 判断是否交叉 return True else: return False class EnemyPlane
: """敌人飞机类""" def __init__(self, img_path, x, y, window): self.img = pygame.
image.load(img_path) # 图片对象 self.x = x # 飞机坐标 self.y = y self.window = window #
飞机所在的窗口 self.is_hited = False self.anim_index = 0 self.hit_sound = pygame.mixer.
Sound("E:/飞机大战/baozha.ogg") def move(self): self.y += 10 # 到达窗口下边界,回到顶部 if self.
y>= WINDOW_HEIGHT: self.x = random.randint(0, random.randint(0, WINDOW_WIDTH -
100)) self.y = 0 def plane_down_anim(self): """敌机被击中动画""" if self.anim_index >=
21: # 动画执行完 self.anim_index = 0 self.img = pygame.image.load(
"E:/飞机大战/img-plane_%d.png" % random.randint(1, 7)) self.x = random.randint(0,
WINDOW_WIDTH- 100) self.y = 0 self.is_hited = False return elif self.anim_index
== 0: self.hit_sound.play() self.img = pygame.image.load( "E:/飞机大战/bomb-%d.png"
% (self.anim_index // 3 + 1)) self.anim_index += 1 def display(self): """贴图"""
if self.is_hited: self.plane_down_anim() self.window.blit(self.img, (self.x,
self.y)) class HeroPlane: def __init__(self, img_path, x, y, window): self.img =
pygame.image.load(img_path) # 图片对象 self.x = x # 飞机坐标 self.y = y self.window =
window# 飞机所在的窗口 self.bullets = [] # 记录该飞机发出的所有子弹 self.is_hited = False self.
is_anim_down= False self.anim_index = 0 def is_hit_enemy(self, enemy): if pygame
.Rect.colliderect( pygame.Rect(self.x, self.y, 120, 78), pygame.Rect(enemy.x,
enemy.y, 100, 68) ): # 判断是否交叉 return True else: return False def plane_down_anim
(self): """敌机被击中动画""" if self.anim_index >= 21: # 动画执行完 self.is_hited = False
self.is_anim_down = True return self.img = pygame.image.load(
"E:/飞机大战/bomb-%d.png" % (self.anim_index // 3 + 1)) self.anim_index += 1 def
display(self): """贴图""" for enemy in enemy_list: if self.is_hit_enemy(enemy):
enemy.is_hited = True self.is_hited = True self.plane_down_anim() break self.
window.blit(self.img, (self.x, self.y)) def display_bullets(self): # 贴子弹图
deleted_bullets= [] for bullet in self.bullets: # 判断 子弹是否超出 上边界 if bullet.y >= -
31: # 没有出边界 bullet.display() bullet.move() else: # 飞出边界 deleted_bullets.append(
bullet) for enemy in enemy_list: if bullet.is_hit_enemy(enemy): # 判断是否击中敌机 enemy
.is_hited = True deleted_bullets.append(bullet) global score score += 10 break
for out_window_bullet in deleted_bullets: self.bullets.remove(out_window_bullet)
def move_left(self): """往左飞""" if self.x >= 0 and not self.is_hited: self.x -=
10 def move_right(self): """往右飞""" if self.x <= WINDOW_WIDTH - 120 and not self.
is_hited: self.x += 10 def move_up(self): """往上飞""" if self.y >= 0 and not self.
is_hited: self.y -= 5 def move_down(self): """往下飞""" if self.y <= WINDOW_HEIGHT
- 78 and not self.is_hited: self.y += 5 def fire(self): """发射子弹""" # 创建子弹对象 子弹x
= 飞机x + 飞机宽度的一半 - 子弹宽度的一半 bullet = HeroBullet("E:/飞机大战/bullet_17.png", self.x +
60 - 10, self.y - 31, self.window) # 显示子弹(贴子弹图) bullet.display() self.bullets.
append(bullet) # 为了避免子弹对象被释放(只有局部变量引用对象,方法一执行完就会释放) class Game: def __init__(
self): pygame.init() # 设置标题 pygame.display.set_caption("飞机大战 v1.0") # 设置图标
game_ico= pygame.image.load("E:/飞机大战/app.ico") pygame.display.set_icon(game_ico)
pygame.mixer.music.load("E:/飞机大战/bg2.ogg") # 游戏结束的音效(超级玛丽) self.gameover_sound
= pygame.mixer.Sound("E:/飞机大战/gameover.wav") # 循环播放背景音乐 pygame.mixer.music.play(
-1) # 创建窗口 set_mode((窗口尺寸)) self.window = pygame.display.set_mode((WINDOW_WIDTH,
WINDOW_HEIGHT)) # 创建地图对象 self.game_map = Map("E:/飞机大战/img_bg_level_%d.jpg" %
random.randint(1, 5), self.window) # 创建对象 self.hero_plane = HeroPlane(
"E:/飞机大战/hero2.png", 240, 500, self.window) enemy_plane1 = EnemyPlane(
"E:/飞机大战/img-plane_%d.png" % random.randint( 1, 7), random.randint(0,
WINDOW_WIDTH- 100), 0, self.window) enemy_plane2 = EnemyPlane(
"E:/飞机大战/img-plane_%d.png" % random.randint(1, 7), random.randint(0,
WINDOW_WIDTH- 100), random.randint(-150, -68), self.window) enemy_plane3 =
EnemyPlane("E:/飞机大战/img-plane_%d.png" % random.randint(1, 7), random.randint(0,
WINDOW_WIDTH- 100), random.randint(-300, -140), self.window) enemy_list.append(
enemy_plane1) enemy_list.append(enemy_plane2) enemy_list.append(enemy_plane3)
self.enemy_list = enemy_list # 创建文字对象 # self.score_font =
pygame.font.SysFont("simhei", 40) self.score_font = pygame.font.Font(
"E:/飞机大战/SIMHEI.TTF", 40) def draw_text(self, content, size, x, y): # font_obj
= pygame.font.SysFont("simhei", size) font_obj = pygame.font.Font(
"E:/飞机大战/SIMHEI.TTF", size) text = font_obj.render(content, 1, (255, 255, 255))
self.window.blit(text, (x, y)) def wait_game_input(self): while True: for event
in pygame.event.get(): if event.type == QUIT: sys.exit() pygame.quit() elif
event.type == KEYDOWN: if event.key == K_ESCAPE: sys.exit() pygame.quit() elif
event.key == K_RETURN: global is_restart, score is_restart = True score = 0
return def game_start(self): # 贴背景图片 self.game_map.display() self.draw_text(
"飞机大战", 40, WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 3) self.draw_text(
"按Enter开始游戏, Esc退出游戏.", 28, WINDOW_WIDTH /3 - 140, WINDOW_HEIGHT /2) pygame.
display.update() self.wait_game_input() def game_over(self): # 先停止背景音乐 pygame.
mixer.music.stop() # 再播放音效 self.gameover_sound.play() # 贴背景图片 self.game_map.
display() self.draw_text("战机被击落,得分为 %d" % score, 28, WINDOW_WIDTH / 3 - 100,
WINDOW_HEIGHT/ 3) self.draw_text("按Enter重新开始, Esc退出游戏.", 28, WINDOW_WIDTH / 3 -
140, WINDOW_HEIGHT / 2) pygame.display.update() self.wait_game_input() self.
gameover_sound.stop() def key_control(self): # 获取事件,比如按键等 先显示界面,再根据获取的事件,修改界面效果
for event in pygame.event.get(): # 判断是否是点击了退出按钮 if event.type == QUIT: sys.exit(
) # 让程序终止 pygame.quit() # 判断是否是按下了键 elif event.type == KEYDOWN: # 检测按键是否是空格键 if
event.key == K_SPACE: self.hero_plane.fire() # 获取连续按下的情况 pressed_keys = pygame.
key.get_pressed() if pressed_keys[pygame.K_LEFT]: self.hero_plane.move_left() if
pressed_keys[pygame.K_RIGHT]: self.hero_plane.move_right() if pressed_keys[
pygame.K_UP]: self.hero_plane.move_up() if pressed_keys[pygame.K_DOWN]: self.
hero_plane.move_down() def display(self): # 贴背景图 self.game_map.display() self.
game_map.move() # 贴飞机图 self.hero_plane.display() self.hero_plane.display_bullets
() # 贴敌机图 for enemy in enemy_list: enemy.display() # 让敌机移动 if not enemy.is_hited
: enemy.move() # 贴得分文字 score_text = self.score_font.render("得分:%d" % score, 1, (
255, 255, 255)) self.window.blit(score_text, (10, 10)) # 刷新界面 不刷新不会更新显示的内容
pygame.display.update() def run(self): if is_restart == False: self.game_start()
while True: # 显示界面 self.display() if self.hero_plane.is_anim_down: self.
hero_plane.is_anim_down = False global enemy_list enemy_list = [] break # 键盘控制
self.key_control() # 每次循环,让程序休眠一会儿 time.sleep(0.01) self.game_over() def main():
"""主函数 一般将程序的入口""" # 运行游戏 while True: # 创建游戏对象 game = Game() game.run() if
__name__== '__main__': # 判断是否主动执行该文件 main() import pygame # 导入动态模块(.dll .pyd
.so) 不需要在包名后边跟模块名 from pygame.locals import * import time import random import
sys# 定义常量(定义后,不再改值) WINDOW_HEIGHT = 768 WINDOW_WIDTH = 512 enemy_list = [] score
= 0 is_restart = False class Map: def __init__(self, img_path, window): self.x =
0 self.bg_img1 = pygame.image.load(img_path) self.bg_img2 = pygame.image.load(
img_path) self.bg1_y = - WINDOW_HEIGHT self.bg2_y = 0 self.window = window def
move(self): # 当地图1的 y轴移动到0,则重置 if self.bg1_y >= 0: self.bg1_y = - WINDOW_HEIGHT
# 当地图2的 y轴移动到 窗口底部,则重置 if self.bg2_y >= WINDOW_HEIGHT: self.bg2_y = 0 #
每次循环都移动1个像素 self.bg1_y += 3 self.bg2_y += 3 def display(self): """贴图""" self.
window.blit(self.bg_img1, (self.x, self.bg1_y)) self.window.blit(self.bg_img2, (
self.x, self.bg2_y)) class HeroBullet: """英雄子弹类""" def __init__(self, img_path,
x, y, window): self.img = pygame.image.load(img_path) self.x = x self.y = y self
.window = window def display(self): self.window.blit(self.img, (self.x, self.y))
def move(self): """子弹向上飞行距离""" self.y -= 6 def is_hit_enemy(self, enemy): if
pygame.Rect.colliderect( pygame.Rect(self.x, self.y, 20, 31), pygame.Rect(enemy.
x, enemy.y, 100, 68) ): # 判断是否交叉 return True else: return False class EnemyPlane
: """敌人飞机类""" def __init__(self, img_path, x, y, window): self.img = pygame.
image.load(img_path) # 图片对象 self.x = x # 飞机坐标 self.y = y self.window = window #
飞机所在的窗口 self.is_hited = False self.anim_index = 0 self.hit_sound = pygame.mixer.
Sound("E:/飞机大战/baozha.ogg") def move(self): self.y += 10 # 到达窗口下边界,回到顶部 if self.
y>= WINDOW_HEIGHT: self.x = random.randint(0, random.randint(0, WINDOW_WIDTH -
100)) self.y = 0 def plane_down_anim(self): """敌机被击中动画""" if self.anim_index >=
21: # 动画执行完 self.anim_index = 0 self.img = pygame.image.load(
"E:/飞机大战/img-plane_%d.png" % random.randint(1, 7)) self.x = random.randint(0,
WINDOW_WIDTH- 100) self.y = 0 self.is_hited = False return elif self.anim_index
== 0: self.hit_sound.play() self.img = pygame.image.load( "E:/飞机大战/bomb-%d.png"
% (self.anim_index // 3 + 1)) self.anim_index += 1 def display(self): """贴图"""
if self.is_hited: self.plane_down_anim() self.window.blit(self.img, (self.x,
self.y)) class HeroPlane: def __init__(self, img_path, x, y, window): self.img =
pygame.image.load(img_path) # 图片对象 self.x = x # 飞机坐标 self.y = y self.window =
window# 飞机所在的窗口 self.bullets = [] # 记录该飞机发出的所有子弹 self.is_hited = False self.
is_anim_down= False self.anim_index = 0 def is_hit_enemy(self, enemy): if pygame
.Rect.colliderect( pygame.Rect(self.x, self.y, 120, 78), pygame.Rect(enemy.x,
enemy.y, 100, 68) ): # 判断是否交叉 return True else: return False def plane_down_anim
(self): """敌机被击中动画""" if self.anim_index >= 21: # 动画执行完 self.is_hited = False
self.is_anim_down = True return self.img = pygame.image.load(
"E:/飞机大战/bomb-%d.png" % (self.anim_index // 3 + 1)) self.anim_index += 1 def
display(self): """贴图""" for enemy in enemy_list: if self.is_hit_enemy(enemy):
enemy.is_hited = True self.is_hited = True self.plane_down_anim() break self.
window.blit(self.img, (self.x, self.y)) def display_bullets(self): # 贴子弹图
deleted_bullets= [] for bullet in self.bullets: # 判断 子弹是否超出 上边界 if bullet.y >= -
31: # 没有出边界 bullet.display() bullet.move() else: # 飞出边界 deleted_bullets.append(
bullet) for enemy in enemy_list: if bullet.is_hit_enemy(enemy): # 判断是否击中敌机 enemy
.is_hited = True deleted_bullets.append(bullet) global score score += 10 break
for out_window_bullet in deleted_bullets: self.bullets.remove(out_window_bullet)
def move_left(self): """往左飞""" if self.x >= 0 and not self.is_hited: self.x -=
10 def move_right(self): """往右飞""" if self.x <= WINDOW_WIDTH - 120 and not self.
is_hited: self.x += 10 def move_up(self): """往上飞""" if self.y >= 0 and not self.
is_hited: self.y -= 5 def move_down(self): """往下飞""" if self.y <= WINDOW_HEIGHT
- 78 and not self.is_hited: self.y += 5 def fire(self): """发射子弹""" # 创建子弹对象 子弹x
= 飞机x + 飞机宽度的一半 - 子弹宽度的一半 bullet = HeroBullet("E:/飞机大战/bullet_17.png", self.x +
60 - 10, self.y - 31, self.window) # 显示子弹(贴子弹图) bullet.display() self.bullets.
append(bullet) # 为了避免子弹对象被释放(只有局部变量引用对象,方法一执行完就会释放) class Game: def __init__(
self): pygame.init() # 设置标题 pygame.display.set_caption("飞机大战 v1.0") # 设置图标
game_ico= pygame.image.load("E:/飞机大战/app.ico") pygame.display.set_icon(game_ico)
pygame.mixer.music.load("E:/飞机大战/bg2.ogg") # 游戏结束的音效(超级玛丽) self.gameover_sound
= pygame.mixer.Sound("E:/飞机大战/gameover.wav") # 循环播放背景音乐 pygame.mixer.music.play(
-1) # 创建窗口 set_mode((窗口尺寸)) self.window = pygame.display.set_mode((WINDOW_WIDTH,
WINDOW_HEIGHT)) # 创建地图对象 self.game_map = Map("E:/飞机大战/img_bg_level_%d.jpg" %
random.randint(1, 5), self.window) # 创建对象 self.hero_plane = HeroPlane(
"E:/飞机大战/hero2.png", 240, 500, self.window) enemy_plane1 = EnemyPlane(
"E:/飞机大战/img-plane_%d.png" % random.randint( 1, 7), random.randint(0,
WINDOW_WIDTH- 100), 0, self.window) enemy_plane2 = EnemyPlane(
"E:/飞机大战/img-plane_%d.png" % random.randint(1, 7), random.randint(0,
WINDOW_WIDTH- 100), random.randint(-150, -68), self.window) enemy_plane3 =
EnemyPlane("E:/飞机大战/img-plane_%d.png" % random.randint(1, 7), random.randint(0,
WINDOW_WIDTH- 100), random.randint(-300, -140), self.window) enemy_list.append(
enemy_plane1) enemy_list.append(enemy_plane2) enemy_list.append(enemy_plane3)
self.enemy_list = enemy_list # 创建文字对象 # self.score_font =
pygame.font.SysFont("simhei", 40) self.score_font = pygame.font.Font(
"E:/飞机大战/SIMHEI.TTF", 40) def draw_text(self, content, size, x, y): # font_obj
= pygame.font.SysFont("simhei", size) font_obj = pygame.font.Font(
"E:/飞机大战/SIMHEI.TTF", size) text = font_obj.render(content, 1, (255, 255, 255))
self.window.blit(text, (x, y)) def wait_game_input(self): while True: for event
in pygame.event.get(): if event.type == QUIT: sys.exit() pygame.quit() elif
event.type == KEYDOWN: if event.key == K_ESCAPE: sys.exit() pygame.quit() elif
event.key == K_RETURN: global is_restart, score is_restart = True score = 0
return def game_start(self): # 贴背景图片 self.game_map.display() self.draw_text(
"飞机大战", 40, WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 3) self.draw_text(
"按Enter开始游戏, Esc退出游戏.", 28, WINDOW_WIDTH /3 - 140, WINDOW_HEIGHT /2) pygame.
display.update() self.wait_game_input() def game_over(self): # 先停止背景音乐 pygame.
mixer.music.stop() # 再播放音效 self.gameover_sound.play() # 贴背景图片 self.game_map.
display() self.draw_text("战机被击落,得分为 %d" % score, 28, WINDOW_WIDTH / 3 - 100,
WINDOW_HEIGHT/ 3) self.draw_text("按Enter重新开始, Esc退出游戏.", 28, WINDOW_WIDTH / 3 -
140, WINDOW_HEIGHT / 2) pygame.display.update() self.wait_game_input() self.
gameover_sound.stop() def key_control(self): # 获取事件,比如按键等 先显示界面,再根据获取的事件,修改界面效果
for event in pygame.event.get(): # 判断是否是点击了退出按钮 if event.type == QUIT: sys.exit(
) # 让程序终止 pygame.quit() # 判断是否是按下了键 elif event.type == KEYDOWN: # 检测按键是否是空格键 if
event.key == K_SPACE: self.hero_plane.fire() # 获取连续按下的情况 pressed_keys = pygame.
key.get_pressed() if pressed_keys[pygame.K_LEFT]: self.hero_plane.move_left() if
pressed_keys[pygame.K_RIGHT]: self.hero_plane.move_right() if pressed_keys[
pygame.K_UP]: self.hero_plane.move_up() if pressed_keys[pygame.K_DOWN]: self.
hero_plane.move_down() def display(self): # 贴背景图 self.game_map.display() self.
game_map.move() # 贴飞机图 self.hero_plane.display() self.hero_plane.display_bullets
() # 贴敌机图 for enemy in enemy_list: enemy.display() # 让敌机移动 if not enemy.is_hited
: enemy.move() # 贴得分文字 score_text = self.score_font.render("得分:%d" % score, 1, (
255, 255, 255)) self.window.blit(score_text, (10, 10)) # 刷新界面 不刷新不会更新显示的内容
pygame.display.update() def run(self): if is_restart == False: self.game_start()
while True: # 显示界面 self.display() if self.hero_plane.is_anim_down: self.
hero_plane.is_anim_down = False global enemy_list enemy_list = [] break # 键盘控制
self.key_control() # 每次循环,让程序休眠一会儿 time.sleep(0.01) self.game_over() def main():
"""主函数 一般将程序的入口""" # 运行游戏 while True: # 创建游戏对象 game = Game() game.run() if
__name__== '__main__': # 判断是否主动执行该文件 main() #代码有点长,得使劲往下拉...
<>效果图

<>最后

今天给大家分享的飞机大战小游戏到这里就结束了,代码就放在上面吧,喜欢的小伙伴就拿去试试手吧。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信