pygame-飞机大战(下·三)

(二)中介绍了Kinds文件下下的类,但大多数都大同小异,除了贴图和更新函数的更新法则不同外,其他相同,而只有特殊的例如Ship、BOSS等含有多个不同的地方,其中由于Ship是主控元素,为了简单起见把界面的部分数据的显示也放入了该类里。

 

接下来介绍各个界面以及界面的鼠标点击触发函数。

在UI文件夹下的界面大部分采用draw函数代替update函数。draw函数在UIMgr的update函数里根据当前的状态被调用。

1.显示文档Display.py:

Display用于在界面中显示txt文档的全部内容,显示文档需要三个参数:total、current_line、和k。total表示一页显示的最大行数,在此设置为15,current_line表示当前页第一行基于整个文件第一行的偏移,即通过点击pre或next按钮更改current_line的值实现翻页。k为每次绘制时遍历的当前页面的行号,每次绘制时初始化为0,最高为total。每一页某一行的相对于整个文档的行号为k+current_line。

Display的初始化函数输入参数为text和icon,text为已经已经读取的txt文件,不同的icon值会有不同的文字格式和背景。

Display页面一共三个按钮:pre、next和back。pre按钮点击会往前翻一页(check_pre),next点击会往后翻一页(check_next),back按钮会返回到主菜单页面(check_back )。触发点击函数check需要在初始化中声明按钮的rect,可通过pygame.Rect()创建,并在(下·一)的UIMgr的check_Mouse被调用。

#在窗口内显示文字信息
import pygame.font
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Logic.GameStates import GStI

class Display(DrawOn):
    def __init__(self,text,icon=0): #icon=0 白色 icon=1 help 2:logo 3:rank
        super().__init__()
        super(Display,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=(0,0,1200,800)
        self.bg_color=(255,255,255)
        self.text_color=(255,215,0)
        pygame.font.init()
        if icon!=3:
            self.font_format = pygame.font.Font("fonts/TianGeKaiTi.TTF",30)
        else:
             self.font_format = pygame.font.Font("fonts/Mouse.otf",30)
        self.total=15 #一页显示最多个数
        self.current_line=0#当前行数 点击next或pre翻页
        self.length=len(text)
        self.text=text
        (self.back_width, self.back_height)=(200,111)
        (self.change_width,self.change_height)=(76,100)
        if icon==1:
            self.bg=pygame.image.load('images/bg_help.jpg')
            self.bg=pygame.transform.scale(self.bg,(1200,800))
        elif icon==2:
            self.bg=pygame.image.load('images/bg_logo.png')
            self.bg=pygame.transform.scale(self.bg,(1200,800))  
        else:
            self.bg=pygame.image.load('images/bg_rank.png')
            self.bg=pygame.transform.scale(self.bg,(1200,800)) 
        self.image_back=pygame.image.load('icons/back.png')
        self.image_next=pygame.image.load('icons/next.png')
        self.image_pre=pygame.image.load('icons/pre.png')
        self.image_back=pygame.transform.scale(self.image_back,(self.back_width,self.back_height))
        self.image_next=pygame.transform.scale(self.image_next,(self.change_width,self.change_height))
        self.image_pre=pygame.transform.scale(self.image_pre,(self.change_width,self.change_height))
        self.back_rect=pygame.Rect(0,0,self.back_width, self.back_height)
        self.next_rect=pygame.Rect(50,400,self.change_width, self.change_height)
        self.pre_rect=pygame.Rect(50,300,self.change_width, self.change_height)
    
    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        k=0
        self.screen.blit(self.bg,(0,0,1200,800))
        self.screen.blit(self.image_back,(0,0,200,111))
        self.screen.blit(self.image_next,(50,400,76,100))
        self.screen.blit(self.image_pre,(50,300,76,100))
        
        while k<self.total and k+self.current_line<self.length:
            self.font=self.font_format.render(self.text[k+self.current_line],True,self.text_color)
            self.imag=self.font.get_rect()
            self.imag_rect=(200,50*k+10)
            self.screen.blit(self.font,self.imag_rect)
            k+=1
        

    def show(self):
        self.pre_draw()
    
    def check_back(self):
        GStI.game_active=False
        GStI.display_active=False
        GStI.help_active=False
        GStI.rank_active=False
        GStI.ui=True
        
    def check_next(self):
        if self.current_line<self.length-15:
            self.current_line+=self.total
    
    def check_pre(self):
        if self.current_line>=15:
            self.current_line-=self.total

RankGame、HelpGame和logo中会读取对应的文件并调用Display来显示界面,除此之外,RankGame和HelpGame、BeginGame、QuitGame、AchisGame会读取对应在主界面上显示的主入口按钮,并在draw中绘制,响应的check函数定义了在主界面点击响应入口按钮的效果,除check函数外其他大体相同。

RankGame.py:

点击rank按钮显示排名。

import pygame.font
from Codes.Logic.GameStates import GStI
from Codes.Base.Screen import SI
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.GameSettings import GSeI
from Codes.UI.Display import Display

class RankGame(DrawOn):
    def __init__(self ):
        super().__init__()
        super(RankGame,self).definePriority(9)
        f=open('rank.txt').readlines()
        self.DisplayUI=Display(f,3)
        self.screen=SI.screen
        self.screen_rect=self.screen.get_rect()
        self.width, self.height=192,74
        self.image=pygame.image.load('icons/rank.png')
        self.image=pygame.transform.scale(self.image,(self.width,self.height))
        self.image_rect=(0.5*GSeI.screen_width-0.5*self.width,0.595*GSeI.screen_height-0.5*self.height)
        self.rect=pygame.Rect(0.5*GSeI.screen_width-0.5*self.width,0.595*GSeI.screen_height-0.5*self.height,self.width,self.height)

    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.image,self.image_rect)

    def show(self):
        self.pre_draw()

    def check(self):
        GStI.game_active=False
        GStI.rank_active=True
        GStI.ui=False

