Python 飞机大战

代码(每一处都有注释)

代码和素材在GitHub:https://github.com/kongbaiblog/Python-feijidazhan
需要用到的模块:pygame,sys,os,random,threading,time
整个目录:在这里插入图片描述

play.py:

#导入模块
import pygame
from pygame import *
import sys,os,random,threading  #threading是用来开线程的模块
import time as tm
from threading import *

#获取文件位置,对路径加工成可以调用的形式
path=os.getcwd()
path=list(path)
i=0
while i<len(path):
    if path[i]=='\\':
        path[i]='/'
    i+=1
path=''.join(path)
print(path)

#一些设置的初始值,见 set.ini
mouse_ctrl=False
T_cd=0.5
R_cd=10
MouseL_cd=10
my_plain_can_kill=[False,True]
background=0
Get_Tick=100

#读取set.ini文件
with open((path+'/set.ini'),'r',encoding='utf-8') as f:
    get_set=f.readlines()
    print(get_set)

#分析set.ini中的设置
line=0
while True:
	# 井号表示注释,读取时直接跳过
    if '#' in get_set[line] and line+1<len(get_set):
        line+=1
    # 获取游戏的控制方式
    if 'control' in get_set[line]:
        #print(get_set[line][8:-1])
        if '0' in get_set[line]:
            mouse_ctrl=False
        if '1' in get_set[line]:
            mouse_ctrl=1
    # 获取T技能的cd(下面的E的类中有对T技能的解释)
    if 'T=' in get_set[line]:
        if '\\n' in get_set[line]:
            T_cd=get_set[line][2:-1]
        else:
            T_cd=get_set[line][2:-1]
        print(T_cd)
    # 获取R技能的cd(下面的T的类中有对R技能的解释)
    if 'R' in get_set[line]:
        if '\\n' in get_set[line]:
            R_cd=get_set[line][2:-1]
        else:
            R_cd=get_set[line][2:]
    # 获取鼠标左键技能的cd(下面的MouseL的类中有对鼠标左键技能的解释)
    if 'MouseL' in get_set[line]:
        if '\\n' in get_set[line]:
            MouseL_cd=get_set[line][7:-1]
        else:
            MouseL_cd=get_set[line][7:]
    # 获取玩家飞机是否会爆炸
    if 'my_plain_kill' in get_set[line]:
        if '1' in get_set[line]:
            my_plain_can_kill=[False,False]
        if '0' in get_set[line]:
            my_plain_can_kill=[False,True]
    # 获取窗口背景是否显示,1为显示,0为不显示
    if 'background' in get_set[line]:
        if '1' in get_set[line]:
            background=1
        if '0' in get_set[line]:
            background=0
    # 获取窗口刷新速率
    if 'Tick' in get_set[line]:
        if '\\n' in get_set[line]:
            Get_Tick=float(get_set[line][5:-1])
        else:
            Get_Tick=float(get_set[line][5:])
        #print(Get_Tick)
    if line+1==len(get_set):
        break
    line+=1
# 敌飞机初始化
back_other_plain=0
back_other_plain_two=0
back_other_plain_three=0

#各种延时的线程
#前三个线程表示敌飞机爆炸后会有1秒停顿然后被重置
def Celled_Time():
    global back_other_plain
    tm.sleep(1)
    back_other_plain=1
    #print("线程T1")
def Celled_Time_T2():
    global back_other_plain_two
    tm.sleep(1)
    back_other_plain_two=1
    #print("线程T2")
def Celled_Time_T7():
    global back_other_plain_three
    tm.sleep(1)
    back_other_plain_three=1
    #print("线程T7")
#三个技能的cd时间
def R_Time():
    #print('线程T3')
    R.R_lock=True
    R.R_pic=pygame.image.load(path+'/pic/RjinengLock.png')
    tm.sleep(float(R_cd))
    R.R_lock=False
    R.R_pic=pygame.image.load(path+'/pic/Rjineng.png')
def T_Time():
    #print('线程T4')
    E.E_pic=pygame.image.load(path+'/pic/Tjinenglock.png')
    E.E_lock=True
    tm.sleep(float(T_cd))
    E.E_lock=False
    E.E_pic=pygame.image.load(path+'/pic/Tjineng.png')
def MOUSE_Time():
    #print('线程5')
    MOUSEL.MOUSE_lock=True
    MOUSEL.MOUSE_pic=pygame.image.load(path+'/pic/shubiaoLlock.png')
    tm.sleep(int(MouseL_cd))
    MOUSEL.MOUSE_lock=False
    MOUSEL.MOUSE_pic=pygame.image.load(path+'/pic/shubiaoL.png')
