python飞机大战

控制英雄精灵移动

项目准备

安装准备

这里我们要用到pygame模块,pygame模块是python中针对电子游戏开发的模块,功能十分完善,安装pygame模块的方法(针对windows用户):直接在终端输入 pip install pygame,如果运行失败可以用镜像源   pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple
安装成功后会显示successfully,也可以输入pip list 进行查看

绘制窗口

初始化和退出

这里我们需要使用到pygame提供的init方法进行初始化,quit来退出

创建游戏主窗口

import pygame

pygame.init()

screen = pygame.display.set_mode((480, 650))

while True:
    pass

pygame.quit()

#修改游戏名称
pygame.display.set_caption('飞机大战')

#修改游戏图标
icon = pygame.image.load("image/icon72x72.png")
pygame.display.set_icon(icon)

创建游戏窗口用set_mode方法,取决于背景图片的大小,里面第一个参数是(width,height),是一个元组一定要用() 括起来,这里设置的是宽480,高650。

pygame.image.load()加载图像数据

绘制图像

# 加载图像数据,括号里面是图片地址
background = pygame.image.load('image/background.png')

# blit绘制图像,(0,0)是将背景图的左上角绘制到游戏窗口的左上角
screen.blit(background, (0, 0))

# update 更新屏幕显示
pygame.display.update()

使用pygame.image.load()加载图像的数据

调用pygame.display.update()方法更新整个屏幕的显示,可以在所有图像绘制完之后调用update

pygame.diaplay.update()来更新整个屏幕的显示

定义图片切换索引

hero_imgindex=0

时钟对象

# 设置时钟对象
clock = pygame.time.Clock()

while True:
    # 设置游戏频率,可以指定循环内部的代码执行的频率,60表示每秒执行60次
    clock.tick(60)


上面的游戏窗口已经把游戏窗口和背景都已经设置好,而这里我们可以设置每秒刷新60次

在规定的时间内执行多少次,可以理解为每秒执行多少次,即刷新帧率,pygame专门提供一个类pygame.time.Clock()可以非常方便的设置屏幕绘制速度,即刷新帧率

绘制英雄机

hero_img1 = pygame.image.load("image/me1.png")

英雄机的移动

# 设置时钟对象
clock = pygame.time.Clock()

# 定义rect记录飞机的初始位置
hero_rect = pygame.Rect(190,525,100,124)

while True:
    # 60表示每秒执行60次
    clock.tick(60)

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

    # 调用blit方法绘制图像,每次循环完用背景图覆盖一次,不然会造成每次循环的飞机重叠
    screen.blit(background, (0, 0))
    screen.blit(hero, hero_rect)

    # 更新屏幕显示
    pygame.display.update()

定义飞机的位置,然后在每次循环内对飞机的坐标进行更改,然后每次循环结束前在对屏幕进行更新

注:在每次循环内我们需要覆盖掉上一次战机,即用背景图进行覆盖,不然会造成每次循环的战机都留在屏幕上,所以我们在每次循环绘制战机之前,先对上一次循环的战机进行覆盖

将英雄的飞机绘制到窗口上

        if shitindex == 0:
            screen.blit(hero_img1, (hero_PlaneX, hero_PlaneY))
            shitindex = 1

        else:
            screen.blit(hero_img2, (hero_PlaneX, hero_PlaneY))
            shitindex = 0

更改英雄机精灵坐标位置

英雄精灵自动移动

# 飞机从底部飞出
    if hero_PlaneY<0:
       hero_PlaneY=750

就是当战机移动到顶部的时候,会从底部钻出来,这样会使战机移动更连续

事件监听

首先获取所有事件

# 对事件进行监听 获取所有事件
    event_list = pygame.event.get()
    #捕捉窗口退出事件
    for event in event_list:
        if event.type == pygame.QUIT:  # 加上这个模块就不卡了
            print("游戏结束了.......")
            pygame.quit()  # 卸载模块
            exit(0)  # 终止Python程序, exit(0)表示正常退出 exit(1)表示异常退出

 控制英雄精灵移动 

# 控制英雄精灵移动
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                hero_PlaneX = hero_PlaneX - 5 if hero_PlaneX >= 5 else 0

            elif event.key == pygame.K_RIGHT:
                hero_PlaneX = hero_PlaneX + 5 if hero_PlaneX <= 375 else 380

            elif event.key == pygame.K_DOWN:
                hero_PlaneY  = hero_PlaneY  + 5 if hero_PlaneY  <= 521 else 526
            elif event.key == pygame.K_UP:
                hero_PlaneY  = hero_PlaneY  - 5 if hero_PlaneY >= 5 else 0

设置灵敏度

pygame.key.set_repeat(20,30)

 绘制敌机

加载敌机

enemy_img=pygame.image.load('image/enemy2.png')
enemy_img2=pygame.image.load("image/enemy2_hit.png")

定义敌机位置 


enemy_rect=pygame.rect.Rect(158,0,69,99)  #(480-69)/2
enemyPlaneX=enemy_rect.x
enemyPlaneY=enemy_rect.y

绘制敌机


    screen.blit(enemy_img,(enemyPlaneX,enemyPlaneY))

控制敌机精灵移动


    if direct =='left':
        enemyPlaneX-=5
        if enemyPlaneX<=0:
            direct='right'
    elif direct=='right':
        enemyPlaneX=enemyPlaneX +  5
        if enemyPlaneX >=480-165:
            direct='left'

绘制精灵子弹

用类的方法

英雄机子弹

class HeroBullet:
    def __init__(self,x,y,screen):
        self.x=x
        self.y=y
        self.screen=screen
        self.pic=pygame.image.load('image/bullet1.png')

    #画子弹
    def draw(self):
        self.screen.blit(self.pic,(self.x,self.y))
        self.move()

    #子弹移动方法
    def move(self):
        self.y-=5

#英雄机子弹列表
hero_Bulletlist=[]

敌机子弹 

class EnemyBullet:
    def __init__(self, x, y, screen):
        self.x = x
        self.y = y
        self.screen = screen
        self.pic = pygame.image.load('image/bullet2.png')

    # 画子弹
    def draw(self):
        self.screen.blit(self.pic, (self.x, self.y))
        self.move()

    # 子弹移动方法
    def move(self):
        self.y+=5

#敌机子弹列表
enemy_list=[]

 画出敌机子弹

x=random.randint(1,100)
    if x==5 or x==78 :
        #绘制敌机子弹
        enemybullet=EnemyBullet(enemyPlaneX+69/2-5/2,enemyPlaneY+99,screen)
        enemy_list.append(enemybullet)
    for bullet2 in enemy_list:
        bullet2.draw()

随机我们就应该要想到random模块,使用random来让敌机出现的位置随机,我们先在文件中导入random模块,然后在敌机精灵类中的初始化方法中进行操作 绘制精灵爆炸

绘制敌机爆炸

#敌机爆炸条件
enemy_bomb=False

#敌机爆炸索引
enemy_bomb_index=0
    for bullet in hero_Bulletlist:
        bullet.draw()
        #让子弹到最上面的时候消失
        hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
        # 定义英雄子弹rect
        hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
        # 碰撞检测
        flag = hero_bullet_rect.colliderect(enemy_rect)
        if flag:
            print("敌机爆炸")
            enemy_bomb = True
            hero_Bulletlist.remove(bullet)

爆炸图片 

enemy_bomb_imgs=["image/enemy2_down1.png",
                   "image/enemy2_down2.png", "image/enemy2_down3.png", "image/enemy2_down4.png"]
    for bullet in hero_Bulletlist:
        bullet.draw()
        #让子弹到最上面的时候消失
        hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
        # 定义英雄子弹rect
        hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
        # 碰撞检测
        flag = hero_bullet_rect.colliderect(enemy_rect)
        if flag:
            print("敌机爆炸")
            enemy_bomb = True
            hero_Bulletlist.remove(bullet)
    if enemy_bomb == False:
            #切换图片, # 绘制敌机图片
        if enemy_bomb_index == 0:

            screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index = 1
        else:
            screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index = 0

    else:
        if enemy_bomb_index == len(enemy_bomb_imgs):
                # 当敌机爆炸索引与图片总数相同时,退出游戏
            time.sleep(0.2)
            exit(0)
enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
        screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY))  # 绘制爆炸图片
        enemy_bomb_index += 1
        time.sleep(0.2)

绘制英雄机爆炸

#英雄机爆炸
hero_bomb=False

#英雄机爆炸索引
hero_bomb_index=0
    for bullet in hero_Bulletlist:
        bullet.draw()
        #让子弹到最上面的时候消失
        hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
        # 定义英雄子弹rect
        hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
        # 碰撞检测
        flag = hero_bullet_rect.colliderect(enemy_rect)
        if flag:
            print("敌机爆炸")
            enemy_bomb = True
            hero_Bulletlist.remove(bullet)
    if enemy_bomb == False:
            #切换图片, # 绘制敌机图片
        if enemy_bomb_index == 0:

            screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index = 1
        else:
            screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index = 0

    else:
        if enemy_bomb_index == len(enemy_bomb_imgs):
                # 当敌机爆炸索引与图片总数相同时,退出游戏
            time.sleep(0.2)
            exit(0)
 enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
        screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY))  # 绘制爆炸图片
        enemy_bomb_index += 1
        time.sleep(0.2)

全部代码

import random
import pygame
import time
pygame.init()

#创建窗口
screen=pygame.display.set_mode((480,650))#480为宽,500为高

#修改游戏名称
pygame.display.set_caption('飞机大战')

#修改游戏图标
icon = pygame.image.load("image/icon72x72.png")
pygame.display.set_icon(icon)

# 加载背景
bg_img = pygame.image.load('image/background.png')


#加载精灵图片
hero_img1 = pygame.image.load("image/me1.png")
hero_img2 = pygame.image.load("image/me2.png")

#加载战机战损
hero_bomb_imgs=["image/me_destroy_1.png",
                   "image/me_destroy_2.png", "image/me_destroy_3.png", "image/me_destroy_4.png"]

#作为切换的索引值
shitindex=0

#定义英雄机位置
hero_rect=pygame.rect.Rect(190,525,100,124)
#设置精灵XY轴
hero_PlaneX=hero_rect.x
hero_PlaneY=hero_rect.y

#加载敌机图片
enemy_img=pygame.image.load('image/enemy2.png')
enemy_img2=pygame.image.load("image/enemy2_hit.png")

#加载敌机战损
enemy_bomb_imgs=["image/enemy2_down1.png",
                   "image/enemy2_down2.png", "image/enemy2_down3.png", "image/enemy2_down4.png"]

#定义敌机位置
enemy_rect=pygame.rect.Rect(158,0,69,99)  #(480-69)/2
enemyPlaneX=enemy_rect.x
enemyPlaneY=enemy_rect.y

#设置灵敏度
pygame.key.set_repeat(20,30)

#定义时钟
clock=pygame.time.Clock()

#定义图片切换索引
hero_imgindex=0

#定义敌机初始移动方向
direct='left'

#定义英雄机子弹   子弹类
class HeroBullet:
    def __init__(self,x,y,screen):
        self.x=x
        self.y=y
        self.screen=screen
        self.pic=pygame.image.load('image/bullet1.png')

    #画子弹
    def draw(self):
        self.screen.blit(self.pic,(self.x,self.y))
        self.move()

    #子弹移动方法
    def move(self):
        self.y-=5

#英雄机子弹列表
hero_Bulletlist=[]

#定义敌机子弹
class EnemyBullet:
    def __init__(self, x, y, screen):
        self.x = x
        self.y = y
        self.screen = screen
        self.pic = pygame.image.load('image/bullet2.png')

    # 画子弹
    def draw(self):
        self.screen.blit(self.pic, (self.x, self.y))
        self.move()

    # 子弹移动方法
    def move(self):
        self.y+=5

#敌机子弹列表
enemy_list=[]

#英雄机爆炸
hero_bomb=False

#英雄机爆炸索引
hero_bomb_index=0

#敌机爆炸条件
enemy_bomb=False

#敌机爆炸索引
enemy_bomb_index=0

#游戏循环
while True:
    clock.tick(60)#60表示每秒刷新60
    # 图片背景
    screen.blit(bg_img, (0, 0))

    # 修改飞机y值,实现自动飞行
    hero_PlaneY -=1

    # 飞机从底部飞出
    if hero_PlaneY<0:
       hero_PlaneY=750

    #绘制敌机
    screen.blit(enemy_img,(enemyPlaneX,enemyPlaneY))

    # 控制敌机移动
    if direct =='left':
        enemyPlaneX-=5
        if enemyPlaneX<=0:
            direct='right'
    elif direct=='right':
        enemyPlaneX=enemyPlaneX +  5
        if enemyPlaneX >=480-165:
            direct='left'

    x=random.randint(1,100)
    if x==5 or x==78 :
        #绘制敌机子弹
        enemybullet=EnemyBullet(enemyPlaneX+69/2-5/2,enemyPlaneY+99,screen)
        enemy_list.append(enemybullet)
    for bullet2 in enemy_list:
        bullet2.draw()
        enemy_bullet_rect = pygame.rect.Rect(bullet2.x, bullet2.y, 5, 11)
        flag2 = enemy_bullet_rect.colliderect(hero_rect)
        if flag2:
            print("战机爆炸")
            hero_bomb = True
            enemy_list.remove(bullet2)
    if hero_bomb == False:
            # 英雄机绘制到窗口
        if shitindex == 0:
            screen.blit(hero_img1, (hero_PlaneX, hero_PlaneY))
            shitindex = 1

        else:
            screen.blit(hero_img2, (hero_PlaneX, hero_PlaneY))
            shitindex = 0
    else:
        if hero_bomb_index == len(hero_bomb_imgs):
            time.sleep(0.3)
            exit()

        hero_bomb_img = pygame.image.load(hero_bomb_imgs[hero_bomb_index])
        screen.blit(hero_bomb_img, (hero_PlaneX, hero_PlaneY))  # 绘制爆炸图片
        hero_bomb_index += 1
        time.sleep(0.07)





    # 对事件进行监听 获取所有事件
    event_list = pygame.event.get()
    #捕捉窗口退出事件
    for event in event_list:
        if event.type == pygame.QUIT:  # 加上这个模块就不卡了
            print("游戏结束了.......")
            pygame.quit()  # 卸载模块
            exit(0)  # 终止Python程序, exit(0)表示正常退出 exit(1)表示异常退出

    # 控制英雄精灵移动
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                hero_PlaneX = hero_PlaneX - 5 if hero_PlaneX >= 5 else 0

            elif event.key == pygame.K_RIGHT:
                hero_PlaneX = hero_PlaneX + 5 if hero_PlaneX <= 375 else 380

            elif event.key == pygame.K_DOWN:
                hero_PlaneY  = hero_PlaneY  + 5 if hero_PlaneY  <= 521 else 526
            elif event.key == pygame.K_UP:
                hero_PlaneY  = hero_PlaneY  - 5 if hero_PlaneY >= 5 else 0

            elif event.key == pygame.K_SPACE:
                #调用子弹的方法属性
                hero_bullet=HeroBullet(hero_PlaneX+50,hero_PlaneY-11,screen)
                #把子弹放入列表中  子弹是多个 我们将多个实例化的子弹放表中
                hero_Bulletlist.append(hero_bullet)

    for bullet in hero_Bulletlist:
        bullet.draw()
        #让子弹到最上面的时候消失
        hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
        # 定义英雄子弹rect
        hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
        # 碰撞检测
        flag = hero_bullet_rect.colliderect(enemy_rect)
        if flag:
            print("敌机爆炸")
            enemy_bomb = True
            hero_Bulletlist.remove(bullet)
    if enemy_bomb == False:
            #切换图片, # 绘制敌机图片
        if enemy_bomb_index == 0:

            screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index = 1
        else:
            screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index = 0

    else:
        if enemy_bomb_index == len(enemy_bomb_imgs):
                # 当敌机爆炸索引与图片总数相同时,退出游戏
            time.sleep(0.2)
            exit(0)
        enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
        screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY))  # 绘制爆炸图片
        enemy_bomb_index += 1
        time.sleep(0.2)



# 图片更新
    pygame.display.update()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值