pygame实现 飞机大战-第三版-仿写版

目录

 

一、功能介绍:

二、原代码

(一)精灵定义部分

(二)游戏运行部分

三、代码解析

(一)游戏开始界面的实现

(二)双人单人游戏控制

(三)利用自定义事件

(四)利用精灵Sprite和精灵组Group的碰撞检测

(五)获取键盘控制键


在对第二版进行深入学习和研究的基础上,根据第二版的精灵Sprite和Group应用的原理的掌握,本着学习就是不断的折腾的原则,依据第二版的飞机大战自己完成了仿写版的飞机大战。不多说,先上原代码,请大家不要取笑啊!

一、功能介绍:

1、游戏开始界面,可以选择单人、双人游戏

2、可以双机作战,子弹不同

3、英雄有飞机架数限制

4、敌机有BOSS,可以发射子弹

5、有音效和音乐

6、有加子弹的道具,最多可以加到6轮子弹,英雄死后子弹清到1

二、原代码

(一)精灵定义部分

#引入库
import random
import pygame
# from pygame.locals import *

#系统常量设置
#窗口的设置
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 刷新的帧率
FRAME_PER_SEC = 60
# 创建敌机的定时器常量,自定义事件
CREATE_ENEMY_EVENT = pygame.USEREVENT
# 英雄发射子弹时间,自定义事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1
#敌机发射子弹的时间,自定义事件

#出现加子弹道具的事件
CREAT_BULLET_ADD_ENENT =pygame.USEREVENT + 2

#出现敌机发射子弹的事件
CREAT_ENEMYPLANE_FIRE_ENENT = pygame.USEREVENT + 3
#英雄同时发射的子弹的个数
NUM_BULLENT_FIRE_HERO1 = 1
NUM_BULLENT_FIRE_HERO2 = 1



#文件引用设置
image_background = "./image/background.png"
image_enemy = "./image/enemy0.png"
image_enemy1 ="./image/enemy1.png"
image_hero1 = "./image/hero1.png"
image_hero2 = "./image/hero2.png"
image_addbullet ="./image/prop_type_0.png"

image_bullet0 = "./image/bullet.png"
image_bullet1 = "./image/bullet1.png"
image_bullet2 = "./image/bullet2.png"


font_path = "font/STXINGKA.TTF"

sound_bullet = "sound/bullet.mp3"
sound_ememydown0 = "sound/enemy0_down.mp3"
sound_backround = "sound/game_music.mp3"

#精灵定义
#创建GameSprite精灵
class GameSprite(pygame.sprite.Sprite):
    """输入路径和是否为标签"""
    def __init__(self, file_name, is_label=False,content=None,size=30):
        #继承父类方法
        super().__init__()
        if not is_label:
            #为图片输入时
            self.image = pygame.image.load(file_name) #通过图像生成surface对象
            self.rect = self.image.get_rect() #生成rect对象
        else:
            #为文字输入时
            # self.myfont = pygame.font.SysFont(file_name, size)  #注意:用sysfont不支持汉字的显示,改成font后显示
            self.myfont = pygame.font.Font(file_name, size)
            self.image = self.myfont.render(content, True, (0, 0, 0))
            self.rect = self.image.get_rect()  # 生成rect对象
        #以上代码生成surface对象image和对应原rect对象
        # #返回image和rect
        # return self.image,self.rect

    #实现移动
    def update(self,x_speed=0,y_speed=0):
        self.rect.x += x_speed
        self.rect.y += y_speed

#定义子类
#
#背景类
class Background(GameSprite):  # 基于GameSprite生成精灵
    def __init__(self, is_alt=False):
        # 1.调用父类方法实现精灵的创建
        super().__init__(image_background)
        # 2.判断是否是交替图像,如果是,需要设置初始位置
        if is_alt:
            self.rect.y = -self.rect.height

    def update(self,x_speed=0,y_speed=0):
        # 1.调用父类的方法实现
        super().update(0,1)  # y方向是1,x方向是0
        # 2.判断是否飞出屏幕,如果是,需要从精灵组删除敌机
        if self.rect.y >= SCREEN_RECT.height:
            print("飞出屏幕,需要从精灵组删除。。。。")
            self.rect.y = -self.rect.height