#开局三秒无敌时间
def Can_not_kill_Time():
    tm.sleep(3)
    global my_plain_can_kill
    my_plain_can_kill[0]=True

#各种线程定义
threading_number=0
catch=threading.Thread(target=Celled_Time,name='T1',daemon=False)
T2_number=0
catch_T2=threading.Thread(target=Celled_Time_T2,name='T2',daemon=False)
T7_number=0
catch_T7=threading.Thread(target=Celled_Time_T7,name='T7',daemon=False)
R_number=0
catch_R=threading.Thread(target=R_Time,name='T3',daemon=False)
T_number=0
catch_T=threading.Thread(target=T_Time,name='T4',daemon=False)
MOUSE_number=0
catch_MOUSE=threading.Thread(target=MOUSE_Time,name='T5',daemon=False)
can_not_kill_number=0
can_not_kill=threading.Thread(target=Can_not_kill_Time,name='T6',daemon=False)

#敌飞机的类(有三个敌飞机)
class Other_plain:
    '''敌飞机'''
    other_plain=pygame.image.load(path+"/pic/otherfly.png")
    other_plain_rect=other_plain.get_rect()
    other_plain_two=pygame.image.load(path+'/pic/otherfly2.png')
    other_plain_two_rect=other_plain_two.get_rect()
    other_plain_three=pygame.image.load(path+'/pic/otherfly3.png')
    other_plain_three_rect=other_plain_three.get_rect()
    other_plain_three_rect.x=random.randint(0,650)
    other_plain_two_rect.x=random.randint(0,650)
    other_plain_rect.x=random.randint(0,650)
    otherx=0
    othery=1
    otherx_t=0
    othery_t=1
    otherx_three=0
    othery_three=1
    speed=[otherx,othery]
    other_two_lock=False
    kill_lock=[False,False,False]   #三个飞机的状态

#子弹的类
class Bullet:
    '''子弹'''
    bullet=pygame.image.load(path+'/pic/bullet.png')
    bullet_rect=bullet.get_rect()
    speed=[0,-1]

#三个技能的类
#R技能是直接使所有敌飞机爆炸
class R:
    '''R技能'''
    other_plain_kill=False
    R_lock=False
    R_pic=pygame.image.load(path+'/pic/Rjineng.png')    #color: #0099ff
    R_pic_rect=R_pic.get_rect()
    R_pic_rect.x=700
    R_pic_rect.y=900

#T技能是在最后按的方向上进行一段位移
class E:
    '''T技能,一开始是E,但E按键不得劲,所以改成了T,E这个类就不改了'''
    E_move=100
    E_lock=False
    E_pic=pygame.image.load(path+'/pic/Tjineng.png')
    E_pic_rect=E_pic.get_rect()
    E_pic_rect.x=600
    E_pic_rect.y=900
    last_key='w'

#鼠标左键是直接传送到鼠标左键所点击的位置
class MOUSEL:
    '''鼠标技能'''
    MOUSE_lock=False
    MOUSE_pic=pygame.image.load(path+'/pic/shubiaoL.png')
    MOUSE_pic_rect=MOUSE_pic.get_rect()
    MOUSE_pic_rect.x=500
    MOUSE_pic_rect.y=900

#游戏结束显示的两个选项(简直是卡爆了)
class GAME_OVER:
    '''游戏结束'''
    regame_pic=pygame.image.load(path+'/pic/regame.png')
    regame_pic_rect=regame_pic.get_rect()
    exit_pic=pygame.image.load(path+'/pic/exit.png')
    exit_pic_rect=exit_pic.get_rect()
    regame_pic_rect.x=100
    regame_pic_rect.y=200
    exit_pic_rect.x=100
    exit_pic_rect.y=430

#pygame初始化
pygame.init()
size=width,heigh=800,1000
screen=pygame.display.set_mode(size)
color=(0,0,0)
pygame.display.set_caption('飞机大战')

#玩家飞机的设置
my_plain=pygame.image.load(path+"/pic/myfly.png")   #  68*48
my_plain_rect=my_plain.get_rect()
my_plain_rect.x=200
my_plain_rect.y=750
my_plain_how=True
clock=pygame.time.Clock()
speedn=10   #速度
biu=0     #限制子弹数量
point=0    #分数
point_output=0
last_key="w"   #默认最后按的方向键是w(向前)
can_not_kill.start()          #进入开局无敌时间的线程

#print(random.randint(0,500))
#调用下面这两个类
other=Other_plain()
bullet=Bullet()


