pygame游戏--飞机大战(plane)_sed

 

游戏操作:
1.wsad或者方向键操作飞机
2.空格键放全屏炸弹

代码:

此代码分5个模块

pygame游戏--飞机大战(plane)_游戏_02

main.py

import pygame
import sys # 退出需要
import traceback # 为了更好地退出
from pygame.locals import * # 就直接用QUIT而不需要pygame.QUIT
from random import * # 生成随机数需要

"""自建模块"""
import myplane # 飞机模块
import bullet # 子弹模块
import enemy # 敌机模块
import supply # 补给模块

"""一些初始化"""
pygame.init() # 初始化
pygame.mixer.init() # 混音器初始化

"""一些设置"""
########################################################################################################################
# 颜色设置
BLACK = (0, 0, 0) # 黑色
WHITE = (255, 255, 255) # 白色
GREEN = (0, 255, 0) # 绿色
RED = (255, 0, 0) # 红色

# 窗口尺寸设置
bg_size = width, height = 480, 700 # 背景尺寸

# 音乐设置
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 += inc
########################################################################################################################


screen = pygame.display.set_mode(bg_size) # 创建窗口
pygame.display.set_caption("飞机大战") # 窗口名字
background = pygame.image.load("images/background.png").convert() # 加载背景图片


def main(): # 主函数
pygame.mixer.music.play(-1) # -1循环播放背景音乐
clock = pygame.time.Clock()

# 生成我方飞机
me = myplane.MyPlane(bg_size)

enemies = pygame.sprite.Group()
# 生成敌方小型飞机
small_enemies = pygame.sprite.Group()
add_small_enemies(small_enemies, enemies, 15) # 15个
# 生成敌方中型飞机
mid_enemies = pygame.sprite.Group()
add_mid_enemies(mid_enemies, enemies, 4) # 4个
# 生成敌方大型飞机
big_enemies = pygame.sprite.Group()
add_big_enemies(big_enemies, enemies, 2) # 2个

# 生成普通子弹
bullet1 = []
bullet1_index = 0
BULLET1_NUM = 4 # 子弹数量
for i in range(BULLET1_NUM):
bullet1.append(bullet.Bullet1(me.rect.midtop)) # 子弹放置飞机的顶部中央

# 生成超级子弹
bullet2 = []
bullet2_index = 0
BULLET2_NUM = 8 # 超级子弹数量,一列4个
for 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))) # 第二列

# 中弹图片索引
e1_destroy_index = 0
e2_destroy_index = 0
e3_destroy_index = 0
me_destroy_index = 0

# 统计得分
score = 0 # 初始化0分
score_font = pygame.font.Font("font/font.ttf", 36) # 字体,字号

# 标志是否暂停游戏
paused = False
pause_nor_image = pygame.image.load("images/pause_nor.png")\
.convert_alpha() # 暂停图片1
pause_pressed_image = pygame.image.load("images/pause_pressed.png")\
.convert_alpha() # 暂停图片1
resume_nor_image = pygame.image.load("images/resume_nor.png")\
.convert_alpha() # 非暂停图片1
resume_pressed_image = pygame.image.load("images/resume_pressed.png")\
.convert_alpha() # 非暂停图片2
paused_rect = pause_nor_image.get_rect() # 图片矩形
paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 # 图片矩形位置
paused_image = pause_nor_image # 初始化图片最初状态,为暂停图片1

# 设置难度级别
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 # 初始化3个全屏炸弹

# 每30秒发放一个补给包
bullet_supply = supply.Bullet_Supply(bg_size) # 超级子弹补给
bomb_supply = supply.Bomb_Supply(bg_size) # 全屏炸弹补给
SUPPLY_TIME = USEREVENT # 自定义事件1
pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) # 定时器30秒,30×1000毫秒

# 超级子弹定时器
DOUBLE_BULLET_TIME = USEREVENT + 1 # 自定义事件2

# 标志是否使用超级子弹
is_double_bullet = False

# 解除我方无敌状态定时器
INVINCIBLE_TIME = USEREVENT + 2 # 自定义事件3

# 生命数量
life_image = pygame.image.load("images/life.png")\
.convert_alpha() # 生命的图片,小飞机表示生命
life_rect = life_image.get_rect() # 图片矩形
life_num = 3 # 初始化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 = 100

running = True # 这个就没改过

