Python项目:飞机大战v1.0

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
#plane_sprites.py
# 模块导入顺序
import random  # 官方标准模块
import pygame  # 第三方模块

# 应用程序模块

# 定义一个屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 600)  # 不用担心到时候可以通过Rect类中的size方法获取到矩形窗口大小的元组
# 刷新的帧率
FRAME_PER_SECOND = 60

# 创建敌机的定时器常量
CREATE_ENEMY_EVENT = pygame.USEREVENT  # pygame提供了一个用户事件常量
#英雄发射子弹事件
HERO_FIRE_EVENT=pygame.USEREVENT+1

# 需要继承一下pygame中的精灵类
class GameSprite(pygame.sprite.Sprite):
    """飞机大战的游戏精灵"""

    def __init__(self, image_name, speed=1):
        # 调用父类的初始化方法必须在这里调用我们要求扩展式继承而不是覆盖式
        # 要求不同对象的init方法也要有重合部分就是继承的super()父类的部分
        super().__init__()  # 这里每个对象有相同的操作

        # 定义对象的属性,这里每个对象属性不同
        self.image = pygame.image.load(image_name)
        self.rect = self.image.get_rect()  # image的图像大小
        self.speed = speed

    def update(self):
        # 在屏幕的垂直方向移动
        self.rect.y += self.speed

class Background(GameSprite):
    """游戏背景精灵"""

    def __init__(self, is_alt=False):
        super().__init__("./images/background.png")
        if is_alt:
            self.rect.y = -self.rect.height

    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:
            self.rect.y = -self.rect.height

class Enemy(GameSprite):
    """敌机精灵"""

    def __init__(self):
        super().__init__("./images/enemy1.png")

        # 设置敌机的初始速度
        self.speed = random.randint(1, 3)
        # 设置敌机的初始位置
        self.rect.bottom = 0
        max_x = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0, max_x)



    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:
            # print("飞出屏幕需要从精灵组删除")
            self.kill()  # kill方法可以将精灵从所有精灵组中移出自动销毁以正常调用__del__()方法
    def __del__(self):  # 销毁敌机
        pass
        # print("敌机挂在了 %s" % self.rect)

class Bullet(GameSprite):
    """子弹精灵"""
    def __init__(self):
        super().__init__("./images/bullet1.png",-2)

    def update(self):
        super().update()
        if self.rect.bottom<0:
            self.kill()

    def __del__(self):
        pass

class Hero(GameSprite):
    def __init__(self):
        super().__init__("./images/me1.png",0)# 第二个参数是飞机的速度我们实现飞机在screen中水平移动
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 120

        # 创建子弹精灵组
        self.bullets=pygame.sprite.Group()
    def update(self):
        # 英雄在水平方向移动
        self.rect.x+=self.speed

        # 控制英雄不能移出屏幕
        if self.rect.x<0 :
            self.rect.x=0
        #rect提供了一个矩形对象right属性right属性的本质等于精灵的位置加上width
        elif self.rect.right>SCREEN_RECT.right:
            self.rect.right=SCREEN_RECT.right

    def fire(self):
        for i in (0,1,2):
            # 1.创建子弹精灵
            bullet=Bullet()
            # 2.设置精灵位置
            bullet.rect.bottom=self.rect.y- i*20
            bullet.rect.centerx=self.rect.centerx
            # 3.将精灵添加到精灵组
            self.bullets.add(bullet)
#plane_main.py
import pygame.examples.sprite_texture

from plane_sprites import *


# 使用import方式导入模块在使用模块中的工具时必须使用 模块. 的方式访问
# 使用from 模块 import * 的方式导入模块在使用的时候就无需写 模块. 直接调用相应对象即可


class PlaneGame(object):
    """飞机大战主游戏"""

    def __init__(self):
        print("游戏初始化")
        # 1.创建游戏窗口用到类似C语言中的宏定义常量
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)  # 从SCREEN_RECT这个矩形对象中取出描述窗口大小的元组

        # 2.创建游戏时钟
        self.clock = pygame.time.Clock()
        # 3.调用私有方法
        self.__create_sprites()  # 创建精灵和精灵组

        # 4.设置定时器事件--创建敌机
        pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)# 第二个参数以毫秒为单位
        pygame.time.set_timer(HERO_FIRE_EVENT,500)# 每隔0.5秒发射一颗子弹
    def __create_sprites(self):
        # 创建背景精灵和精灵组
        bg1 = Background()
        bg2 = Background(True)
        # bg2.rect.y=-bg2.rect.height# bg2的初始位置,由于已经封装在Background类初始化方法中故可以不写
        self.back_group = pygame.sprite.Group(bg1, bg2)

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

        # 创建英雄的精灵和精灵组
        self.hero = Hero()
        self.hero_group = pygame.sprite.Group(self.hero)

    def start_game(self):
        print("游戏开始")

        while True:
            # 1.设置刷新帧率
            self.clock.tick(FRAME_PER_SECOND)
            # 2.事件监听
            self.__event_handler()
            # 3.碰撞检测
            self.__check_collide()
            # 4.更新/绘制精灵组
            self.__update_sprites()
            # 5.更新显示
            pygame.display.update()

    # 事件监听
    def __event_handler(self):
        for event in pygame.event.get():
            # 判断是否退出游戏
            if event.type == pygame.QUIT:
                PlaneGame.__game_over()
            elif event.type == CREATE_ENEMY_EVENT:
                print("敌机出场")
                # 创建敌机精灵
                enemy = Enemy()
                # 将地精精灵添加到敌机精灵组
                self.enemy_group.add(enemy)
            elif event.type==HERO_FIRE_EVENT:
                self.hero.fire()
            # 第一种捕获键盘输入向右的方式
            # elif event.type==pygame.KEYDOWN and event.key==pygame.K_RIGHT:
            #     print("向右移动")

            # 第二种,使用键盘提供的方法获取键盘按键
            keys_pressed=pygame.key.get_pressed()
            # 判断元组中对应的按键索引值
            if keys_pressed[pygame.K_RIGHT]:
                #print("向右移动")
                self.hero.speed=3
            elif keys_pressed[pygame.K_LEFT]:
                self.hero.speed=-3
            else:
                self.hero.speed=0


    def __check_collide(self):

        # 子弹摧毁敌机
        pygame.sprite.groupcollide(self.hero.bullets,self.enemy_group,True,True)

        # 敌机撞毁英雄
        enemies=pygame.sprite.spritecollide(self.hero,self.enemy_group,True)
        # 判断enemise列表是否有内容如果有就做英雄牺牲的动作
        if len(enemies)>0:
            self.hero.kill()
            PlaneGame.__game_over()




    def __update_sprites(self):
        self.back_group.update()
        self.back_group.draw(self.screen)

        self.enemy_group.update()  # 更新所有敌机的位置
        self.enemy_group.draw(self.screen)  # 绘制敌机对象

        self.hero_group.update()
        self.hero_group.draw(self.screen)

        self.hero.bullets.update()
        self.hero.bullets.draw(self.screen)

    @staticmethod  # 静态方法 1.添加修饰符 2.无需任何参数self也不需要
    def __game_over():
        print("游戏结束")
        pygame.quit()
        exit()