其他类和RankGame很相似,只有check函数不同,只介绍check。

HelpGame.py:

点击显示帮助。

 

    def check(self):
        GStI.game_active=False
        GStI.help_active=True
        GStI.ui=False

QuitGame.py:

点击退出。

    def check(self):
        GStI.game_active=False
        GStI.reset_stats()
        pygame.quit()
        sys.exit()

BeginGame.py:

点击显示游戏背景(游戏开始前兆)。

    def check(self):
        GStI.background=True
        GStI.ui=False
        GStI.reset_stats()

logo.py:

点击三次logo显示工作日志:

    def check(self):
        self.caidan+=1
        if self.caidan==3:#设置彩蛋:当点击logo三次后会显示logo
            self.caidan=0
            GStI.game_active=False
            GStI.display_active=True
            GStI.ui=False

AchisGame.py:

点击显示成就页面,由于不需要显示文档,所以代码里不需要调用Display,而仅仅是显示按钮和点击改变状态。

    def check(self):
        GStI.game_active=False
        GStI.achis_active=True
        GStI.ui=False

点击开始游戏按钮BeginGame会进入显示背景页面:

Display_bg.py:

首先背景为“背景0.jpg”,背景文字为“背景0.png”。进入该界面后,背景直接显示,而背景文字会缓缓从下端上浮。(通过self.i的更新),如果文字到达顶端,则显示两个按钮,左侧按钮代表退出回到主界面,右侧按钮代表进入游戏,对应的点击函数分别为check_refuse和check_accept。如果点击进入游戏,那么GameStates的first_play会置1,以后在主菜单点击BeginGame时不回进入显示背景页面而是关卡选择页面。如果背景文字正在滚动中在任意位置发生点击,则直接跳到结束,显示两个按钮。(UIMgr.py 150行~163行)。

 

 

import pygame.font
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Logic.GameStates import GStI

class Display_bg(DrawOn):
    def __init__(self):
        super().__init__()
        super(Display_bg,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=(0,0,1200,800)
        self.bg_image=pygame.image.load('images/背景0.jpg')
        self.bg_image=pygame.transform.scale(self.bg_image,(1200,800))
        self.te_image=pygame.image.load('images/背景0.png')
        self.te_image=pygame.transform.scale(self.te_image,(1200,800))        
        self.i=0
        self.button_acc=pygame.image.load('icons/accept.png')
        self.button_acc=pygame.transform.scale(self.button_acc,(200,67))
        self.button_ref=pygame.image.load('icons/refuse.png')
        self.button_ref=pygame.transform.scale(self.button_ref,(200,67))
      #  self.image_rect=(0,0)
        self.rect_ref=pygame.Rect(200,700,200, 67)
        self.rect_acc=pygame.Rect(700,700,200, 67)
    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.bg_image,(0,0,1200,800))
        self.screen.blit(self.te_image,(0,800-self.i,1200,800))
        if self.i<=800:
            self.i+=1
        else:
            self.screen.blit(self.button_ref,(200,700,200, 67))
            self.screen.blit(self.button_acc,(700,700,200, 67))
            #显示两个按钮

    def show(self):
        self.pre_draw()
    
    def check_accept(self):
        GStI.first_play=False
        GStI.game_active=True
        GStI.background=False
    def check_refuse(self):
        GStI.background=False
        GStI.ui=True

Pass_Choose.py:

关卡选择页面,当不是第一次进入游戏时(GameStates的first_play为False时),会显示关卡选择页面而不是显示背景页面。

该界面会显示一行文字,“请选择进入已经通关关卡:”和四个关卡的背景。如果这个关卡如果已经通过,则会显示彩色图片,否则显示黑白图像。可以点击已进入的关卡(彩色背景)。如果该关卡未被选中(无蓝框),则被点击的关卡变为被选中状态(带篮框),并且取消其他关卡的被选中状态。如果点击前该关卡已经被选中,那么会进入该关卡开始游戏。(click_pass函数)GameStates的pass_clear列表存放了四个数,分别代表四个关卡是否曾进入。pass_choose列表同样存放四个数,分别代表四个关卡是否被选中,只有一个为1(被选中)。黑白图像、彩色图像、被选中图像分别放在image_gray、image_rgb和image_select列表里。

import pygame.font
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Logic.GameStates import GStI
from Codes.Base.GameSettings import GSeI
from Codes.Battles.Battle1 import BI as Battle1
from Codes.Battles.Battle2 import BI as Battle2
from Codes.Battles.Battle3 import BI as Battle3
from Codes.Battles.Battle4 import BI as Battle4
Battles=[Battle1,Battle2,Battle3,Battle4]
class Pass_Choose(DrawOn):
    def __init__(self):
        super().__init__()
        super(Pass_Choose,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=(0,0,1200,800)
        self.bg_color=(29,49,73)
        self.text_color=(0,0,0)
        self.rect_list=list()
        pygame.font.init()
        self.font_title=pygame.font.Font("fonts/TianGeKaiTi.TTF",50)
        self.font_subtitle=pygame.font.Font("fonts/TianGeKaiTi.TTF",20)
        self.image_bg=pygame.image.load('images/bg_select.jpg')
        self.image_rgb=[pygame.image.load('images/pass1_rgb.jpg'),pygame.image.load('images/pass2_rgb.jpg'),
                        pygame.image.load('images/pass3_rgb.jpg'),pygame.image.load('images/pass4_rgb.jpg')]
        self.image_gray=[pygame.image.load('images/pass1_gray.jpg'),pygame.image.load('images/pass2_gray.jpg'),
                        pygame.image.load('images/pass3_gray.jpg'),pygame.image.load('images/pass4_gray.jpg')]
        self.image_select=[pygame.image.load('images/pass1_select.jpg'),pygame.image.load('images/pass2_select.jpg'),
                        pygame.image.load('images/pass3_select.jpg'),pygame.image.load('images/pass4_select.jpg')]
        self.image_pos_x=[250,650,250,650]
        self.image_pos_y=[200,200,500,500]
        for i in range(4):
            self.image_rgb[i]=pygame.transform.scale(self.image_rgb[i],(250,250))
            self.image_gray[i]=pygame.transform.scale(self.image_gray[i],(250,250))
            self.image_select[i]=pygame.transform.scale(self.image_select[i],(250,250))
            self.rect_list.append(pygame.Rect(self.image_pos_x[i],self.image_pos_y[i],250,250))

    def show(self):
        DCI.add(self)

    def draw(self):
        text =self.font_title.render("请选择进入已经通关关卡:",True,(255,215,0))
        self.screen.blit(self.image_bg,(0,0,1200,800))
        self.screen.blit(text,(200,70))
        for i in range(4):
            image=self.image_select[i]
            if GSeI.pass_choose[i]==1:
                image=self.image_select[i]
            elif GSeI.pass_clear[i]==1:
                image=self.image_rgb[i]
            else:
                image=self.image_gray[i]
            self.screen.blit(image,(self.image_pos_x[i],self.image_pos_y[i],200,200))
        text_list=["第一章","第二章","第三章","第四章"]
        for tl in range(4):
            if GSeI.pass_choose[tl]==1:
                text =self.font_title.render(text_list[tl],True,(215,0,0))
            else:
                text =self.font_title.render(text_list[tl],True,(0,215,215))
            self.screen.blit(text,(self.image_pos_x[tl]+50,self.image_pos_y[tl]+100))

    def click_pass(self,i):#点击关卡
        for index in range(4):
            if index==i and GSeI.pass_choose[i]:#如果已经被选中并切点击的是该关卡,进入游戏
                GStI.game_active=True
                temp=i+1
                GSeI.init()
                Battles[temp-1].init()
                GStI.current_checkpoint=temp
                GStI.background=False
            elif index==i and GSeI.pass_clear[i]:#否则该关卡被选中
                GSeI.pass_choose[index]=1
            else:#其他为选择的置为未选中
                GSeI.pass_choose[index]=0
      

死亡结算页面:

Display_die.py:

在飞机剩余生命不足时会退出游戏并进入该界面,该界面读取当前关卡的时间、本局击杀数、总共击杀数,并和背景一起绘制在屏幕上,同时在下方会有一个again按钮,当点击该按钮时则会退出死亡结算页面进入主菜单页面。

import pygame.font
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Logic.GameStates import GStI
from Codes.Base.GameSettings import GSeI
from Codes.Battles.Battle1 import BI as Battle1
from Codes.Battles.Battle2 import BI as Battle2
from Codes.Battles.Battle3 import BI as Battle3
from Codes.Battles.Battle4 import BI as Battle4
def returnbattle():
    Battles=[Battle1,Battle2,Battle3,Battle4]
    return Battles[GStI.current_checkpoint-1]


class Display_die(DrawOn):
    def __init__(self):
        super().__init__()
        super(Display_die,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=(0,0,1200,800)
        self.bg_image=pygame.image.load('images/die_bg.jpg')
        self.bg_image=pygame.transform.scale(self.bg_image,(1200,800))       
        self.button=pygame.image.load('icons/again.png')
        self.button=pygame.transform.scale(self.button,(100,67))
      #  self.image_rect=(0,0)
        self.rect=pygame.Rect(500,700,100, 67)
    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.bg_image,(0,0,1200,800))
        self.screen.blit(self.button,(500,700,100,67))
        BI=returnbattle()
        text1=str(int(BI.time))+'S'
        text2=str(BI.kill_fly)
        text3=str(GSeI.kill_fly)
        font1 = pygame.font.SysFont('kaiti', 36)
        textSurfaceObj1 = font1.render(text1, True, (255,0,0))
        textSurfaceObj2 = font1.render(text2, True, (255,0,0))
        textSurfaceObj3 = font1.render(text3, True, (255,0,0))
        textRectObj1 = textSurfaceObj1.get_rect()
        textRectObj1.center=(550,250)
        textRectObj2 = textSurfaceObj2.get_rect()
        textRectObj2.center=(970,390)
        textRectObj3 = textSurfaceObj3.get_rect()
        textRectObj3.center=(970,520)
        self.screen.blit(textSurfaceObj1, textRectObj1)
        self.screen.blit(textSurfaceObj2, textRectObj2)
        self.screen.blit(textSurfaceObj3, textRectObj3)

    def show(self):
        self.pre_draw()
    
    def check(self):
        GStI.die_active=False
        GStI.ui=True

金币商城页面:

StoreSys.py:

改界面读取了当前GameStates的参数,并和其他文字绘制在屏幕上,每行代表一个商品项,最后侧附带Buy按钮。商城一共分三个区,强化属性区、随机道具区和武器区。强化属性区为固定,随机道具将会在几个特殊道具中抽取一个显示,抽取在Ship的pause函数产生,随机结果将保存在GameSettings的item里;武器区,一共含有四个武器,如果该武器为当前持有,则右侧无按钮,如果已购买但不是当前持有,则显示蓝色USE,未购买则显示Buy按钮。随机道具区和强化属性区每行最右侧都含有Buy按钮。由于按钮过多,在draw最开始创建一个button列表,所有按钮初始化后放入该列表里。


import pygame
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Base.GameSettings import GSeI
from Codes.Logic.GameStates import GStI
from Codes.UI.Buy import Buy
from Codes.Battles.Battle1 import BI as Battle1
from Codes.Battles.Battle2 import BI as Battle2
from Codes.Battles.Battle3 import BI as Battle3
from Codes.Battles.Battle4 import BI as Battle4
def returnbattle():
    Battles=[Battle1,Battle2,Battle3,Battle4]
    return Battles[GStI.current_checkpoint-1]

class Store(DrawOn):
    def __init__(self):
        super().__init__()
        super(Store,self).definePriority(2)
        self.screen=SI.screen
        self.bg_width=GSeI.screen_width
        self.bg_height=GSeI.screen_height
        self.aliens_v=1
        self.aliens_scale=1
        self.bullets_scale=1
        self.image=pygame.image.load('images/bg_store.jpg')

        
    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.buttons=[]
        self.screen.blit(self.image,(0,0,1200,800))
        self.print_text("当前金币:"+str(returnbattle().gold)+'G',200,50,(0,0,0))
        text=[]
        text.append("当前敌机速度:"+str(GSeI.aliens_v_min)+"    降低0.1,需要花费")
        text.append("当前敌机体积:"+str(GSeI.aliens_size)+"    降低0.1,需要花费")
        text.append("当前子弹上限:"+str(GSeI.bullets_allowed)+"    提高上限1,需要花费")
        text.append("当前子弹体积:"+str(GSeI.bullet_width)+"    提高0.1,需要花费")
        text.append("当前子弹射速:"+str(GSeI.bullet_speed_factor)+"    提高0.1,需要花费")
        text.append("当前主机速度:"+str(GSeI.ship_speed_factor)+"    提高0.1,需要花费")
        text.append("当前飞机生命:"+str(GSeI.ship_limit)+"    提高上限1,需要花费")
        if GSeI.vip==0:
            spend=[500,500,200,300,200,1000,1000]
        elif GSeI.vip==1:#购买vip后提升属性八折 vip在道具组
            spend=[400,400,160,240,160,800,800]
        i=0
        while i<len(text):
            self.print_text(text[i],200,50*i+100,(0,0,0))
            self.print_text(str(spend[i])+'G',400,50*i+100,(255,215,0))
            button=Buy((600,50*i+100),i,spend[i])
            button.show()
            self.buttons.append(button)
            i=i+1
        cost=[2000,10000,2000,1000,5000]#上面对应道具的价格
        tool=['至尊VIP','永久加成卡','清屏','屏障','超级加倍卡']
        item=GSeI.item
        self.print_text(tool[item],200,50*i+2+100,(0,0,0))
        self.print_text(str(cost[item])+'G',400,50*i+100,(255,215,0))
        button=Buy((600,50*i+100),i+item,cost[item])
        button.show()
        self.buttons.append(button)
        weapons=['初始武器','激光武器','霰弹枪','榴弹枪']
        weapons_buy=[]
        for index in range(4):
            if GSeI.buy[index]==0:
                weapons_buy.append(index*10000)
            else:
                weapons_buy.append(0)
        j=i+1
        i=0
        while i<len(weapons):
            self.print_text(weapons[i],200,50*(i+j)+100,(0,0,0))
            if GSeI.buy[i]==0:
                local_text=str(weapons_buy[i])+'G'
            if GSeI.buy[i]!=0:
                local_text='0G'
            self.print_text(local_text,400,50*(i+j)+100,(255,215,0))
            if GSeI.weapon!=i:#如果是当前武器,则不用显示按钮
                button=Buy((600,50*(i+j)+100),12+i,weapons_buy[i])
                if GSeI.buy[i]==0:#未购买 则显示购买 否则显示可更换
                    button.show()
                else:
                    button.image=pygame.image.load('icons/use.png')
                    button.image=pygame.transform.scale(button.image,(button.width,button.height))
                    button.show()
                self.buttons.append(button)
            i=i+1
        
    def show(self):
        self.pre_draw()
        
    def print_text(self,text,pos_x,pos_y,rgb=(0,255,255),texttype='kaiti',textsize=20):#缺省参数的显示文字
        font1 = pygame.font.Font("fonts/TianGeKaiTi.TTF",textsize)
        textSurfaceObj = font1.render(text, True, rgb)
        textRectObj = textSurfaceObj.get_rect()
        textRectObj.center=(pos_x,pos_y)
        self.screen.blit(textSurfaceObj, textRectObj)

购买按钮:

Buy.py:

购买按钮的初始化中载入默认的buy图标,初始化的输入参数为pos、num、和spend,在SoreSys中创建并传参。pos定义了按钮的位置,在draw中绘制。num指定了该按钮为第几个按钮,在被点击时根据num选择不同的触发事件。spend为该按钮对应项的花费。在check时先检查当前关卡的金币是否大于spend,如果大于则减去spend并根据num值进行处理。【现在才发现有错误,如果点击的是已购买的是武器,则不需要检查花费,我当时竟然偷懒点击后先检查后加回去,如果钱不够则不能换回去,虽然不需要花钱】

import pygame
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Base.GameSettings import GSeI
from Codes.Logic.GameStates import GStI
from Codes.Battles.Battle1 import BI as Battle1
from Codes.Battles.Battle2 import BI as Battle2
from Codes.Battles.Battle3 import BI as Battle3
from Codes.Battles.Battle4 import BI as Battle4
def returnbattle():
    Battles=[Battle1,Battle2,Battle3,Battle4]
    return Battles[GStI.current_checkpoint-1]


class Buy(DrawOn):
    def __init__(self,pos,num,spend):#num:第几个按钮0-6 spend:对应金钱
        super().__init__()
        super(Buy,self).definePriority(3)
        self.screen=SI.screen
        self.width, self.height=79,38
        self.spend=spend
        self.num=num
        self.image=pygame.image.load('icons/buy.png')
        self.image=pygame.transform.scale(self.image,(self.width,self.height))
        self.rect=pygame.Rect(0,0,self.width,self.height)
        self.rect.center=pos

    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.image,self.rect)

    def show(self):
        self.pre_draw()
    def clean(self):
        GStI.shotgun_active=False
        BI=returnbattle()
        BI.bullets.empty()
    def check(self):
        BI=returnbattle()
        if BI.gold>=self.spend:#能够购买
            BI.gold-=self.spend
            GSeI.gold_consume+=self.spend
            if self.num==0:
                for alien in BI.aliens.sprites():
                    alien.v=round(0.9*alien.v,2)
                GSeI.aliens_v_min=round(0.9*GSeI.aliens_v_min,2)
                GSeI.aliens_v_max=round(0.9*GSeI.aliens_v_max,2)
                if GStI.current_checkpoint==3:
                    for bullet in BI.aliens_bullets:
                        bullet.speed_factor==round(0.9*bullet.speed_factor,2)
                        GSeI.alien_bullet_speed=round(0.9*GSeI.alien_bullet_speed,2)
                if GSeI.aliens_v_min<0.1:#最低限制:0.1
                    GSeI.aliens_v_min=0.1
                if GSeI.aliens_v_max<0.1:
                    GSeI.aliens_v_max=0.1
                if GSeI.alien_bullet_speed<100:
                    GSeI.alien_bullet_speed=100
            elif self.num==1:
                GSeI.aliens_size=round(0.9*GSeI.aliens_size,2)
                if GSeI.aliens_size<0.1:
                    GSeI.aliens_size=0.1
                GSeI.alien_bullet_width=round(0.9*GSeI.alien_bullet_width,2)
                GSeI.alien_bullet_height=round(0.9*GSeI.alien_bullet_height,2)
                if GSeI.alien_bullet_width<2:
                    GSeI.alien_bullet_width=2
                    GSeI.alien_bullet_height=17.2
                    
            elif self.num==2:
                GSeI.bullets_allowed+=1
            elif self.num==3:
                GSeI.bullet_width=round(1.1*GSeI.bullet_width,2)
                GSeI.bullet_height=round(1.1*GSeI.bullet_height,2)
                if GSeI.bullet_width>300:
                    GSeI.bullet_width=300
                if GSeI.bullet_height>300:
                    GSeI.bullet_height=300                
            elif self.num==4:
                GSeI.bullet_speed_factor=round(1.1*GSeI.bullet_speed_factor,2)
            elif self.num==5:
                GSeI.ship_speed_factor=round(1.1*GSeI.ship_speed_factor,2)
            elif self.num==6:
                GSeI.ship_limit+=1
                GStI.ships_left+=1
            elif self.num==7:#道具 商品vip卡
                GSeI.vip=1
            elif self.num==8:
                GSeI.pac=1
            elif self.num==9:
                GSeI.use=1#清屏
            elif self.num==10:
                GSeI.use=2#无敌
            elif self.num==11:
                GSeI.use=3#tac
            elif self.num==12:#初始武器
                GSeI.weapon=0
                self.clean()
            elif self.num==13:#激光
                if GSeI.buy[1]==0:
                    GSeI.buy[1]=1
                GSeI.weapon=1
                self.clean()
            elif self.num==14:#霰弹
                if GSeI.buy[2]==0:
                    GSeI.buy[2]=1
                GSeI.weapon=2
                self.clean()
            elif self.num==15:#榴弹
                if GStI.current_checkpoint==3:
                    BI.gold+=self.spend
                else:
                    if GSeI.buy[3]==0:
                        GSeI.buy[3]=1
                    GSeI.weapon=3
                    self.clean()

商店系统界面还有两个子系统的入口按钮:本机颜色更改系统和武器强化系统。

武器强化系统的入口按钮:

Weapon_Advance.py:

import pygame.font
from Codes.Logic.GameStates import GStI
from Codes.Base.Screen import SI
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.UI.Display_Advance import Display_Advance

class Weapon_Advance(DrawOn):
    def __init__(self ):
        super().__init__()
        super(Weapon_Advance,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=self.screen.get_rect()
        self.display=Display_Advance()
        self.width, self.height=255,81
        self.image=pygame.image.load('icons/advance.png')
        self.image=pygame.transform.scale(self.image,(self.width,self.height))
        self.image_rect=(900,600)
        self.rect=pygame.Rect(900,600,255,81)

    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.image,self.image_rect)

    def show(self):
        self.pre_draw()

    def check(self):
        GStI.store_active=False
        GStI.advance_active=True

本机颜色更改系统的入口按钮和武器强化系统类似。check函数的advance_active改为change_active即可。

本机颜色更改系统:

Display_Change.py:

该系统读取18个飞机的图像,被选取的图像号为GameStates的color_select。18个飞机颜色的预览图在上侧,当前选区(color_select)的样式会显示在屏幕中央。点击上侧预览图则可更改选择,点击预览图在UIMgr的146行~149行。


import pygame.font
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Logic.GameStates import GStI
from Codes.Base.GameSettings import GSeI
import time
class Display_Change(DrawOn):
    
    def __init__(self):
        super().__init__()
        super(Display_Change,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=(0,0,1200,800)
        self.bg_color=(255,255,255)
        self.text_color=(0,0,0)
        self.font_format=pygame.font.SysFont('SimHei',20)
        self.back_width, self.back_height=200,111
        self.image_back=pygame.image.load('icons/back.png')
        self.image_back=pygame.transform.scale(self.image_back,(self.back_width,self.back_height))
        self.bg=pygame.image.load('images/bg_advance.png') 
        self.image=[]
        self.img_rect=[]
        self.back_rect=pygame.Rect(0,0,self.back_width, self.back_height)
        for i in range(18):
            filename='images/Ship/plane_'+str(i)+'_'
            img=pygame.image.load(filename+'1.png').convert_alpha()
            self.image.append(pygame.transform.scale(img,(80,80)))
            c=i%9
            r=i//9
            self.img_rect.append((250+c*80,20+r*80,80,80))
        
        
    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        cs=GSeI.color_select
        self.screen.blit(self.bg,(0,0,1200,800))
        pygame.draw.rect(self.screen,[206,0,0],self.img_rect[cs],10)
        self.screen.blit(self.image_back,(0,0,200,111))
        for i in range(18):
            self.screen.blit(self.image[i],self.img_rect[i])
        filename='images/Ship/plane_'+str(cs)+'_'
        img1=pygame.image.load(filename+'1.png').convert_alpha()
        img1=pygame.transform.scale(img1,(600,600))
        img2=pygame.image.load(filename+'2.png').convert_alpha()
        img2=pygame.transform.scale(img2,(600,600))
        if time.time()%1>0.5:
            self.screen.blit(img1, (300,200))
        else:
            self.screen.blit(img2, (300,200))
       


    def show(self):
        self.pre_draw()
    
    def check_back(self):
        if GStI.current_checkpoint%2==1:
            GStI.store_active=True
            GStI.change_active=False
        else:
            GStI.game_active=True
            GStI.change_active=False

武器强化系统:

Display_Advance.py:

首先显示四种武器的子弹在左边,该武器可以强化,则显示右侧Advance按钮,如果未购买,则显示UNLOCKED按钮,如果已经强化到最够等级则显示TOP,只有ADVANCE按钮可以点击。

#在窗口内显示文字信息
import pygame.font
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Logic.GameStates import GStI
from Codes.Base.GameSettings import GSeI
from Codes.UI.Advance import Advance
from Codes.Battles.Battle1 import BI as Battle1
from Codes.Battles.Battle2 import BI as Battle2
from Codes.Battles.Battle3 import BI as Battle3
from Codes.Battles.Battle4 import BI as Battle4

def returnbattle():
    Battles=[Battle1,Battle2,Battle3,Battle4]
    return Battles[GStI.current_checkpoint-1]



class Display_Advance(DrawOn):
    
    def __init__(self):
        super().__init__()
        super(Display_Advance,self).definePriority(9)
        self.screen=SI.screen
        self.screen_rect=(0,0,1200,800)
        self.bg_color=(255,255,255)
        self.text_color=(0,0,0)
        pygame.font.init()
        self.font_format=pygame.font.SysFont('SimHei',20)
        self.back_width, self.back_height=200,111
        self.image_back=pygame.image.load('icons/back.png')
        self.image_back=pygame.transform.scale(self.image_back,(self.back_width,self.back_height))
        self.image_bullet=pygame.image.load('images/ship_bullet.png')
        self.image_bullet=pygame.transform.scale(self.image_bullet,(14,90))
        self.image_bullet_shotgun=pygame.image.load('images/bullet_shotgun.png')
        self.image_bullet_shotgun=pygame.transform.scale(self.image_bullet_shotgun,(33,127))
        self.image_flow=pygame.image.load('images/flow.jpg')    
        self.image_flow=pygame.transform.scale(self.image_flow,(12,120))        
        self.image_boom=pygame.image.load('images/boom.png')          
        self.image_boom=pygame.transform.scale(self.image_boom,(53,53))
        self.image_back_rect=(0,0)
        self.back_rect=pygame.Rect(0,0,self.back_width, self.back_height)
        self.button=[]
        self.bg=pygame.image.load('images/bg_advance.png') 
        
        
    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.bg,(0,0,1200,800))
        self.screen.blit(self.image_back,(0,0,200,111))
        self.screen.blit(self.image_bullet,(200,150,25,110))
        self.screen.blit(self.image_flow,(195,300,33,127))
        self.screen.blit(self.image_bullet_shotgun,(200,500,12,120))
        self.screen.blit(self.image_boom,(180,700,53,53))
        BI=returnbattle()
        text1="当前金币:"+str(BI.gold)+'G'
        text2="初始武器,无法进阶"
        text3="激光枪,当前宽度"+str(GSeI.light_width)+",升阶需要10000G"
        text4="霰弹枪,当前等级"+str(GSeI.shotgun_rank)+",一次可发出"+str(2*GSeI.shotgun_rank+1)+"升阶需要10000G"
        text5="榴弹枪,当前爆炸范围"+str(GSeI.boom_range)+",升阶需要10000G"
        error1="霰弹枪,已达到最高等级,无法进阶"
        error2="榴弹枪,已达到最高等级,无法进阶"
        text=[text1,text2,text3,text4,text5]
        error=[error1,error2]
        i=0
        while i<len(text):
            if i>=2 and i<=4:
                advance=Advance((900,180*i+20),i-1,10000)
                self.button.append(advance)
                if GSeI.buy[i-1]!=1:#如果未购买显示未解锁 
                    advance.image=pygame.image.load('icons/locked.png')
                    advance.image=pygame.transform.scale(advance.image,(advance.width,advance.height))
                if (i==3 and GSeI.shotgun_rank==3)or(i==4 and GSeI.boom_range==200):
                    advance.image=pygame.image.load('icons/top.png')
                    advance.image=pygame.transform.scale(advance.image,(advance.width,advance.height))
                    text[i]=error[i-3]
                advance.show()
            font1 = pygame.font.SysFont('kaiti', 16)
            textSurfaceObj = font1.render(text[i], True, (0,0,0))
            textRectObj = textSurfaceObj.get_rect()
            textRectObj.center=(600,180*i+20)
            self.screen.blit(textSurfaceObj, textRectObj)
            i=i+1


    def show(self):
        self.pre_draw()
    
    def check_back(self):
        GStI.store_active=True
        GStI.advance_active=False

强化按钮Advance.py:

import pygame
from Codes.Common.DrawBase import DrawOn,DCI
from Codes.Base.Screen import SI
from Codes.Base.GameSettings import GSeI
from Codes.Battles.Battle1 import BI as Battle1
from Codes.Battles.Battle2 import BI as Battle2
from Codes.Battles.Battle3 import BI as Battle3
from Codes.Battles.Battle4 import BI as Battle4
from Codes.Logic.GameStates import GStI

def returnbattle():
    Battles=[Battle1,Battle2,Battle3,Battle4]
    return Battles[GStI.current_checkpoint-1]


class Advance(DrawOn):
    def __init__(self,pos,num,spend):#num:第几个按钮0-6 spend:对应金钱
        super().__init__()
        super(Advance,self).definePriority(3)
        self.screen=SI.screen
        self.width, self.height=80,40
        self.spend=spend
        self.num=num
        self.image=pygame.image.load('icons/advance_button.png')
        self.image=pygame.transform.scale(self.image,(self.width,self.height))
        self.rect=pygame.Rect(0,0,self.width,self.height)
        self.rect.center=pos

    def pre_draw(self):
        DCI.add(self)

    def draw(self):
        self.screen.blit(self.image,self.rect)

    def show(self):
        self.pre_draw()

    def check(self):
        BI=returnbattle()
        if BI.gold>=self.spend:#能够购买
            BI.gold-=self.spend
            GSeI.gold_consume+=self.spend
            if self.num==2 and GSeI.shotgun_rank<=2 and GSeI.buy[2]==1:#提升霰弹
                GSeI.shotgun_rank+=1 
            if self.num==1 and GSeI.buy[1]==1:#提升激光枪
                GSeI.light_width+=2 
                GSeI.charge_time+=0.5
                GSeI.max_time+=1
            if  self.num==3 and GSeI.boom_range<200 and GSeI.buy[3]==1 :#榴弹
                GSeI.boom_range+=50

                

接下来讲四个关卡。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值