while 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): # 1是左键,鼠标在按钮上且点击了左键
paused = not paused # 暂停不暂停相互切换
if paused: # 如果暂停
pygame.time.set_timer(SUPPLY_TIME, 0) # 暂停供给
pygame.mixer.music.pause() # 暂停音乐
pygame.mixer.pause() # 暂停混音器
else: # 如果不暂停
pygame.time.set_timer(SUPPLY_TIME, 30*1000) # 30秒一个供给
pygame.mixer.music.unpause() # 不暂停音乐
pygame.mixer.unpause() # 不暂停混音器

elif event.type == MOUSEMOTION: # 鼠标有移动
if paused_rect.collidepoint(event.pos): # 鼠标位置在图片上
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else: # 鼠标没在图片上,显示浅色的方案
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image

elif event.type == KEYDOWN: # 如果有按键
if event.key == K_SPACE: # 按下的是空格键
if bomb_num: # 如果还有全屏炸弹
bomb_num -= 1 # 剩余全屏炸弹数量-1
bomb_sound.play() # 炸弹播放音效
for each in enemies: # 遍历敌人
if each.rect.bottom > 0: # 如果有敌人在屏幕内
each.active = False # 毁灭它们

elif 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 = False # 改为False
pygame.time.set_timer(DOUBLE_BULLET_TIME, 0) # 取消计时器

elif event.type == INVINCIBLE_TIME: # 如果是无敌状态
me.invincible = False # 改False
pygame.time.set_timer(INVINCIBLE_TIME, 0) # 取消计时器

# 升级提升游戏难度
########################################################################################################################
# 根据用户的得分增加难度
if level == 1 and score > 50000:
level = 2
upgrade_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 = 3
upgrade_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(big_enemies, 1)

elif level == 3 and score > 600000:
level = 4
upgrade_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(big_enemies, 1)

elif level == 4 and score > 1000000:
level = 5
upgrade_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(big_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: # 如果现存全屏炸弹数量 < 3
bomb_num += 1 # 全屏炸弹+1
bomb_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 = True # 超级子弹现在为活跃状态
pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000) # 18秒状态的定时器
bullet_supply.active = False # 供给状态改为非活跃

# 子弹
########################################################################################################################
# 发射子弹
if not(delay % 10): # 被10整除
bullet_sound.play()
if is_double_bullet:
bullets = bullet2
bullets[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_NUM

else:
bullets = bullet1
bullets[bullet1_index].reset(me.rect.midtop) # 复位子弹
bullet1_index = (bullet1_index + 1) % BULLET1_NUM # 索引+1

# 检测子弹是否击中敌机
for b in bullets: # 遍历子弹
if b.active: # 如果活跃为True
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 = False # 子弹活跃False
for e in enemy_hit: # 遍历碰撞
if e in mid_enemies or e in big_enemies: # 如果碰撞大型敌机或者中型敌机
e.hit = True # 击中为True
e.energy -= 1 # 血量-1
if e.energy == 0: # 当血量为0
e.active = False # 敌机活跃改为False
else: # 如果是小型飞机
e.active = False # 敌机活跃改为False
########################################################################################################################

# 绘制大型敌机
########################################################################################################################
for each in big_enemies: # 遍历大型敌机
if each.active: # 如果敌机活跃为True
each.move() # 移动敌机
if each.hit: # 如果敌机被击中
# 绘制被打到的特效
screen.blit(each.image_hit, each.rect) # 绘制击中的效果图像
each.hit = False # 击中改为False
else: # 如果没有被击中,正常情况下
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.energy
if energy_remain > 0.2:
energy_color = GREEN
else:
energy_color = RED
pygame.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: # 大型敌机距离上边界50
enemy3_fly_sound.play(-1) # 循环播放大型敌机的音效
else: # 如果大型敌机为非活跃状态
# 毁灭
if not (delay % 3): # 被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) % 6 # 图片索引+1
if e3_destroy_index == 0: # 播放完
enemy3_fly_sound.stop() # 大型敌机被击落的音效暂停
score += 10000
each.reset() # 敌机重置复位
########################################################################################################################

# 绘制中型敌机
########################################################################################################################
for each in mid_enemies: # 遍历中型敌机
if each.active: # 如果中型敌机活跃为True
each.move() # 移动中型敌机

if each.hit: # 如果被击中
screen.blit(each.image_hit, each.rect) # 绘制被击中效果图像
each.hit = False # 被击中改为False,就是不在绘制被击中的效果图像
else: # 没有被击中
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.energy
if energy_remain > 0.2:
energy_color = GREEN
else:
energy_color = RED
pygame.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): # 被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) % 4 # 索引+1
if e2_destroy_index == 0: # 播放完
score += 6000
each.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) % 4 # 索引+1
if e1_destroy_index == 0: # 播放完
score += 1000
each.reset() # 复位
########################################################################################################################

