欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

飞机大战内容讲解

程序员文章站 2022-06-22 23:21:26
大概内容首先,我们说了,飞机大战和植物大战僵尸差不多,有碰撞检测啊、音效播放啊、等等一些东西好,废话不多说,开始首先我们知道游戏代码较多,我在这里用小甲鱼的吧,打开首先,我们是没有下载pygame的。我们看到了,这里面有好多的import我们一个一个的看import random表示进口随机的意思random是随机的意思里边有好多执行语句,我就不一一讲解了代码from pygame.locals import *from random import *import traceba...

大概内容

首先,我们说了,飞机大战和植物大战僵尸差不多,有碰撞检测啊、音效播放啊、等等一些东西

好,废话不多说,开始

首先我们知道游戏代码较多,我在这里用小甲鱼的吧,打开

首先,我们是没有下载pygame的。

我们看到了,这里面有好多的import

我们一个一个的看

import random
表示进口随机的意思

random是随机的意思

里边有好多执行语句,我就不一一讲解了

代码

from pygame.locals import *
from random import *
import traceback
import tkinter as tk
import pygame
import math
import sys

"""\/\/\/\/\/\/\/\/------我的飞机类------\/\/\/\/\/\/\/\/"""
class MyPlane (pygame.sprite.Sprite):       #定义我的飞机类,继承动画精灵类(因为之后要进行碰撞检测)
    def __init__(self,bg_size,me1_image,me2_image) :
        pygame.sprite.Sprite.__init__(self)
        self.me1_image = me1_image
        self.me2_image = me2_image
        self.image1 = pygame.image.load(me1_image).convert_alpha()  #第一张飞机图片
        self.image2 = pygame.image.load(me2_image).convert_alpha()  #第二张飞机图片 两张图片是为了做出飞机喷气的效果
        #添加坠机图片
        self.destroy_images = []
        self.me_destory_1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_1.png").convert_alpha()    #自身飞机炸毁第1张图片
        self.me_destory_2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_2.png").convert_alpha()    #自身飞机炸毁第2张图片
        self.me_destory_3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_3.png").convert_alpha()    #自身飞机炸毁第3张图片
        self.me_destory_4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_4.png" ).convert_alpha()   #自身飞机炸毁第4张图片
        self.destroy_images.extend([self.me_destory_1_image,self.me_destory_2_image,self.me_destory_3_image,self.me_destory_4_image])
        
        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.mask = pygame.mask.from_surface(self.image1)  #给类添加上mask属性,之后可以按照完美碰撞
        self.speed = 10 #设置飞机出现的速度
        self.active = True#设置飞机是否生存的状态
        self.invincible = True   #是否处于无敌状态

    def moveup(self):   #飞机向上飞的函数
        if self.rect.top > 0: #如果我方飞机没有飞出 上方边界
            self.rect.top -= 10 #那么我方飞机朝上飞10个像素
        else :  #飞出 上方边界
            self.rect.top = 0   #锁定在0的位置,不再发生变化
    
    def movedown(self):     #飞机向下飞的函数
        if self.rect.bottom < (self.height - 60) : #如果我方飞机没有飞出 上方边界
            self.rect.bottom += 10 #那么我方飞机朝下飞10个像素
        else :  #飞出 下方边界
            self.rect.bottom = (self.height - 60)  #锁定在底边界上方60的位置,不再发生变化

    
    def moveleft(self):     #飞机向左飞的函数
        if self.rect.left > 0 : #如果我方飞机没有飞出 左方边界
            self.rect.left -= 10 #那么我方飞机朝下左10个像素
        else :  #飞出 左方边界
            self.rect.left = 0  #锁定在左边界的位置,不再发生变化

    def moveright(self):     #飞机向下飞的函数
        if self.rect.right < self.width : #如果我方飞机没有飞出 上方边界
            self.rect.right += 10 #那么我方飞机朝下飞10个像素
        else :  #飞出 下方边界
            self.rect.right = self.width #锁定在底边界的位置,不再发生变化
    
    def reset(self):
        self.active = True#设置飞机是否生存的状态
        self.invincible = True   #重新设置飞机处于无敌状态
        self.rect.left , self.rect.top = [ (self.width - self.rect.width) // 2 ,  \
                                                     (self.height - self.rect.height - 60) ]  #设置我方飞机出现的位置



