pygame-飞机大战(上)

前言:当时(去年三月)接下来这个项目的时候,由于各种关系还没有开始着手,七月在天津实训的时候学了会儿(以后也许会发出来吧,不过都是半成品),之后就准备考研。这个项目还是得做的,本来就打算这个寒假完成,其实考研期间还挺犹豫,因为还不知道做什么游戏,前几天开了个会商榷了一下,ycb(YYyyCCCcccBb )说他五六月份已经把飞机大战的雏形搭建好了,本来我的本意是想做主剧情类的,但是他都搭建好了也只能用雏形做咯。(刚开始以为是他从哪里download下来的,后来发现他有好多拼写错误以为他自己写的,后来才知道他从书上抄下来的),最近差不多花了五六天(的晚上)对他给的雏形进行理解(连个注释都没有)和深度优化(那个雏形的效果简直不能看),然后增加了点功能。我是负责第一关的,所以以后还会再改进(再更)。

总体效果:

先说下不足(以后有时间会完成):1.暂时没找到合适的各种背景图和logo 以及本机的贴图

                                                          2.除了清屏道具以外其他道具使用的实现

                                                          3.金币商城内武器系统未上线

                                                          4.死亡、下一关特效及提示等

                                                          5.显示文档只能第一页(懒得写翻页了)

 

实现(优化)了的内容:1.菜单各按钮的功能 2.金币商城内购买的提升属性的提升 3.敌机、石头、bonus的随机性 4.部分彩蛋和道具

 

在这里介绍一下写的部分函数:

Display.py:(没有写完,只能显示前十行)

import pygame.font
from Codes.Common.DrawBase import DrawOn,_DrawCallInstance
from Codes.Base.Screen import _ScreenInstance
from Codes.Logic.GameStats import _GameStatsInstance