########################################################################################################################
# 检测我飞机是否被撞
enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
if enemies_down and not me.invincible: # 如果被撞
# 这里可以改无敌
me.active = False # 飞机活跃状态改为False
for e in enemies_down: # 遍历被撞的敌机
e.active = False # 敌机状态也改为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) % 4 # 索引+1
if me_destroy_index == 0: # 播放完
life_num -= 1
me.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 // 3
screen.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 + 10
screen.blit(gameover_text2, gameover_text2_rect)

again_rect.left, again_rect.top = \
(width - again_rect.width) // 2, gameover_text2_rect.bottom + 50
screen.blit(again_image, again_rect)

gameover_rect.left, gameover_rect.top = \
(width - again_rect.width) // 2, again_rect.bottom + 10
screen.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)
########################################################################################################################

# 切换图片,5帧切换一次
if not(delay % 5): # 被5整除
switch_image = not switch_image # 切换图片

delay -= 1 # 递减
if not delay:
delay = 100

pygame.display.flip()

clock.tick(60) # 一秒钟60次


# 运行
########################################################################################################################
if __name__ == "__main__":
try:
main()
except SystemExit: # 这是按下 × 的异常,直接忽略
pass
except:
traceback.print_exc()
pygame.quit()
input()
########################################################################################################################



myplane.py

import pygame


class MyPlane(pygame.sprite.Sprite): # 继承动画精灵类
def __init__(self, bg_size):
pygame.sprite.Sprite.__init__(self) # 初始化动画精灵

self.image1 = pygame.image.load("images/me1.png").convert_alpha() # 飞机图片1
self.image2 = pygame.image.load("images/me2.png").convert_alpha() # 飞机图片2
self.destroy_images = []
self.destroy_images.extend([
pygame.image.load("images/me_destroy_1.png").convert_alpha(), # 飞机被撞图片1
pygame.image.load("images/me_destroy_2.png").convert_alpha(), # 飞机被撞图片2
pygame.image.load("images/me_destroy_3.png").convert_alpha(), # 飞机被撞图片3
pygame.image.load("images/me_destroy_4.png").convert_alpha() # 飞机被撞图片4
])
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 - 60 # 使飞机在正下方
self.speed = 10 # 飞机速度为10
self.active = True
self.invincible = False # 无敌
self.mask = pygame.mask.from_surface(self.image1) # 标记飞机非透明部分

def moveUp(self): # 向上移动的方法
if self.rect.top > 0: # 飞机矩形坐标上边界 > 0
self.rect.top -= self.speed # 坐标数值变小,即向上移动
else: # 到屏幕顶端
self.rect.top = 0 # 保证飞机不出屏幕

def moveDown(self): # 向下移动的方法
if self.rect.bottom < self.height - 60:
self.rect.top += self.speed
else:
self.rect.bottom = self.height - 60

def moveLeft(self):
if self.rect.left > 0:
self.rect.left -= self.speed
else:
self.rect.left = 0

def moveRight(self):
if self.rect.right < self.width:
self.rect.left += self.speed
else:
self.rect.right = self.width

def reset(self):
self.rect.left, self.rect.top = \
(self.width - self.rect.width) // 2, \
self.height - self.rect.height - 60
self.active = True
self.invincible = True



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(), # 小型敌机被击落图片1
pygame.image.load("images/enemy1_down2.png").convert_alpha(), # 小型敌机被击落图片2
pygame.image.load("images/enemy1_down3.png").convert_alpha(), # 小型敌机被击落图片3
pygame.image.load("images/enemy1_down4.png").convert_alpha() # 小型敌机被击落图片4
])
self.rect = self.image.get_rect() # 小型敌机矩形位置
self.width, self.height = bg_size[0], bg_size[1] # 屏幕宽,高
self.speed = 2 # 小型敌机速度为2
self.active = True # 初始化在动
self.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.speed
else: # 出了屏幕下边界
self.reset() # 重置

def reset(self): # 重置的方法
self.active = True # 重置在动
self.rect.left, self.rect.top = \
randint(0, self.width - self.rect.width), \
randint(-5 * self.height, 0) # 重新随机在屏幕上边界外面生成


class MidEnemy(pygame.sprite.Sprite): # 中型敌机类,继承动画精灵类
energy = 8 # 中型敌机的血量8

def __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(), # 中型敌机被击落的图片1
pygame.image.load("images/enemy2_down2.png").convert_alpha(), # 中型敌机被击落的图片2
pygame.image.load("images/enemy2_down3.png").convert_alpha(), # 中型敌机被击落的图片3
pygame.image.load("images/enemy2_down4.png").convert_alpha() # 中型敌机被击落的图片4
])
self.rect = self.image.get_rect() # 中型敌机矩形位置
self.width, self.height = bg_size[0], bg_size[1] # 窗口的宽,高
self.speed = 1 # 中型敌机移动速度
self.active = True # 初始化在动
self.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.energy # 中型敌机的血量为8
self.hit = False # 初始化没击中

"""中型敌机移动的方法,只能向下,处理屏幕就重置复位"""
def move(self): # 移动的方法,只能向下
if self.rect.top < self.height:
self.rect.top += self.speed
else: # 出了屏幕底端
self.reset() # 重置

""""重置的方法"""
def reset(self): # 重置的方法
self.active = True # 重置在动
self.energy = MidEnemy.energy # 重置血量8
self.rect.left, self.rect.top = \
randint(0, self.width - self.rect.width), \
randint(-10 * self.height, -self.height) # 重新随机在屏幕上边界外面生成


class BigEnemy(pygame.sprite.Sprite): # 大型敌机类,继承动画精灵类
energy = 20 # 大型敌机血量20

def __init__(self, bg_size):
pygame.sprite.Sprite.__init__(self) # 初始化动画精灵

self.image1 = pygame.image.load("images/enemy3_n1.png")\
.convert_alpha() # 大型敌机图片1
self.image2 = pygame.image.load("images/enemy3_n2.png")\
.convert_alpha() # 大型敌机图片2
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(), # 大型敌机被击落图片1
pygame.image.load("images/enemy3_down2.png").convert_alpha(), # 大型敌机被击落图片2
pygame.image.load("images/enemy3_down3.png").convert_alpha(), # 大型敌机被击落图片3
pygame.image.load("images/enemy3_down4.png").convert_alpha(), # 大型敌机被击落图片4
pygame.image.load("images/enemy3_down5.png").convert_alpha(), # 大型敌机被击落图片5
pygame.image.load("images/enemy3_down6.png").convert_alpha() # 大型敌机被击落图片6
])
self.rect = self.image1.get_rect() # 大型敌机矩形位置
self.width, self.height = bg_size[0], bg_size[1] # 屏幕宽,高
self.speed = 1 # 大型敌机速度为1
self.active = True # 初始化在动
self.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.energy # 大型敌机血量20
self.hit = False # 初始化没击中

def move(self): # 移动的方法,只能向下移动
if self.rect.top < self.height:
self.rect.top += self.speed
else: # 出了屏幕下边界
self.reset() # 重置

def reset(self): # 重置的方法
self.active = True # 重置在动
self.energy = BigEnemy.energy # 重置血量
self.rect.left, self.rect.top = \
randint(0, self.width - self.rect.width), \
randint(-15 * self.height, -5 * self.height) # 重置位置,在屏幕上边界外面



bullet.py

import pygame


class 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 = position # 子弹图片矩形位置在哪里
self.speed = 12 # 子弹速度
self.active = False # 初始化子弹在动
self.mask = pygame.mask.from_surface(self.image) # 标记子弹图片非透明部分

def move(self): # 子弹移动的方法,只能向上移动
self.rect.top -= self.speed

if self.rect.top < 0: # 子弹到达上边界
self.active = False # 子弹不动

def reset(self, position): # 重置的方法
self.rect.left, self.rect.top = position # 重置位置
self.active = True # 重置在动


class 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 = position # 子弹图片矩形位置在哪里
self.speed = 14 # 子弹速度
self.active = False # 初始化子弹在动
self.mask = pygame.mask.from_surface(self.image) # 标记子弹图片非透明部分

def move(self): # 子弹移动的方法,只能向上移动
self.rect.top -= self.speed

if self.rect.top < 0: # 子弹到达上边界
self.active = False # 子弹不动

def reset(self, position): # 重置的方法
self.rect.left, self.rect.top = position # 重置位置
self.active = True



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), -100
self.speed = 5
self.active = False
self.mask = pygame.mask.from_surface(self.image)

def move(self):
if self.rect.top < self.height:
self.rect.top += self.speed
else:
self.active = False

def reset(self):
self.active = True
self.rect.left, self.rect.bottom = \
randint(0, self.width - self.rect.width), -100


class 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), -100
self.speed = 5
self.active = False
self.mask = pygame.mask.from_surface(self.image)

def move(self):
if self.rect.top < self.height:
self.rect.top += self.speed
else:
self.active = False

def reset(self):
self.active = True
self.rect.left, self.rect.bottom = \
randint(0, self.width - self.rect.width), -100

素材:

pygame游戏--飞机大战(plane)_游戏_03