#敌机类
class Enemy(GameSprite):
    def __init__(self,filename,bottom_speed_num=1,top_speed_num=3):
        # 1.调用父类方法,创建敌机精灵,同时指定敌机图片
        super().__init__(filename)
        # 2.指定敌机的初始随机速度
        self.speed = random.randint(bottom_speed_num, top_speed_num)

        # 3.指定敌机的初始随机位置
        self.rect.bottom = 0
        max_x = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0, max_x)

        # 创建敌机子弹精灵组
        self.emeny_bullet_group = pygame.sprite.Group()

    def update(self,x_speed=0,y_speed=0):
        super().update(0,self.speed)
        # 2.判断是否飞出屏幕,如果是,需要从精灵组删除敌机
        if self.rect.y >= SCREEN_RECT.height:
            # print("飞出屏幕,需要从精灵组删除。。。。")
            self.kill()

    def enemyfire(self,file_bullet,num=1):  #修改:2022-4-13 添加num参数,并根据数量控制好子弹位置
        print("敌机发射子弹。。。")
        bullet_num = num  #单独定义同时发射的子弹数可以为后期游戏过程中改变子弹发射数作基础

        for i in range(0,bullet_num):
            # 1.创建子弹精灵
            emeny_bullet = Bullet(file_bullet,3)
            # 2.设置精灵的位置
            emeny_bullet.rect.bottom = self.rect.y + self.rect.height
            emeny_bullet.rect.centerx = self.rect.centerx - 20 * (i - (bullet_num-1)/2)
            # emeny_bullet.rect.centerx = self.rect.centerx
            print("敌机子弹的位置,top为{0};X中心为{1}".format(emeny_bullet.rect.bottom,emeny_bullet.rect.centerx))
            # 3.将精灵添加到精灵组
            self.emeny_bullet_group.add(emeny_bullet)
            # print(len(self.emeny_bullet_group)) #有精灵却不能在planegame调用??

            # return self.emeny_bullet_group
            #加入方法也有问题,返回组的话没有数据
            # print(emeny_bullet)

#英雄类
class Hero(GameSprite):
    def __init__(self,hero_image_file):
        # 1.调用父类方法,设置image speed
        super().__init__(hero_image_file)
        # 2.设置英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 80

        # 3.创建子弹的精灵组
        self.bullets = pygame.sprite.Group()

    def update(self,x_speed=0,y_speed=0):
        super().update(x_speed, y_speed)
        # # 英雄在水平方向运行
        # self.rect.x += self.speed2
        # # 英雄在垂直方向运行
        # self.rect.y -= self.speed1
        # 控制英雄不能离开屏幕
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.y < 0:
            self.rect.y = 0
        elif self.rect.right > SCREEN_RECT.right:
            self.rect.right = SCREEN_RECT.right
        elif self.rect.bottom> SCREEN_RECT.bottom:
            self.rect.bottom = SCREEN_RECT.bottom


    def fire(self,num,file_bullet):  #修改:2022-4-13 添加num参数,并根据数量控制好子弹位置
        # print("发射子弹。。。")
        bullet_num = num  #单独定义同时发射的子弹数可以为后期游戏过程中改变子弹发射数作基础

        for i in range(0,bullet_num):
            # 1.创建子弹精灵
            bullet = Bullet(file_bullet,-3)
            # 2.设置精灵的位置
            bullet.rect.bottom = self.rect.y
            bullet.rect.centerx = self.rect.centerx - 20 * (i - (bullet_num-1)/2)

            # 3.将精灵添加到精灵组
            self.bullets.add(bullet)

class Bullet(GameSprite):
    def __init__(self,filename,speed):
        # 调用父类方法,设置子弹图片,设置初始速度
        super().__init__(filename)
        self.yspeed=speed

    def update(self,x_speed=0,y_speed=0):
        # 调用父类方法,让子弹沿垂直方向飞行,
        super().update(0,self.yspeed)
        # 判断子弹是否飞出屏幕
        if self.rect.bottom < 0:
            # kill方法把精灵从精灵组删除
            self.kill()

    def __del__(self):
        # print("子弹被销毁。。")
        pass

class Label(GameSprite):
    def __init__(self,content,x,y): # 引用时需要输入内容及相应的位置
        # 调用父类方法,设置文字字体位置
        super().__init__(font_path, True, content,30)
        #设置文字显示位置
        self.rect.x = x
        self.rect.y = y


    def update(self,x_speed=0,y_speed=0):
        # 调用父类方法,标签位置不动
        super().update(0,0)


#创建SoundSprite精灵
class SoundSprite(pygame.sprite.Sprite):
    def  __init__(self,sound_name):
        super().__init__()
        self.sound_name=sound_name

    def play(self,is_music=False):
        self.sound = pygame.mixer.Sound(self.sound_name)
        pygame.mixer.Sound.play(self.sound)
        if is_music :
            self.music=pygame.mixer.music.l
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值