じ☆ve冰风 发表于 2024-4-19 15:33:35

[Done]真.动画播放的提速=_= [BY FantasyDR]

原来的那篇文章,实在有点误人子弟了。虽然前面大体分析过程没有错误,但是后面的改法有点效率低下,而且存在错误……我也就不细说了。下面已经改过了……

最近我发了个叫做《Strike》的射击游戏Demo,虽然很卡,不过速度上面应该比纯事件制作的快一些。其中子弹的效果是一个空白的事件,然后在其身上播放一种动画来表现。最初很快发现一个问题,即使在P4,2.8G的CPU的机器上面,按下子弹发射键依然会卡一下才能继续。

这对于游戏的表现力很有影响,所以就探察了一下原因。

开始以为是并行事件调用的原因,后来发现,如果一个动画正在播放中,那么再次播放它就不会有停顿。如果是一个独立的动画,开始的时候就会卡。于是看是分析动画播放相关的内容,追溯到RPG::Sprite这个内部类。

还好,帮助里面厚道的给出了RPG::Sprite的实现方法,否则真的死在这里了。而且,帮助文件里面厚道的提示了以下内容:
显示的动画图像从 RPG::Cache 模块中取得,动画结束时为了节约内存而被释放。

现在又仔细理解了一下那个RPG::Sprite的定义,发现还是不要把Sprite的dispos也去掉为好,因为显示层的关系。

根据这条线索,阅读RPG:Sprite的代码实现,发现每次播放动画前,会载入动画所需的素材图片。接下来分析了下代码,发现其实原本素材的bitmap是存放在一个Hash表里面的,也就是本来是可以实现类似缓存加速的效果的,当有动画调用这副素材,这副素材的引用数量就被加1,如果这个动画播放完毕,引用数量减1,当引用数量为0,素材图片被释放……

问题就在这里。

这也就解释了为什么同样的动画一起播放反而不卡的原因,因为只有一次new和一次dispose,中间都是直接取Hash里面的对象,省略了大量的初始化时间。

那么改造方案也就出炉了,重载这个方法,去掉相关的资源释放的内容。以下是代码,从帮助里面粘贴出来,代码中被我注释掉的是释放资源相关的内容。只有在头一次按播放某个动画的时候会稍微卡一下,机子好的话不会有感觉,以后都不会卡了。

而且,其实速度的关键就是那张动画图片的加载,现在可以确定,这种改法至多会让你浪费掉Animation目录下面的图片所消耗的内存,其他没有任何副作用。
但是觉得RM游戏动画播放所消耗的内存应该不足以致命吧?至少我的游戏是正常的……

如果在调用动画之前卡一下觉得不爽的朋友们,就加入这个脚本吧。
甚至可以可以尝试动态Loding。在需要的时候,把Animation目录下面的图片随便用
RPG::Cache.animation("文件名",色相值)
赋给某个变量,这样就相当于预载入了图片。播放的时候一点都不会卡:)
那么,文件多的话,做一个Loding画面也就不过分了:)

脚本请插入工程的Main之前:
module RPG
class Sprite < ::Sprite
    def dispose_animation
      if @_animation_sprites != nil
      sprite = @_animation_sprites
      if sprite != nil
          @@_reference_count -= 1
      #if @@_reference_count == 0
      #    sprite.bitmap.dispose
      #end
      end
      for sprite in @_animation_sprites
          sprite.dispose
      end
      @_animation_sprites = nil
      @_animation = nil
      end
    end
end
end


              [本贴由 柳柳 于 2005-10-24 6:51:42 最后编辑]
            本帖来自P1论坛作者亿万星辰,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg. blue/forum.php?mod=viewthread&tid=270若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: [Done]真.动画播放的提速=_= [BY FantasyDR]