while 1:
    speed=[0,0]
    #玩家存活时,敌飞机获取相应速度
    if my_plain_how==True:
        speed_other=[other.otherx,other.othery]
        speed_other_two=[other.otherx_t,other.othery_t]
        speed_other_three=[other.otherx_three,other.othery_three]
    #当玩家阵亡,敌飞机停止运动
    if my_plain_how==False:
        speed_other=[0,0]
        speed_other_two=[0,0]
        speed_other_three=[0,0]

    #键盘事件
    for event in pygame.event.get():

        key_pressed=pygame.key.get_pressed()
        #方向移动,w(前进),a(向左),s(后退),d(向右)
        if my_plain_how==True:
            if key_pressed[K_w]:
                speed[1]-=speedn
                E.last_key='w'
                #print('w')
            if key_pressed[K_s]:
                speed[1]+=speedn
                E.last_key='s'
            if key_pressed[K_a]:
                speed[0]-=speedn
                E.last_key='a'
            if key_pressed[K_d]:
                speed[0]+=speedn
                E.last_key='d'
            #子弹射出
            if key_pressed[K_SPACE] and biu!=2:
                #print('biu~')
                biu=1
            #玩家转向,按住左侧CTRL键同时按住相应方向键
            if key_pressed[K_LCTRL] and key_pressed[K_p]:
                print('己方飞机坐标:',my_plain_rect.x,',',my_plain_rect.y)
                print('\n敌方飞机:',other.other_plain_rect.x,',',other.other_plain_rect.y)
            if key_pressed[K_LSHIFT] and key_pressed[K_w]:
                my_plain=pygame.image.load(path+'/pic/myfly.png')
                last_key='w'
            if key_pressed[K_LSHIFT] and key_pressed[K_s]:
                my_plain=pygame.image.load(path+'/pic/myflyB.png')
                last_key='s'
            if key_pressed[K_LSHIFT] and key_pressed[K_a]:
                my_plain=pygame.image.load(path+'/pic/myflyL.png')
                last_key='a'
            if key_pressed[K_LSHIFT] and key_pressed[K_d]:
                my_plain=pygame.image.load(path+'/pic/myflyR.png')
                last_key='d'
            #R技能释放后进入cd
            if key_pressed[K_r] and R.R_lock==False:
                R.other_plain_kill=True
                try:
                    catch_R.start()
                except:
                    catch_R='catch_R'+str(R_number)
                    catch_R=threading.Thread(target=R_Time,name='T3',daemon=False)
                    catch_R.start()
                    R_number+=1
            #T技能释放后进入cd
            if key_pressed[K_t] and E.E_lock==False and mouse_ctrl!=1:
                if E.last_key=='d':
                    my_plain_rect.x+=E.E_move
                    if my_plain_rect.x+E.E_move>width:
                        my_plain_rect.x=750
                if E.last_key=='a':
                    my_plain_rect.x-=E.E_move
                    if my_plain_rect.x-E.E_move<0:
                        my_plain_rect.x=50
                if E.last_key=='w':
                    my_plain_rect.y-=E.E_move
                    if my_plain_rect.y-E.E_move<0:
                        my_plain_rect.y=50
                if E.last_key=='s':
                    my_plain_rect.y+=E.E_move
                    if my_plain_rect.y+E.E_move>heigh:
                        my_plain_rect.y=950
                try:
                    catch_T.start()
                except:
                    catch_T='catch_T'+str(T_number)
                    catch_T=threading.Thread(target=T_Time,name='T4',daemon=False)
                    catch_T.start()
                    T_number+=1


        if event.type==pygame.QUIT:
            print("QUIT")
            pygame.quit()
            sys.exit()
        #鼠标左键技能释放后进入cd
        if event.type==pygame.MOUSEBUTTONDOWN and mouse_ctrl==False and MOUSEL.MOUSE_lock==False and my_plain_how==True:
            go_to=pygame.mouse.get_pos()
            my_plain_rect.x=go_to[0]
            my_plain_rect.y=go_to[1]
            print('传送至坐标:',go_to)
            try:
                catch_MOUSE.start()
            except:
                catch_MOUSE='catch_MOUSE'+str(MOUSE_number)
                catch_MOUSE=threading.Thread(target=MOUSE_Time,name='T5',daemon=False)
                catch_MOUSE.start()
                MOUSE_number+=1
        #玩家阵亡后画面判定
        if event.type==pygame.MOUSEBUTTONDOWN and my_plain_how==False:
            if 100<=pygame.mouse.get_pos()[0]<=730:  #x:100,730   y:200,380 #x:100,730   y:430,610
                if 200<=pygame.mouse.get_pos()[1]<=380:
                    print('游戏重启中...')
                    try:
                        os.system('start '+path+'/play.py')
                    except:
                        os.system('start '+path+'/play.exe')
                    exit()
                if 430<=pygame.mouse.get_pos()[1]<=610:
                    print('退出中...')
                    exit()

    clock.tick(Get_Tick)

    #防止玩家出地图
    if my_plain_rect.right>width:
        speed[0]=-1
    if my_plain_rect.left<0:
        speed[0]=1
    if my_plain_rect.bottom>heigh:
        speed[1]=-1
    if my_plain_rect.top<0:
        speed[1]=1

    #敌飞机出地图后重置
    if (other.other_plain_rect.y>heigh):
        other.other_plain_rect.y=1
        other.other_plain_rect.x=random.randint(0,650)
    if other.other_plain_two_rect.y>heigh:
        other.other_plain_two_rect.y=1
        other.other_plain_two_rect.x=random.randint(0,650)
    if other.other_plain_three_rect.y>heigh:
        other.other_plain_three_rect.y=1
        other.other_plain_three_rect.x=random.randint(0,650)
    #print(other.other_plain_rect.y)

    #确定子弹位置
    if biu==1:
        bullet.bullet_rect.x=my_plain_rect.x
        bullet.bullet_rect.y=my_plain_rect.y
        biu=2
    #子弹移动
    if biu==2:
        if last_key=='w':
            bullet.speed[1]-=1
        if last_key=='s':
            bullet.speed[1]+=1
        if last_key=='a':
            bullet.speed[0]-=1
        if last_key=='d':
            bullet.speed[0]+=1

    #子弹出图重置
    if bullet.bullet_rect.y<0 or bullet.bullet_rect.y>heigh or bullet.bullet_rect.x<0 or bullet.bullet_rect.x>width:
        bullet.bullet_rect.x=-10
        bullet.bullet_rect.y=-10
        biu=0
        bullet.speed=[0,0]


    if bullet.speed==[0,0]:
        bullet.bullet_rect.x=my_plain_rect.x
        bullet.bullet_rect.y=my_plain_rect.y-10

    #三个敌飞机死亡判定和重置
    if back_other_plain==1:
        #print("change")
        other.other_plain=pygame.image.load(path+'/pic/otherfly.png')
        other.othery=1
        other.other_plain_rect.x=random.randint(0,650)
        other.other_plain_rect.y=0
        back_other_plain=0
        other.kill_lock[0]=False


    if back_other_plain_two==1:
        #print("T2 True")
        other.other_plain_two=pygame.image.load(path+'/pic/otherfly2.png')
        other.othery_t=1
        other.other_plain_two_rect.x=random.randint(0,650)
        other.other_plain_two_rect.y=0
        back_other_plain_two=0
        other.kill_lock[1]=False

    if back_other_plain_three==1:
        #print("T7 True")
        other.other_plain_three=pygame.image.load(path+'/pic/otherfly3.png')
        other.othery_three=1
        other.other_plain_three_rect.x=random.randint(0,650)
        other.other_plain_three_rect.y=0
        back_other_plain_three=0
        other.kill_lock[2]=False

    #判定敌飞机是否爆炸,爆炸后进入重置延时线程
    if ((other.other_plain_rect.x-30)<=bullet.bullet_rect.x<=(other.other_plain_rect.x+30) and (other.other_plain_rect.y-20)<=bullet.bullet_rect.y<=(other.other_plain_rect.y+20) or R.other_plain_kill==True) and other.kill_lock[0]==False:
        point+=1
        print(point)
        other.kill_lock[0]=True
        other.othery=0
        other.other_plain=pygame.image.load(path+'/pic/otherflyboom.png')
        try:
            catch.start()
        except:
            catch='catch'+str(threading_number)
            threading_number+=1
            catch=threading.Thread(target=Celled_Time,name='T1'+str(threading_number),daemon=False)
            catch.start()
    #print(back_other_plain)


    if ((other.other_plain_two_rect.x-30)<=bullet.bullet_rect.x<=(other.other_plain_two_rect.x+30) and (other.other_plain_two_rect.y-20)<=bullet.bullet_rect.y<=(other.other_plain_two_rect.y+20) or R.other_plain_kill==True) and other.kill_lock[1]==False:
        point+=1
        print(point)
        other.kill_lock[1]=True
        other.othery_t=0
        other.other_plain_two=pygame.image.load(path+'/pic/otherflyboom.png')
        try:
            catch_T2.start()
        except:
            catch_T2='catch'+str(T2_number)
            T2_number+=1
            catch_T2=threading.Thread(target=Celled_Time_T2,name='T2'+str(T2_number),daemon=False)
            catch_T2.start()

    if ((other.other_plain_three_rect.x-30)<=bullet.bullet_rect.x<=(other.other_plain_three_rect.x+30) and (other.other_plain_three_rect.y-20)<=bullet.bullet_rect.y<=(other.other_plain_three_rect.y+20) or R.other_plain_kill==True) and other.kill_lock[2]==False:
        point+=1
        print(point)
        other.kill_lock[2]=True
        other.othery_three=0
        other.other_plain_three=pygame.image.load(path+'/pic/otherflyboom.png')
        try:
            catch_T7.start()
        except:
            catch_T7='catch'+str(T7_number)
            T7_number+=1
            catch_T7=threading.Thread(target=Celled_Time_T7,name='T7'+str(T7_number),daemon=False)
            catch_T7.start()

    #玩家死亡判定
    if ((other.other_plain_rect.y-40)<=my_plain_rect.y<=(other.other_plain_rect.y+40) or (other.other_plain_two_rect.y-40)<=my_plain_rect.y<=(other.other_plain_two_rect.y+40) or (other.other_plain_three_rect.y-40)<=my_plain_rect.y<=(other.other_plain_three_rect.y+40)) and my_plain_can_kill==[True,True]:
       # print('敌飞机1:',other.other_plain_rect.x,',',other.other_plain_rect.y,'\n','敌飞机2:',other.other_plain_two_rect.x,',',other.other_plain_two_rect.y,'\n','我方飞机:',my_plain_rect.x,',',my_plain_rect.y)
        my_plain=pygame.image.load(path+'/pic/myflyboom.png')
        my_plain_how=False
        other.speed=[0,0]
        speed_other_two=[0,0]
        if point_output==0:
            print('————————————————分数为:',point,'————————————————')
            point_output+=1

    #鼠标操作模式
    if mouse_ctrl==True and my_plain_how==True:
        go_to=pygame.mouse.get_pos()
        my_plain_rect.x=go_to[0]
        my_plain_rect.y=go_to[1]
        
    #玩家飞机敌飞机以及子弹移动
    my_plain_rect=my_plain_rect.move(speed)
    other.other_plain_three_rect=other.other_plain_three_rect.move(speed_other_three)
    other.other_plain_two_rect=other.other_plain_two_rect.move(speed_other_two)
    other.other_plain_rect=other.other_plain_rect.move(speed_other)
    bullet.bullet_rect=bullet.bullet_rect.move(bullet.speed)
    screen.fill(color)
    #判定背景是否加载
    if background==1:
        screen.blit(pygame.image.load(path+'/pic/bg.png'),(0,0))
        
    #显示玩家飞机敌飞机以及子弹和R技能
    screen.blit(other.other_plain,other.other_plain_rect)
    screen.blit(other.other_plain_two,other.other_plain_two_rect)
    screen.blit(other.other_plain_three,other.other_plain_three_rect)
    screen.blit(bullet.bullet,bullet.bullet_rect)
    screen.blit(my_plain,my_plain_rect)
    screen.blit(R.R_pic,R.R_pic_rect)
    
    #当玩家不是用鼠标控制,显示T技能和鼠标左键技能
    if mouse_ctrl!=1:
        screen.blit(E.E_pic,E.E_pic_rect)
        screen.blit(MOUSEL.MOUSE_pic,MOUSEL.MOUSE_pic_rect)
        
    #当玩家阵亡,显示结束画面
    if my_plain_how==False:
        screen.blit(GAME_OVER.regame_pic,GAME_OVER.regame_pic_rect)
        screen.blit(GAME_OVER.exit_pic,GAME_OVER.exit_pic_rect)
    
    #重置R技能    
    R.other_plain_kill=False
    pygame.display.update()

set.ini:

#这玩应你删了也没啥事儿,正常玩肯定没毛病,就是没法设置下面这些玩应,主程序有默认设置
#设置控制飞机的方式,0为键盘控制,1为鼠标控制
control=0
#设置技能cd时间T表示T技能以此类比,时间参数以秒为单位
T=0.5
R=10
MouseL=10
#飞机无敌,0表示不无敌,1表示无敌
my_plain_kill=0
#游戏内容刷新速度
Tick=100
#打开游戏背景,1为打开,0为不打开,设置这个是因为打开后游戏会很慢,但背景画了不舍得删
#(虽然画的很简单)
background=0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值