Pygame游戏飞机大战《星野守望》

程序地址:网页链接

注意:目前只支持win系统。

游戏做的不完整,只能用来体验体验。

最近接触了Pygame游戏编程,十分感兴趣,学习了一本相关书籍以及查阅了Pygame的官网https://www.pygame.org的资料,花了一周的时间写出了这个飞机大战的游戏。主体玩法相对完整,模拟的是逝去的手游帝王《雷霆战机》,算是对它多舛命运的哀悼吧。

话不多说,先看效果

什么,你问我素材哪里找的?万能的淘宝在这时候总不会让你失望!所有音频和图片素材均来自于淘宝。

这里跟大家分享几个制作过程中遇到的几个技术细节的解决方法,以及优化措施:

1.帧率不同步问题。

我用pygame.time.Clock对象来控制整个游戏的最大帧率为60。为什么说是最大呢?不是因为性能原因导致游戏帧率真的低于60(虽然在某些过程优化之前的确出现过卡的低于60帧的情况),是因为某些动画过程的帧率本就不是60,比如飞机爆炸的动画,就那么9帧,若60Hz播放的话就显得太快了,起初,我想到用重复的图片Surface对象填充这些应该重复的几帧,使得切换到下一帧的速度没那么快,但重复的图片对象会导致成倍数的内存占用,这是我不能忍受的。于是我用了一个FramNum对象,将重复的次数用正整数num表示,并增加计数点属性,当运行到下一次就增加一个计数点,若计数点达到了num,则运行下一帧。于是一个完整的动画帧Frame对象被设计成由FramNum对象组成,能够成倍数地减少在动画帧方面内存使用。

以下实现代码看不懂没关系,因为注释不清楚,而且有一些额外的设计没有被提及。

import pygame

class FrameNum:
    def __init__(self, frame:pygame.Surface, num:int):
        self.frame = frame
        self.num   = num
    def __getframe(self):
        return self.__frame
    def __setframe(self, other):
        self.__frame = other
    frame = property(__getframe, __setframe)

    def __getnum(self):
        return self.__num
    def __setnum(self, other):
        self.__num = other
    num = property(__getnum, __setnum)

    def __mul__(self, other):
        self.num *= other
        return self

    def __imul__(self, other):
        self.num *= other
        return self

    def __getitem__(self, item):
        if item == 0:
            return self.frame
        elif item == 1:
            return self.num
        else:
            raise ValueError('indexvalue not 0 or 1!')


class Frame:
    'like [[(frame1,num1),(frame2,num2)],[...]]'
    LASTCIRCLE= b'\x01'
    LASTSTICK = b'\x00'
    def __init__(self, framelist, leisureframe=0):
        self.framelist  = framelist
        # this condition
        self.this_code  = leisureframe
        self.thiscondition = framelist[self.this_code]
        # this condition len
        self.thiscdlen  = len(self.thiscondition)
        # this frame
        self.thisframe  = 0
        # this frame num
        self.thisfnum   = self.thiscondition[self.thisframe][1]
        self.thisgone   = 0
        self.image      = self.thiscondition[self.thisframe][0]
        self.next_code  = self.LASTCIRCLE
        self.sticked    = False
        # 得到本状态的虚拟帧数目

        self.leisureframe = leisureframe
    def set_stick(self):
        self.next_code = self.LASTSTICK
    def unsetonce(self):
        self.next_code = self.LASTCIRCLE

    def update(self):
        # 若为循环播放
        if not self.sticked:
            if self.next_code == self.LASTCIRCLE:
                self.circleupdate()
            elif self.next_code == self.LASTSTICK:
                self.stickupdate()
            else:
                self.onceupdate()

    def changecondition(self, condition_code):
        self.thiscondition = self.framelist[condition_code]
        self.thisgone   = 0
        self.thisframe  = 0
        self.this_code = condition_code
        self.thiscdlen  = len(self.thiscondition)
        self.updateframe()
    # 跳转condition代码
    def set_next(self, next_code):
        self.next_code = next_code

    def set_condition(self, this_code):
        self.this_code = this_code
    
    def circleupdate(self):
        # 若达到这一帧的最后一个
        if self.thisgone >= self.thisfnum:
            # 进入下一帧
            self.nextframe()
            # 若超过最后一帧
            if self.thisframe >= self.thiscdlen:
                self.thisframe = 0
                self.thisgone = 0
            # 图像变化
            self.updateframe()
        # 下一个虚帧
        self.go()
        
    def stickupdate(self):
        if self.thisframe < self.thiscdlen - 1:
            if self.thisgone >= self.thisfnum - 1:
                self.nextframe()
                self.updateframe()
            else:
                self.go()
        elif self.thisframe == self.thiscdlen - 1:
            if self.thisgone < self.thisfnum - 1:
                self.go()
            else:
                if not self.sticked:
                    self.sticked = True

    def onceupdate(self):
        if not self.thisframe == self.next_code:
            if self.thisframe < self.thiscdlen - 1:
                if self.thisgone >= self.thisfnum:
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值