"""\/\/\/\/\/\/\/\/------敌机类------\/\/\/\/\/\/\/\/"""
"""本来这里其实可以使用类的继承,然后三种敌机分别继承这个敌机类生成新的敌机,但是在这里、
    没有这样做的必要,因为三个类的差别并不是很大,所以不用那么繁杂"""
class SmallEnemy(pygame.sprite.Sprite):  #定义我的低敌机类,继承自动画精灵
    def __init__(self,bg_size,enemy1_image):
        pygame.sprite.Sprite.__init__(self)

        self.enemy1_image = enemy1_image
        self.enemy1 = pygame.image.load(enemy1_image).convert_alpha()   #载入低级敌机照片
        #添加坠机图片
        self.destroy_images = []
        self.enemy1_down1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down1.png").convert_alpha()    #低级敌机撞到爆炸第1张图片
        self.enemy1_down2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down2.png").convert_alpha()      #低级敌机撞到爆炸第2张图片
        self.enemy1_down3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down3.png").convert_alpha()      #低级敌机撞到爆炸第3张图片
        self.enemy1_down4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down4.png").convert_alpha()      #低级敌机撞到爆炸第4张图片
        self.destroy_images.extend([self.enemy1_down1_image,self.enemy1_down2_image,self.enemy1_down3_image,self.enemy1_down4_image])
        
        self.width ,self.height = bg_size[0] , bg_size[1]   #获取生成低级敌机的活动范围
        self.rect = self.enemy1.get_rect()   #获得低级敌机的尺寸
        self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
                                                     randint(-5*self.height , 0) ]      #在窗口的5倍之上的距离中产生飞机

        self.mask = pygame.mask.from_surface(self.enemy1)  #给类添加上mask属性,之后可以按照完美碰撞
        self.speed = 3  #设置小敌机移动的速度
        self.active = True  #设置飞机是否生存的状态

    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) ]      #在窗口的5倍之上的距离中产生飞机

class MiddleEnemy(pygame.sprite.Sprite):  #定义我的中敌机类,继承自动画精灵
    energy = 8
    def __init__(self,bg_size,enemy2_image):
        pygame.sprite.Sprite.__init__(self)
        self.enemy2_image = enemy2_image
        self.enemy2 = pygame.image.load(enemy2_image).convert_alpha()   #载入中级敌机照片
        #添加坠机图片
        self.destroy_images = []
        self.enemy2_down1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down1.png").convert_alpha()    #中级敌机撞到爆炸第1张图片
        self.enemy2_down2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down2.png").convert_alpha()    #中级敌机撞到爆炸第2张图片
        self.enemy2_down3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down3.png").convert_alpha()    #中级敌机撞到爆炸第3张图片
        self.enemy2_down4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down4.png").convert_alpha()    #中级敌机撞到爆炸第4张图片
        self.enemy2_hit_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_hit.png").convert_alpha()   #中级敌机被子弹打到后图片
        self.destroy_images.extend([self.enemy2_down1_image,self.enemy2_down2_image,self.enemy2_down3_image,self.enemy2_down4_image])
        
        self.width ,self.height = bg_size[0] , bg_size[1]   #获取生成低级敌机的活动范围
        self.rect = self.enemy2.get_rect()   #获得中级敌机的尺寸
        self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
                                                     randint(-10*self.height , 0) ]      #在窗口的5倍之上的距离中产生飞机
        
        self.mask = pygame.mask.from_surface(self.enemy2)  #给类添加上mask属性,之后可以按照完美碰撞
        self.speed = 2  #设置中敌机移动的速度
        self.active = True  #设置飞机是否生存的状态
        self.energy = MiddleEnemy.energy    #设置敌机的生命值
        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.hit = False
        self.energy = 8
        self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
                                                     randint(-10*self.height , 0) ]      #在窗口的5倍之上的距离中产生飞机

