当前位置:主页 > 行业新闻 > 正文

游戏随笔之游戏资源池的设计

 2018-01-06 15:11  浏览次数:

游戏随笔之游戏资源池的设计

  很久没有更新了,今天给大家写一篇游戏资源池的相关文章,就当作2017年的最后银河护卫队2_全旺娱乐一篇文章吧。 转载请标明出处:

一、游戏项目中的资源池

  在一款游戏中,随着游戏的进行,我们会不断的创建和销毁一些角色,比如我们玩一款射击游戏,我们需要不断的发射子弹,一般的情况下,我们会不断的创建子弹,然后发射出去,在击中物体后销毁。分析整个设计的恋爱禁止的世界_全旺娱乐过程,我们会不断的创建子弹,然后发射出去,最后销毁它。这儿,其实就可以引入资源池的概念来解决子弹的反复创建和销毁。

  如果只是反复的创建和销毁子弹,那么每次的性能点主要在子弹的创建上,在场景中有较多角色频繁操作射击的时候,不断执行创建,会带来性能的较大消耗,从而让游戏卡帧。如果我们把这些子弹预先创建出来,塞入到一个弹夹,然后每次在射击发射子弹的时候,从预先创建的弹夹中取出来发射,每次在销毁的时候,又将其还原到弹夹中,这样循环反复的利用,可以避免每次射击子弹的时候的创建操作带来的性能消耗。将弹夹拓展一步,就是资源池的概念了。

二、不同设计下的资源池

  1、简单lua版本的资源池

  基于前文子弹的阐述,我就写一个简单版本的资源池的lua版本,首先,是资源池的定义:

function BulletPool:initialize() --缓存子弹的table self.mBulletPool = {} end

  是不是觉得很简单,是的,lua版本的资源池可以只需要用一个table就简单的表示,接下来,我们只需要维护好这个table即可。首先是取子弹的接口:

function BulletPool:GetBullet() --如果没有定义,则执行一次兜底定义 if not self.mBulletPool then self.mBulletPool = {} end -- 如果池子里面没有可以取的了,则返回nil if next(self.mBulletPool) == nil then return nil end local bulletObj = self.mBulletPool[#self.mBulletPool] table.remove(self.mBulletPool, #self.mBulletPool) return bulletObj end

  有了设计的接口,接下来,我们可以继续设计归还的接口,所谓有借有还再借不难,不能只从池子里面取,不归还,那池子早晚会干涸的 :D

function BulletPool:InsertBullet(bullet) if not bullet then return end if not self.mBulletPool then self.mBulletPool = {} end --子弹归还前的释放操作,可以不在意这一步操作 bullet:Release() table.insert(self.mBulletPool, bullet) end

  好了,有了整体的获取和归还的操作,池子的基本接口就有了,有的同学会说,如果我们想重置一遍池子怎么办?那就再写一个清除池子的操作吧 :b

function BulletPool:Release() for k, v in pairs(self.mBulletPool) do v:Release() end for k, v in pairs(self.mBulletPool) do self.mBulletPool[k] = nil end end

  这下接口都有了,让我们来应用这些接口吧 :D

首先给角色挂载一个子弹的资源池的获取接口吧:

--获取接口 function Character:GetBullet() return BulletPool:GetBullet() end --塞入接口 function Character:RemoveBullet(bullet) 泡泡堂_全旺娱乐 BulletPool:InsertBullet(bullet) end

  因为每个角色都会射出一堆的子弹,所以我们是直接挂在角色身上,就不在整个场景管理器中去管理子弹了,可以通过场景管理器的更新来执行角色的更新,从而执行所有子弹的更新,这样每个角色的子弹更新和角色更方博教练是张继科爸爸_全旺娱乐新一致。这种设计模式下,不会出现先更新角色,然后再更新子弹的带来的一些问题。

  有了这两个接口,下面就是让角色调用这2个接口: