用python写的一个飞机大战小游戏

谁都会走 提交于 2020-01-12 03:26:36

用python写的一个飞机大战小游戏

一、配置环境

首先,我们需要一个python的编写环境,我用的是pycharm18.3.1版,在编译环境里面,导入pygame包(可以用pip指令pip install pygame,也可以在pycharm的File——setting——Project : Pycharm projects——Project interpreter中,找到所有包的列表的左边栏,点击+号,添加pygame包)。

+号位置如图所示:
导入pygame包如图所示
在编代码之前,我们还需要寻找一些可能会用到的方法,比如事件绑定按键等,我是在pygame的这个官方文档上寻找和学习的。仅供参考。

二、编写代码

首先导入可能要用到的包:

import pygame,sys,random,time
from pygame.locals import *

接着开始定义英雄的类:

class Hero():              #定义自身主机属性
    def __init__(self,img,x,y,window): #初始化
        self.img=pygame.image.load(img)
        self.x=x
        self.y=y
        self.window=window
        self.fire_list=[]
    # def __init__(self,window):     #将自身主机属性设置为固定格式
    #     self.window=window
    #     self.x=150
    #     self.y=528
    #     self.img=pygame.image.Load("hero.png")

    def display(self):              #刷新主机页面
        self.window.blit(self.img,(self.x,self.y))

    def move_left(self):           #操作主机向左移动
        if self.x<5:               #这里的数字改变可以改变英雄移动的速度,下面的上下和右移同理
            pass
        else:
            self.x-=3
    def move_right(self):          #操作主机向右移动
        if self.x>395:             #这里的395是在窗口全宽690前提下寻找的中点,可根据需要修改英雄的位置
            pass
        else:
            self.x+=3
    def move_up(self):             #操作主机向上移动
        if self.y<100:
            pass
        else:
            self.y-=3
    def move_down(self):           #操作主机向下移动
        if self.y>690:             #这里690的大小可根据窗口需要自行更改
            pass
        else:
            self.y+=3

    def fire(self):                #定义子弹函数
        hero_biu=Bullet("bullet.png",self.x+40,self.y-20,self.window)
        bu_list.append(hero_biu)

    def fire_biu(self):            #处理已发射出的子弹
        for biu_i in bu_list:
            biu_i.display()
            biu_i.run()

紧接着是敌机的类:(忽略我自己写着玩玩的塑料英语 ^ _ ^)

class DJ_plan():                   #定义敌机自身属性
    def __init__(self,img,x,y,window): #初始化变量
        self.img=pygame.image.load(img)
        self.x=x
        self.y=y
        self.window=window
        # self.is_bool=False

    def diji_display(self):
        self.window.blit(self.img,(self.x,self.y))     #初始化敌机

    def run(self):                 #对于敌机的飞行定义就容易很多,用run一个函数来实现
        self.y+=1
        if self.y>height:
            self.x=random.randint(0,350)  #敌机出现的横向位置是随机的
            self.y=0

    def if_touch(self,hero):    #定义如果英雄碰到敌机时的事件函数
        if pygame.Rect.colliderect(pygame.Rect(self.x,self.y,51,39),     #矩形的对撞
                pygame.Rect(hero.x,hero.y,100,124)):
            return True
        else:
            return False

子弹类:

class Bullet():    #子弹类的定义
    def __init__(self,img,x,y,window):  #初始化
        self.img=pygame.image.load(img)
        self.x=x
        self.y=y
        self.window=window

    def display(self):  #刷新
        self.window.blit(self.img,(self.x,self.y))

    def run(self):  #子弹飞行的速度在此更改
        self.y-=3

    def if_touch(self,dj):  #定义如果子弹击中引起的事件函数
        if pygame.Rect.colliderect(pygame.Rect(self.x,self.y,22,22),     #矩形的对撞函数
                pygame.Rect(dj.x,dj.y,51,39)):
            return True
        else:
            return False

下面是hit(子弹击中敌机函数)的定义:

def hit(dj_plan):           #子弹击中敌机的函数
    for fire_i in bu_list:  # 在子弹列表中的某一颗子弹
        for dj_i in dj_list:  # 在敌机列表中的某一架敌机
            if fire_i.if_touch(dj_i):  # 如果它俩相遇发生爆炸
                img = pygame.image.load("boom.jpg")  # 这里是相对路径,将img变为爆炸的图片
                dj_plan.window.blit(img, (dj_plan.x, dj_plan.y))  # 把刷新爆炸的图片刷新出来
                dj_plan.is_touch = False
                pygame.display.update()  # 再刷新一遍
                pygame.time.delay(300)  # 图片停留多长时间
                dj_plan.x = random.randint(0,450)  # 重新生成一个敌机
                dj_plan.y = 0
                bu_list.remove(fire_i)  # 碰到敌机后删除子弹

touch(英雄自身被敌机碰到时的函数)定义:

def touch(hero,dj_plan,window):       #英雄自身被敌机碰到
    for dj_i in dj_list:
        if dj_i.if_hero_touch(hero):        #如果这个敌机触碰到了英雄
            dj_plan.x = random.randint(0, 350)  # 重新生成一个敌机
            dj_plan.y = 0
            global count
            count -= 5
            font = pygame.font.SysFont("思源黑体", 30)  # 设置字体和大小
            text_surface = font.render("count:" + str(count), True, (0, 255, 0))
            window.blit(text_surface, (20, 20))

一个背景音乐函数的定义:

def music():
    filename = "Panama .mp3" #这里采用的也是相对路径,我的该歌曲是放在py文件旁边,读者可根据自身情况自行更改。
    pygame.mixer.init()
    pygame.mixer.music.load(filename)
    pygame.mixer.music.set_volume(0.2)
    pygame.mixer.music.play(loops=-1)  # loops 对应的值为 -1 则音乐会无限循环播放

最后就是把他们综合到一起的主函数了

width=490 #游戏界面宽度定义
height=870  #游戏界面高度定义
dj_list=[]  #敌机列表
bu_list=[]  #子弹列表
count = 100   #这里的count是初始分值,分值低于0分游戏结束。

def main():
    pygame.init()       #初始化pygame

    music()             #运行时加上背景音乐

    window=pygame.display.set_mode((width,height))  #新建游戏窗口
    bg_img=pygame.image.load("background.jpg")    #用pygame进行转化,转化为图片,填充背景图图片
    hero=Hero("hero.png",210,680,window)           #传入主机及位置

    font = pygame.font.SysFont("思源黑体", 30)       #设置字体和大小
    text_surface = font.render("count:" + str(count), True, (0, 255, 0))   #设置内容和颜色

    dj_plan=DJ_plan("enemy.png",random.randint(0,350),0,window)   #传入敌机及位置
    dj_list.append(dj_plan)

    while count>=0:      #用循环检测键盘操作,并输出
        window.blit(bg_img,(0,0))     #在游戏窗口上显示背景图片,背景图片比游戏窗口大,否则窗口周边将用黑边填充
        hero.display()                #主机初始化
        hero.fire_biu()
        window.blit(text_surface, (20, 20))    #在窗口刷新出文字

        for dj_i in dj_list:        #产生敌机
            dj_i.run()
            dj_i.diji_display()     #敌机初始化,随机刷新敌机位置
        pygame.display.update()     #刷新页面

        hit(dj_plan)               #子弹打中敌机时,完成删除子弹,改变照片并且重新生成敌机的功能
        touch(hero,dj_plan,window)   #敌机碰到英雄时,删除敌机并减分

        # print(count)

        for event in pygame.event.get():    #检测键盘输入事件
            if event.type==QUIT:            #如果点击quit,则系统退出
                pygame.quit()
                sys.exit()
            elif event.type==KEYDOWN:
                if event.key == K_SPACE:    #点击空格发射子弹
                    hero.fire()

        pressed_keys = pygame.key.get_pressed()     #移动按钮绑定
        if pressed_keys[pygame.K_LEFT] or pressed_keys[pygame.K_a]:   #点左键或者a键英雄左移
                    hero.move_left()
        elif pressed_keys[pygame.K_RIGHT] or pressed_keys[pygame.K_d]:   #点右键或者d键英雄右移
                    hero.move_right()
        elif pressed_keys[pygame.K_UP] or pressed_keys[pygame.K_w]:    #点上或者w英雄上移
                    hero.move_up()
        elif pressed_keys[pygame.K_DOWN] or pressed_keys[pygame.K_s]:    #点下或者s英雄下移
                    hero.move_down()
        # elif pressed_keys[pygame.K_SPACE]:   #连续发射,柱状子弹的代码
        #             hero.fire()

读者到此就可以把之前所有的子模块和这个主函数粘贴到一个py文件里,然后让他们运行一下,就可以玩这个小游戏了。
运行代码:

if __name__ == '__main__':
    main()

运行方式:在py文件上点击鼠标右键,找到Run’py文件名‘这个选项,点击,即可弹出游戏窗口开始游戏。

这里在攻击方式上我还找到了一种柱状子弹的攻击形式,也蛮好玩的。代码为:

elif pressed_keys[pygame.K_SPACE]:   #连续发射,柱状子弹的代码
            hero.fire()

在上面的主函数代码块里也有,只不过是注释掉了的,想玩的读者把上面主函数里的用ctrl+/快捷键解注释了也可以。

还有一种就是我刚开始第一遍写的时候使用的按一下英雄动一下方法,比较容易写出来,按时游戏体验不好哈,也放一个代码在这里:

if event.type == KEYDOWN:
	if event.key == K_SPACE:
         hero.fire()
     elif event.key == K_LEFT:
         print("left")
         hero.move_left()
     elif event.key == K_RIGHT:
         print("right")
         hero.move_right()
     elif event.key == K_SPACE:
         print("biu")
     elif event.key == K_UP:
         print("up")
         hero.move_up()
     elif event.key == K_DOWN:
         print("down")
         hero.move_down()

这就是这个小游戏的全部代码了。注释详细,有问题可以微信联系作者haun_neither

另附一些图片素材:
background.jpg
在这里插入图片描述
boom.jpg
在这里插入图片描述
bullet.jpg
在这里插入图片描述
enemy.png
在这里插入图片描述
hero.png
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!