class BigEnemy(pygame.sprite.Sprite):  #定义我的大敌机类,继承自动画精灵
    energy = 20

    def __init__(self,bg_size,enemy3_n1_image,enemy3_n2_image):
        pygame.sprite.Sprite.__init__(self)
        self.enemy3_n1_image = enemy3_n1_image
        self.enemy3_n1 = pygame.image.load(enemy3_n1_image).convert_alpha()   #载入高级敌机照片
        self.enemy3_n2_image = enemy3_n1_image
        self.enemy3_n2 = pygame.image.load(enemy3_n2_image).convert_alpha()   #载入高级敌机照片
        #添加坠机图片
        self.destroy_images = []
        self.enemy3_down1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down1.png").convert_alpha()    #高级敌机撞到爆炸第1张图片
        self.enemy3_down2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down2.png").convert_alpha()    #高级敌机撞到爆炸第2张图片
        self.enemy3_down3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down3.png").convert_alpha()    #高级敌机撞到爆炸第3张图片
        self.enemy3_down4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down4.png").convert_alpha()    #高级敌机撞到爆炸第4张图片
        self.enemy3_down5_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down5.png").convert_alpha()    #高级敌机撞到爆炸第5张图片
        self.enemy3_down6_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down6.png").convert_alpha()    #高级敌机撞到爆炸第6张图片
        self.enemy3_hit_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_hit.png").convert_alpha()  #高级敌机被子弹打到后图片
        self.destroy_images.extend([self.enemy3_down1_image,self.enemy3_down1_image,self.enemy3_down3_image,self.enemy3_down4_image,\
                                                self.enemy3_down5_image,self.enemy3_down6_image ])
        
        
        self.width ,self.height = bg_size[0] , bg_size[1]   #获取生成低级敌机的活动范围
        self.rect = self.enemy3_n1.get_rect()   #获得低级敌机的尺寸
        self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
                                                     randint(-15*self.height , 0) ]      #在窗口的5倍之上的距离中产生飞机
        
        self.mask = pygame.mask.from_surface(self.enemy3_n1)  #给类添加上mask属性,之后可以按照完美碰撞
        self.speed = 1  #设置大敌机移动的速度
        self.active = True#设置飞机是否生存的状态
        self.energy = BigEnemy.energy    #设置敌机的生命值
        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.hit = False
        self.energy = 20
        self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
                                                     randint(-15*self.height , 0) ]      #在窗口的5倍之上的距离中产生飞机

"""\/\/\/\/\/\/\/\/------子弹类------\/\/\/\/\/\/\/\/"""
class Bullet1 (pygame.sprite.Sprite):       #定义子弹类,继承动画精灵类(因为之后要进行碰撞检测)
    def __init__(self,bullet1_image,position) :
        pygame.sprite.Sprite.__init__(self)
        
        self.bullet1_image = bullet1_image  #子弹1图的路径
        self.image = pygame.image.load(bullet1_image).convert_alpha()   #加载子弹1图
        self.rect = self.image.get_rect()   #获得子弹1图的尺寸
        self.rect.left , self.rect.top = position   #把飞机的位置传给子弹
        self.speed = 12 #子弹运动的速度
        self.active = True  #用来表示这颗子弹是或否失效
        self.mask = pygame.mask.from_surface(self.image)  #给类添加上mask属性

    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,bullet2_image,position):
        pygame.sprite.Sprite.__init__(self)
 
        self.image = pygame.image.load(bullet2_image).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  

"""\/\/\/\/\/\/\/\/------补给类------\/\/\/\/\/\/\/\/"""
class Bullet_Supply(pygame.sprite.Sprite):
    def __init__(self,bg_size) :
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load( r"D:\Code\Python\Pygame\pygame11:飞机大战\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.top = 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.top = 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( r"D:\Code\Python\Pygame\pygame11:飞机大战\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.top = 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.top = randint(0,self.width-self.rect.width)  , -100
    
def main() :
    pygame.init()   #初始化
    pygame.mixer.init()     #混音器初始化

    clock = pygame.time.Clock()     #设置一个计时器

    transform = False   #设置一个是否改变的变量
    delay = 100 #类似于单片机,设置一个延时变量,让飞机的改变看起来更加的顺滑
    switch_image = True     # 用于切换图片
    running = True

    #创建字体的标志
    font = pygame.font.Font(r'D:\Code\Python\Pygame\font\font.ttf',35)
    #初始化分数
    score = 0
    score_font = pygame.font.Font(r"D:\Code\Python\Pygame\font\font.ttf", 36)
    #初始化我方飞机数量,生命为3条
    life_num = 3

    #设置难度等级
    level = 1

    black = ([0,0,0])   #黑色
    green = ([0,255,0])  #绿色
    red = ([255,0,0])   #红色
    white = ([255,255,255]) #白色

    """载入音乐文件"""
    #背景音乐
    pygame.mixer.music.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\game_music.ogg")  #设置背景音乐
    pygame.mixer.music.set_volume(1)  #设置音量

    #游戏音效
    bullet_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\bullet.wav")  #子弹特效
    bullet_sound.set_volume(0.5)
    button_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\button.wav")    #按键特效
    button_sound.set_volume(0.5)
    enemy1_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy1_down.wav")    #低等敌机被击毁音效
    enemy1_down_sound.set_volume(0.5)
    enemy2_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy2_down.wav")    #中等敌机被击毁音效
    enemy2_down_sound.set_volume(0.5)
    enemy3_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy3_down.wav")    #高等敌机被击毁音效
    enemy3_down_sound.set_volume(0.5)
    enemy3_fly_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy3_flying.wav")    #高等敌机出现音效
    enemy3_fly_sound.set_volume(0.5)
    get_bomb_sound = pygame.mixer.Sound(  r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\get_bomb.wav")    #获得全屏炸弹补给音效
    get_bomb_sound.set_volume(0.5)
    get_bullet_sound = pygame.mixer.Sound(  r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\get_bullet.wav")    #获得双倍子弹补给音效
    get_bullet_sound.set_volume(0.5)
    myself_down_sound = pygame.mixer.Sound(  r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\me_down.wav")    #自身飞机被击毁(死亡)音效
    myself_down_sound.set_volume(0.5)
    supply_sound = pygame.mixer.Sound(  r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\supply.wav")    #补给产生音效
    supply_sound.set_volume(0.5)
    upgrade_sound = pygame.mixer.Sound(  r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\upgrade.wav")    #升级音效
    upgrade_sound.set_volume(0.5)
    use_bomb_sound = pygame.mixer.Sound(  r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\use_bomb.wav")    #使用全屏炸弹音效
    use_bomb_sound.set_volume(0.5)

    """图片文件路径"""
  
    background_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\background.png"  #背景图的路径

    bullet1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bullet1.png" #第一种子弹图
    bullet2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bullet2.png" #第二种子弹图
    
    enemy1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1.png"  #低级敌机图片
    enemy2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2.png"  #中级敌机图片
    enemy3_n1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_n1.png"   #高级敌机图片1
    enemy3_n2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_n2.png"   #高级敌机图片2

    me1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me1.png" #自身飞机第一张图片
    me2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me2.png" #自身飞机第二张图片

    #设置背景
    bg_size = width , height = 430 , 700       #背景大小
    screen = pygame.display.set_mode(bg_size)   #这是背景大小
    background = pygame.image.load(background_image).convert_alpha()       #画背景
    pygame.mixer.music.set_volume(1)    #设置音量
    pygame.mixer.music.play(-1)     #播放背景音乐,-1 表示无限循环播放

    # 标志是否暂停游戏
    paused = False
    pause_nor_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\pause_nor.png" ).convert_alpha() #暂停的时候图片
    pause_pressed_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\pause_pressed.png"  ).convert_alpha() #暂停到继续的中间变换图
    resume_nor_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\resume_nor.png").convert_alpha()   #继续的时候的图片
    resume_pressed_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\resume_pressed.png"   ).convert_alpha()   #继续到暂停的中间变换图
    paused_rect = pause_nor_image.get_rect()
    paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
    paused_image = pause_nor_image

    #补给包
    bullet_supply = Bullet_Supply(bg_size)
    bomb_supply = Bomb_Supply(bg_size)
    supply_timer = USEREVENT 
    pygame.time.set_timer(supply_timer,30000)   #设定自定义事件每隔30s返回一个用户自定义事件属性

    #超级子弹定时器
    double_bullet_timer = USEREVENT + 1
    # 标志是否使用超级子弹
    is_double_bullet = False

    # 全屏炸弹
    bomb_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bomb.png").convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_font = pygame.font.Font(r"D:\Code\Python\Pygame\font\font.ttf", 48)

    bomb_num = 3
    #载入生命图片
    life_image =pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\life.png").convert_alpha()    #表示生命值的图片
    life_image_rect = life_image.get_rect()
    #中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    myself_destroy_index = 0

    #生成自己飞机
    myself = MyPlane(bg_size,me1_image,me2_image)    
    #无敌时间计时器
    myself_invincible_timer = USEREVENT + 2
    pygame.time.set_timer(myself_invincible_timer, 3*1000)  #3秒

    #创建子弹
    bullet1 = []    #创建一个子弹列表
    bullet1_index  = 0  #创建一个搜索子弹的下标
    bullet1_num = 4     #一次性创建子弹的数量
    for i in range (bullet1_num) :  #循环生成子弹
        bullet1.append(Bullet1(bullet1_image,myself.rect.midtop))     #使用子弹类生成子弹
    
    # 生成超级子弹
    bullet2 = []
    bullet2_index = 0
    bullet2_num = 8
    for i in range(bullet2_num//2):
        bullet2.append(Bullet2(bullet2_image,(myself.rect.centerx-33, myself.rect.centery)))
        bullet2.append(Bullet2(bullet2_image,(myself.rect.centerx+30, myself.rect.centery)))

    #生成敌机组
    def add_smallenemies(group1, group2, num):
        for i in range(num):
            e1 = SmallEnemy(bg_size,enemy1_image)
            group1.add(e1)
            group2.add(e1)

    def add_middleenemies(group1, group2, num):
        for i in range(num):
            e2 = MiddleEnemy(bg_size,enemy2_image)
            group1.add(e2)
            group2.add(e2)

    def add_bigenemies(group1, group2, num):
        for i in range(num):
            e3 = BigEnemy(bg_size,enemy3_n1_image,enemy3_n2_image)
            group1.add(e3)
            group2.add(e3)

    #提升所有飞机的速度
    def inc_speed(group,addspeed):
        for each in group :
            each.speed += addspeed

    #生成敌机组
    enemies = pygame.sprite.Group() #生成整个飞机组
    smallenemies = pygame.sprite.Group()    #生成小飞机组
    add_smallenemies(smallenemies,enemies,20)     #生成小型飞机
    middleenemies = pygame.sprite.Group()   #生成中飞机组
    add_middleenemies(middleenemies,enemies,10)     #生成中型飞机
    bigenemies = pygame.sprite.Group() #生成大飞机组
    add_bigenemies(bigenemies,enemies,4)     #生成大型飞机

    # 用于阻止重复打开记录文件
    recorded = False
 
    #结束的全部东西
    gameover_font = pygame.font.Font(r"D:\Code\Python\Pygame\font\font.ttf", 48)
    again_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\again.png" ).convert_alpha()
    again_rect = again_image.get_rect()
    gameover_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\gameover.png").convert_alpha()
    gameover_rect = gameover_image.get_rect()


    while running :
        for event in pygame.event.get() :
            if event.type == QUIT :
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN: 
                if event.button == 1 and paused_rect.collidepoint(event.pos):   #如果检测到鼠标在暂停位置按下点击按钮
                    paused = not paused #puase标志键变为True
                    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
                    screen.blit(paused_image,(width - paused_rect.width,5)) #绘制此时的暂停按钮
                    if paused : #如果暂停了
                        pygame.time.set_timer(supply_timer,0)
                        pygame.mixer.music.pause()
                        pygame.mixer.pause()
                    else :
                        pygame.time.set_timer(supply_timer,30000)
                        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 :   #如果还有超级炸弹,那么炸弹数量-1
                        bomb_num -= 1
                        use_bomb_sound.play()
                        for each in enemies:
                            if each.rect.bottom > 0:
                                each.active = False

                if event.key == K_0 :   #如果按下0键
                    bomb_num += 1

            elif event.type == supply_timer :   #响应补给包事件
                supply_sound.play() #播放补给的声音
                if choice([True,False]) :   #随机生成子弹补给或者炸药补给
                    bullet_supply.reset()
                else :
                    bomb_supply.reset()
                
            elif event.type == double_bullet_timer:     #响应超级子弹事件
                is_double_bullet = False
                pygame.time.set_timer(double_bullet_timer, 0)

            elif event.type == myself_invincible_timer: #响应无敌事件
                myself.invincible = False 

        # 根据用户的得分增加难度
        if level == 1 and score > 50000:
            level = 2
            upgrade_sound.play()
            # 增加3架小型敌机、2架中型敌机和1架大型敌机
            add_smallenemies(smallenemies, enemies, 3)
            add_middleenemies(middleenemies, enemies, 2)
            add_bigenemies(bigenemies, enemies, 1)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
        elif level == 2 and score > 300000:
            level = 3
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_smallenemies(smallenemies, enemies, 5)
            add_middleenemies(middleenemies, enemies, 3)
            add_bigenemies(bigenemies, enemies, 2)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
            inc_speed(middleenemies, 1)
        elif level == 3 and score > 600000:
            level = 4
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_smallenemies(smallenemies, enemies, 5)
            add_middleenemies(middleenemies, enemies, 3)
            add_bigenemies(bigenemies, enemies, 2)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
            inc_speed(middleenemies, 1)
        elif level == 4 and score > 1000000:
            level = 5
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_smallenemies(smallenemies, enemies, 5)
            add_middlenemies(middleenemies, enemies, 3)
            add_bigenemies(bigenemies, enemies, 2)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
            inc_speed(middleenemies, 1)        # 根据用户的得分增加难度
        if level == 1 and score > 50000:
            level = 2
            upgrade_sound.play()
            # 增加3架小型敌机、2架中型敌机和1架大型敌机
            add_smallenemies(smallenemies, enemies, 3)
            add_middleenemies(middleenemies, enemies, 2)
            add_bigenemies(bigenemies, enemies, 1)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
        elif level == 2 and score > 300000:
            level = 3
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_smallenemies(smallenemies, enemies, 5)
            add_middleenemies(middleenemies, enemies, 3)
            add_bigenemies(bigenemies, enemies, 2)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
            inc_speed(middleenemies, 1)
        elif level == 3 and score > 600000:
            level = 4
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_smallenemies(smallenemies, enemies, 5)
            add_middleenemies(middleenemies, enemies, 3)
            add_bigenemies(bigenemies, enemies, 2)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
            inc_speed(middleenemies, 1)
        elif level == 4 and score > 1000000:
            level = 5
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_smallenemies(smallenemies, enemies, 5)
            add_middlenemies(middleenemies, enemies, 3)
            add_bigenemies(bigenemies, enemies, 2)
            # 提升小型敌机的速度
            inc_speed(smallenemies, 1)
            inc_speed(middleenemies, 1)        

        #如果没有暂停
        if life_num and not paused:

            screen.blit(background,(0,0))   #绘制背景

            #检查是否有上下左右或wsad按下,如有则对飞机进行相应的控制
            key_press = pygame.key.get_pressed()
            if key_press[K_w] or key_press[K_UP] :    #如果按下上键或者↑
                myself.moveup()   #飞船向上飞行
            elif key_press[K_s] or key_press[K_DOWN] :    #如果按下下键或者↓
                myself.movedown()   #飞船向下飞行
            elif key_press[K_a] or key_press[K_LEFT] :    #如果按下左键或者←
                myself.moveleft()   #飞船向左飞行
            elif key_press[K_d] or key_press[K_RIGHT] :    #如果按下右键或者→
                myself.moveright()   #飞船向右飞行

            #绘制暂停和继续按钮
            screen.blit(paused_image,(width - paused_rect.width,5))    #绘制暂停按钮        

            #绘制我方飞机
            if life_num :
                # 绘制大型敌机
                for each in bigenemies:
                    if each.active: #如果大型敌机为生存状态
                        each.move()
                        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 / 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.hit :   #如果被撞
                            screen.blit(each.enemy3_hit_image,each.rect)     
                            each.hit = False       
                        else :  #如果没有被撞
                            if switch_image:    #判断是否交换图片
                                screen.blit(each.enemy3_n1, each.rect)
                            else:
                                screen.blit(each.enemy3_n2, each.rect)
                        # 即将出现在画面中,播放音效
                        if each.rect.bottom == -50:
                            enemy3_fly_sound.play()
                    else:   
                        #如果大型敌机为撞毁状态
                        if not (delay % 3) :
                            if e3_destroy_index == 0:   #当索引再次变为0时
                                enemy3_down_sound.play()    #播放声音
                            screen.blit(each.destroy_images[e3_destroy_index], each.rect)
                            e3_destroy_index = (e3_destroy_index + 1) % 6
                            if e3_destroy_index == 0:   #当索引再次变为0时
                                enemy3_down_sound.stop()
                                score += 10000  #打掉大型飞机+10000分
                                each.reset()    #重置飞机
                # 绘制中型敌机:
                for each in middleenemies:
                    if each.active :    #如果此敌机的为存活状态
                        each.move()
                        if each.hit :   #如果被撞
                            screen.blit(each.enemy2_hit_image,each.rect)    
                            each.hit = False               
                        else :  #如果没有被撞
                            screen.blit(each.enemy2, 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 / MiddleEnemy.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) :
                            if e2_destroy_index == 0:   #当索引再次变为0时
                                enemy2_down_sound.play()    #播放声音
                            screen.blit(each.destroy_images[e2_destroy_index], each.rect)
                            e2_destroy_index = (e2_destroy_index + 1) % 4
                            if e2_destroy_index == 0:   #当索引再次变为0时
                                score += 6000  #打掉大型飞机+6000分
                                each.reset()    #重置飞机
                # 绘制小型敌机:
                for each in smallenemies:
                    if each.active :    #如果此敌机的为存活状态
                        each.move()
                        screen.blit(each.enemy1, each.rect)
                    else :
                        #敌机撞毁
                        if not (delay % 3) :
                            if e1_destroy_index == 0:   #当索引再次变为0时
                                enemy1_down_sound.play()    #播放声音
                            screen.blit(each.destroy_images[e1_destroy_index], each.rect)
                            e1_destroy_index = (e1_destroy_index + 1) % 4
                            if e1_destroy_index == 0:   #当索引再次变为0时
                                score += 1000  #打掉小型飞机+1000分
                                each.reset()    #重置飞机                
                if myself.active :  #如果我方飞机active的属性为真,即未和其他飞机发生碰撞
                    if transform :  #如果改变属性为真  画第一张飞机图
                        screen.blit(myself.image1,myself.rect)  #绘制第一张飞机图         
                    else :  #如果改变属性为假  画第二张飞机图
                        screen.blit(myself.image2,myself.rect)  #绘制第二张飞机图
                else:
                    #我方飞机撞毁
                    myself_down_sound.play()
                    if not (delay % 3) :
                        screen.blit(myself.destroy_images[myself_destroy_index], myself.rect)
                        myself_destroy_index = (myself_destroy_index + 1) % 4
                        if myself_destroy_index == 0:
                            life_num -= 1
                            myself.reset()
            
                #绘制从飞机中出现的子弹
                if not (delay % 10) :   #设置每10帧射出一个子弹
                    bullet_sound.play()
                    if is_double_bullet:
                        bullets = bullet2
                        bullets[bullet2_index].reset((myself.rect.centerx-33, myself.rect.centery))
                        bullets[bullet2_index+1].reset((myself.rect.centerx+30, myself.rect.centery))
                        bullet2_index = (bullet2_index + 2) % bullet2_num
                    else:
                        bullets = bullet1
                        bullet1[bullet1_index].reset(myself.rect.midtop)    #将子弹的坐标初放到飞机的前面
                        bullet1_index = (bullet1_index + 1) % bullet1_num   #使子弹的下标始终处于0-4间不断循环

                score_text = font.render('score = %s' %str(score),True,white)  #绘制分数
                screen.blit(score_text,(10,5)) #绘制分数

                # 绘制全屏炸弹数量
                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-((i+1)*life_image_rect.width) , height - 5- life_image_rect.height))

                #检测子弹是否击中敌机
                for b in bullets:   #对于列表中的的所有子弹
                    if b.active :  #如果子弹有效
                        b.move()    #子弹移动
                        screen.blit(b.image,b.rect) #把子弹绘制在背景上
                        enemies_hit = pygame.sprite.spritecollide(b,enemies,False,collided=pygame.sprite.collide_mask)  #将所有与子弹发生碰撞的敌方飞机都加入到组中
                        if enemies_hit :   #如果有敌机与子弹相碰
                            b.active = False    #将碰撞后在子弹设置为未激活,使其消失,不再继续存在在画面中
                            for e in enemies_hit : #对于所有相撞的敌机
                                if (e in middleenemies) or (e in bigenemies) :  #如果敌机是中型飞机或者大型飞机
                                    e.hit = True    #将敌机的撞击属性设置为已碰撞
                                    e.energy -= 1   #生命值-1
                                    if e.energy == 0 :   #如果生命值变为0
                                        e.active = False    #将敌机的生命属性设置为死亡
                                        e.hit = False   #重新降低及的撞击属性变为未撞击
                                else :  #小型敌机 
                                    e.active = False    #将他们的状态设置为死亡

                if not (delay % 5) :
                    transform = not transform    #改变transform的属性来打到改变图片的效果
                    switch_image = not switch_image #改变switch_image 来改变大型飞机的图片

                if not delay :  #如果delay值变为0那么重新调回100
                    delay = 100
                delay -= 1

                #检查双方飞机是否发生碰撞
                if not myself.invincible :
                    enemies_down = pygame.sprite.spritecollide(myself, enemies, False,collided=pygame.sprite.collide_mask)  #将所有与我们的飞机发生碰撞的敌方飞机都加入到组中
                    if enemies_down:       #如果组中有成员,说明又发生碰撞
                        myself.active = False   #我放飞机存活状态变成False
                        for e in enemies_down:  
                            e.active = False    #对于与我相撞的飞机的也设为False

                #绘制全屏炸弹补给并检测是否发生碰撞
                if bomb_supply.active :     #如果炸弹补给是激活的
                    bomb_supply.move()  #补给移动
                    supply_sound.play() #播放炸弹补给出现音乐
                    screen.blit(bomb_supply.image,bomb_supply.rect)   #绘制补给图片
                    if pygame.sprite.collide_mask(bomb_supply,myself):   #检测补给和我放飞机是否发送碰撞
                        bomb_supply.active = False    #如果发生碰撞,那么补给变为未激活状态
                        get_bomb_sound.play()#播放得到补给的音效
                        if bomb_num < 3: #如果炸弹数小于3
                            bomb_num += 1   #炸弹数+1
                #绘制子弹补给并检测是否发生碰撞
                if bullet_supply.active :     #如果子弹补给是激活的
                    bullet_supply.move()  #补给移动
                    screen.blit(bullet_supply.image,bullet_supply.rect)   #绘制补给图片
                    if pygame.sprite.collide_mask(bullet_supply,myself):   #检测补给和我放飞机是否发送碰撞
                        bullet_supply.active = False    #如果发生碰撞,那么补给变为未激活状态
                        get_bullet_sound.play()#播放得到补给的音效
    
                # 绘制超级子弹补给并检测是否获得
                if bullet_supply.active:
                    bullet_supply.move()
                    screen.blit(bullet_supply.image, bullet_supply.rect)
                if pygame.sprite.collide_mask(bullet_supply, myself):
                    get_bullet_sound.play()
                    #发射超级子弹18秒
                    is_double_bullet = True
                    pygame.time.set_timer(double_bullet_timer, 18 * 1000)
                    bullet_supply.active = False 

        elif life_num and paused :  #如果暂停了
            pygame.mixer.music.pause()     #暂停背景音乐
            screen.blit(background,(0,0))   #绘制背景

            #绘制暂停和继续按钮
            screen.blit(paused_image,(width - paused_rect.width,5))    #绘制暂停按钮

        # 绘制游戏结束画面
        elif life_num == 0:

            # 背景音乐停止
            pygame.mixer.music.stop()
    
            # 停止全部音效
            pygame.mixer.stop()
    
            # 停止发放补给
            pygame.time.set_timer(supply_timer, 0)
    
            if not recorded:
                recorded = True
                # 读取历史最高得分
                with open(r"D:\Code\Python\Pygame\pygame11:飞机大战\record.txt", "r") as f:
                    record_score = int(f.read())
    
                # 如果玩家得分高于历史最高得分,则存档
                if score > record_score:
                    with open(r"D:\Code\Python\Pygame\pygame11:飞机大战\record.txt", "w") as f:
                        f.write(str(score))

            screen.blit(background,(0,0))   #绘制背景

            # 绘制结束画面
            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()  


        pygame.display.flip()   #不停的刷新画面,不停的绘画

        clock.tick(60)     #设置帧率


if __name__ == "__main__":
    # 这样做的好处是双击打开时如果出现异常可以报告异常,而不是一闪而过!
    try:
        main()
    except SystemExit: #这是按下 × 的异常,直接忽略
        pass
    except:
        traceback.print_exc()
        pygame.quit()
        input()

好吧,说完了。
内容中的一个注释:# 这样做的好处是双击打开时如果出现异常可以报告异常,而不是一闪而过!
很好

本文地址:https://blog.csdn.net/wrt112120/article/details/107890490

相关标签: 编程吧 游戏