def main():
   # pygame.init()
    # 创建游戏对象
    game = PlaneGame()
    game.start_game()  # 启动游戏


if __name__ == '__main__':
    main()

"""以下为入门举例代码
pygame.init()

# 使用pygame.Rect类描述一个矩形对象,rect就是矩形的意思
# 这个矩形对象pygame.Rect(x,y,width,height)
hero_rect=pygame.Rect(150,300,102,126)# 102,126是英雄飞机图像的参数,英雄飞机的初始位置
# print("英雄的原点 %d %d"% (hero_rect.x,hero_rect.y))
# print("英雄的尺寸 %d %d"%(hero_rect.width,hero_rect.height))
# print("%d %d"%hero_rect.size)#使用Rect类中的size属性可以返回英雄的宽度和高度



# 1.创建游戏窗口480*700
# 使用pygame模块中的display模块中的set_mode()方法
screen=pygame.display.set_mode((480,600))


# 2.绘制图像初始位置
# 绘制背景图像
# 1>加载图像数据,设置background
bg=pygame.image.load("./images/background.png")
# 2>屏幕对象screen调用blit方法在窗口(0,0)处绘制图像
screen.blit(bg,(0,0))
# 3>update更新屏幕显示,如果不调用update方法则不能绘制背景图像
#pygame.display.update()#可以在screen对象调用完所有blit方法后统一调用一次


# 绘制英雄飞机和上面一样三步曲其中第三步可以在screen对象调用完所有blit方法后统一调用一次
hero=pygame.image.load("./images/me1.png")
screen.blit(hero,(200,500))



# 可以在screen对象调用完所有blit方法后统一调用一次可以提高游戏流畅度
pygame.display.update()# 把screen对象的绘制结果一次性的绘制到屏幕上

# 3.创建时钟对象
clock=pygame.time.Clock()

# i=0# 用于测试游戏循环帧率

# 创建敌机的精灵
enemy=GameSprite("./images/enemy1.png")
enemy1=GameSprite("./images/enemy1.png",2)# 2是敌机的速度
# 创建敌机的精灵组
enemy_group=pygame.sprite.Group(enemy,enemy1)


# 游戏循环
while True:
    # 60fps60 frame per second
    clock.tick(60)

    # 捕获事件
    # event_list = pygame.event.get()#get()方法的返回值是一个列表
    # if len(event_list)>0:# 只有当有事件时才输出
    #    print(event_list)

    #事件监听
    for event in pygame.event.get():

        if event.type==pygame.QUIT:
            # print("退出游戏")
            pygame.quit()# 在这里卸载pygame
            exit()#直接终止程序


    # 修改飞机位置
    hero_rect.y-=1

    # 判断飞机的位置如果y<=0则修改y的值让飞机实现在框内循环
    if hero_rect.y<=-126:# 当飞机完全越过上界时才重新定位到最下方
        hero_rect.y=600

    # 调用blit方法绘制图像
    # 我们不希望在循环的时候留下飞机的残影
    # 我们的解决方案是在移动之前重新绘制背景图像
    screen.blit(bg,(0,0))# 解决方案核心代码
    screen.blit(hero,hero_rect)# 参数一图像特性参数二位置特性

    # 让精灵组调用两个方法update draw
    enemy_group.update()# 让组中所有精灵更新位置
    enemy_group.draw(screen)# 在screen上绘制所有的精灵

    pygame.display.update()


    #用于测试游戏循环帧率
    # i+=1
    # print(i)
    #用于测试游戏循环帧率



# pygame.quit() #在事件监听中退出pygame
"""

//linux

//矩阵

Pygame.Rect 类

//精灵类继承自pygame的精灵类而不是继承自object的类我们需要先扩展重写super()一下父类的__init__()方法

//用于代替blit、update方法进行绘制和更新

//背景图片的动态实现的原理

改进

背景图像的设置封装在初始化方法内部

初始位置的设置封装在初始化方法内部

采用is_alt参数来确定到底是哪一个对象

False表示第一张图像位置与屏幕重合

True表示另一张图像位置在屏幕正上方

//import的顺序

链接https://pan.baidu.com/s/1c2aMz1kjHMtmnlsgDC7pKw?pwd=5kxc

提取码5kxc

--图片素材

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python