class Display(DrawOn):
    def __init__(self,text):
        super().__init__()
        super(Display,self).definePriority(9)
        self.screen=_ScreenInstance.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.total=10 #一页显示最多个数
        self.length=len(text)
        self.text=text
        self.width, self.height=200,111
        self.image=pygame.image.load(r'D:/MyG/icons/back.png')
        self.image=pygame.transform.scale(self.image,(self.width,self.height))
        self.image_rect=(0,0)
        self.rect=pygame.Rect(0,0,self.width, self.height)
    def pre_draw(self):
        _DrawCallInstance.add(self)

    def draw(self):
        
        i=0
        k=0

        self.screen.fill(self.bg_color, self.screen_rect)
        self.screen.blit(self.image,(0,0,200,111))
        
        
        while k<self.total and k<self.length:
            self.font=self.font_format.render(self.text[k],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(self):
        _GameStatsInstance.game_active=False
        _GameStatsInstance.display_active=False
        _GameStatsInstance.help_active=False
        _GameStatsInstance.rank_active=False

实例化这个类的时候需要输入一个txt(字符串数组,数组中每个值代表一行),show/pre_show/draw函数在很多类中都有,每次循环update的时候都会调用各个show,show调用pre_show(感觉直接就把preshow的代码写在show里也可以),把这个类的实例化对象放入一个类似于队列的drawcall,drawcall对队列中所有对象进行优先级排序(Priority),优先级大的对象会先调用自身的draw在屏幕上绘制。

self.rect是定义的点击事件触发的范围,check函数就是对应的触发事件,在这里image为back,就是显示文本后的返回键,点击返回键(self.rect的范围),就会触发check函数 (这个在UImgr.py里),更改对应的几个状态值。

GameStats包含了几个状态值:

from Codes.Base.GameSettings import _GameSettingsInstance
class GameStats():
    def __init__(self ):
        pass

    def init(self):
        self.reset_stats()
        self.game_active=False
        self.display_active=False
        self.rank_active=False
        self.help_active=False
        self.store_active=False

    def reset_stats(self):
        self.ships_left = _GameSettingsInstance.ship_limit#left=剩下的生命
    def printstats(self):
        print('game'+str(self.game_active))
        print('display'+str(self.display_active))
        print('rank'+str(self.rank_active))
        print('help'+str(self.help_active))
        print('store'+str(self.store_active))
        

_GameStatsInstance= GameStats()

 

在UImgr里会根据当前不同的状态值处理不同的点击事件和调用对应的show,且最多同时只有一个状态为True:

状态名 为True时的含义
game_active 显示对战界面
display_active 显示日志(log)
rank_active 显示排名(rank)
help_active 显示帮助(help)
store_active 显示金币商城界面
都为False 显示菜单

 

UImgr:


from Codes.UI.BeginGame import BeginGame
from Codes.UI.QuitGame import QuitGame
from Codes.UI.HelpGame import HelpGame
from Codes.UI.RankGame import RankGame
from Codes.UI.StoreSys import Store
from Codes.UI.logo import logo
from Codes.Logic.GameStats import _GameStatsInstance

class UIMgr():
    def init(self):
        
        self.BeginUI=BeginGame()
        self.QuitUI=QuitGame()
        self.HelpUI=HelpGame()
        self.RankUI=RankGame()
        self.storeUI=Store()
        self.logoUI=logo()

    def update(self,delta):
        if not _GameStatsInstance.game_active and not _GameStatsInstance.display_active and not _GameStatsInstance.rank_active and not _GameStatsInstance.help_active and not _GameStatsInstance.store_active:         
            self.BeginUI.show()
            self.QuitUI.show()
            self.HelpUI.show()
            self.RankUI.show()
            self.logoUI.show()
        if _GameStatsInstance.display_active and not _GameStatsInstance.store_active:
            self.logoUI.DisplayUI.show()
        if _GameStatsInstance.rank_active and not _GameStatsInstance.store_active:
            self.RankUI.DisplayUI.show()
        if _GameStatsInstance.help_active and not _GameStatsInstance.store_active:
            self.HelpUI.DisplayUI.show()
        if _GameStatsInstance.store_active:
            self.storeUI.show()
 
    def check_Mouse(self,mouse_x,mouse_y,dispatcher): 
        if not _GameStatsInstance.game_active and not _GameStatsInstance.display_active and not _GameStatsInstance.rank_active and not _GameStatsInstance.help_active and not _GameStatsInstance.store_active:#游戏未开始前的点击
            #四个按钮的触发条件:所UI均处于关闭(false)
            if self.BeginUI.rect.collidepoint(mouse_x,mouse_y) :
                self.BeginUI.check()
            if self.QuitUI.rect.collidepoint(mouse_x,mouse_y) :
                self.QuitUI.check()  
            if self.RankUI.rect.collidepoint(mouse_x,mouse_y) :
                self.RankUI.check()            
            if self.HelpUI.rect.collidepoint(mouse_x,mouse_y) :
                self.HelpUI.check()    
            if self.logoUI.rect.collidepoint(mouse_x,mouse_y) :
                self.logoUI.check()  
        
        if  _GameStatsInstance.display_active:
            if self.logoUI.DisplayUI.rect.collidepoint(mouse_x,mouse_y) :
                self.logoUI.DisplayUI.check()
        if  _GameStatsInstance.rank_active:
            if self.RankUI.DisplayUI.rect.collidepoint(mouse_x,mouse_y) :
                self.RankUI.DisplayUI.check()
        if  _GameStatsInstance.help_active:
            if self.HelpUI.DisplayUI.rect.collidepoint(mouse_x,mouse_y) :
                self.HelpUI.DisplayUI.check()
        if _GameStatsInstance.store_active:
            for button in self.storeUI.buttons:
                if button.rect.collidepoint(mouse_x,mouse_y) :
                    button.check()
                    break
        
        
            
_UIMgrInstance=UIMgr()

初始化时,分别对开始、退出、排名等类进行实例化,每次update时,检查状态情况,如果都为false,则调用五个(logo.begin.quit.rank.help)的show,实现显示菜单,如果display/rank/help为active的时候,则调用对象里的displayUI(已实例化Display类)的显示,实现显示不同的三个文本,如果store为True,则显示金币商店;check_Mouse在Handle.py被调用:每次收到鼠标点击时,执行check_Mouse:根据不同的当前状态执行对应的check

Handle.py和Event.py:

import sys
import pygame
from Codes.Common.Event import _EventPatcher
from Codes.UI.UIMgr import _UIMgrInstance

class Handle():
    def init(self):
        self.add(pygame.K_q, self.exit)

    # 配置游戏基本信息
    def update(self, delta):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                _EventPatcher.dispatch(event.key)
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_a or event.key == pygame.K_d or event.key == pygame.K_w or event.key == pygame.K_s or event.key == pygame.K_p  or  pygame.K_r or  pygame.K_e:
                    _EventPatcher.dispatch(event.key)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                _UIMgrInstance.check_Mouse(mouse_x, mouse_y, self)

    def add(self, type, element):
        _EventPatcher.addEvent(type, element)

    def exit(self):
        sys.exit()


_HandleInstance = Handle()
import  sys
import py
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值