写在最前:

本系列教程原创版权归bsucat所有,本文只为收藏及共享。转载请按如下方式标明原创作者出处,以示尊重!!

作者:bsucat

原文:http://blog.csdn.net/bsucat/archive/2010/03/01/5334619.aspx

目录

0.    前言

1.    RM的运作原理

1.1         概览

1.2         想象中的结构

2.    图像模块

2.1         10s的秘密

2.2         性能与偏见

2.3         绘制流水线

(待续)

0.    前言

什么人适合阅读这篇文章?

这篇文章涉及到的知识范畴,可能让大家感到陌生。确实,这篇文章不太适合新手阅读,对于大部分人来说这篇文章所讲的内容是没有用的。但是对想要了解RM内部运行原理的朋友来说,这篇文章的内容应该能值得大家一起分享、探讨。

这篇文章里讲到的RGSS版本?

由于RM并不是一个公开源代码的商业软件,各位也对RM的反编译很反感( 我也没那个能力),所以这篇文章的内容,只是我凭个人经验对RM底层引擎的一个猜测性的分析。如果有不对的地方,请大家务必谅解,烦请纠正。

另外,由于我个人对RMXP版本比较熟悉,所以这篇文章主要分析的是RGSS而不是RGSS2 。RGSS2较之RGSS,在底层实现里并无太大的变化,只是更加规范,并增加了部分功能而已。所以这篇文章的大部分内容,对于RGSS2也是适用的。

1.    RM的运作原理

1.1概览

可能有不少人诟病RM有这样那样的缺点,但是RPG Maker XP确实是一款设计得非常现代的2D游戏制作工具。从组织结构来讲,RMXP使用的是非常流行的游戏内容和游戏引擎分离的结构,游戏逻辑灵活地独立成一个模块,大概如下图所示。

不要觉得这个很简单哦,实际上要设计好一个引擎上的脚本系统并非易事,还好RM已经帮我们做到了。下面看看RM是怎么实现的。

一般来说,脚本有两种作用方式,一种是宿主语言(比如C)加载脚本处理部分内容,但控制权仍在宿主语言,另一种是则是宿主加载脚本后失去控制权,控制权在脚本语言。RM很明显是属于后者,RM在做了一系列初始化的工作后,调用ruby的C API(比如ruby_run?我对ruby的C API并不熟悉,只是猜测)来让ruby解释器取得了控制权。所以我们能感受到的整个游戏的运行过程,就可以完全由RGSS来控制了。

RGSS在整个RM的软件层次里,已经属于最高级的层次。如下图所示。

在脚本层之下的,便是游戏的引擎。RM通过扩展ruby库,将引擎的功能抽象化,并封装了部分操作。使用者并没有必要关心底层引擎究竟是怎么运行的,比如怎么使用DirectX ,怎么管理内存,怎么处理windows的消息循环等等。只要用户知道怎么使用RGSS,便可顺利地使用引擎做出自己的游戏。

这一部分被封装好的内容,是对用户透明的,通常情况下你无需了解。但是对于求知欲很重的我们来说,今天要探讨的,恰恰就是这部分内容了J。

1.2 想象中的结构

整个游戏的运行,在默认情况下,至少有以下三个文件存在,那就是:Game.exe,Game.ini和rgssxxxx.dll。赶快来猜猜,里面都有些什么吧(不是纯粹的瞎猜哦)。

Game.exe是游戏的主程序,Game.ini是配置文件,这个毫无疑问。Game.exe在一开始运行的时候,就从Game.ini里读取了相关的信息,比如窗口的标题是什么,一会动态加载的dll文件的名字(就是rgssxxxx.dll),以及哪里去找ruby解释器将要运行的脚本(比如默认的Script.rxdata)等等内容。解析ini文件很简单,调用windows提供的ini文件处理API就行了,所以我估计RM也是这么干的(不然呢?!)。

Game.exe本身并没有多少真正和游戏引擎相关的内容,甚至没有windows的消息循环(这个后面会分析),它更像是一个“傀儡”。而操纵它的幕后黑手便是rgssxxxx.dll。在这个dll里,封装了一个用DirectX实现的游戏引擎。Game.exe通过调用它提供的API,最终实现了我们想要的一切(好吧,也许你还想要得更多……)。

在一个游戏程序里,一般来说,大概流程如下:

这个循环,在RGSS的默认脚本里,也有所体现:

# 主循环 loop do # 刷新游戏画面 Graphics.update # 刷新输入信息 Input.update # 刷新画面 update # 如果画面被切换就中断循环 if $scene != self break end end # 主循环 loop do # 刷新游戏画面 Graphics.update # 刷新输入信息 Input.update # 刷新画面 update # 如果画面被切换就中断循环 if $scene != self break end end

在这个循环里,update这一句,担负着的便是游戏逻辑处理的任务,Graphics.update从字面上看,明显是游戏画面的处理(实际上有更多内容……),那么窗口消息的处理跑到哪里去了呢?

2.

图像模块

2.1 10s的秘密

假如你有自己写过一个差劲的寻路脚本,导致游戏窗口弹出“脚本已备份”的提示栏,相信你对RGSS每10s至少要调用一次Graphics.update的限制并不陌生。有的人认为这个10s限制非常的没有道理,是RM的性能瓶颈。但经过我的仔细思考,事实并非如此。

熟悉windows编程的朋友们想必都知道,windows程序都是消息驱动型的,假如没有消息循环的更新,整个程序必定会陷入卡死的状态。前面我说过,在RM的Game.exe程序运行时,ruby解释器占用了整个程序的控制权。我们姑且假设在Game.exe中,一旦调用脚本,便无法返回。这样,窗口消息更新的任务,就只能交给脚本了。

假设脚本中不调用窗口消息的更新,整个程序必定陷入卡死状态,所以为了防止用户写出的糟糕脚本导致程序运行过慢而无法终止程序,很有必要加上只要10s没有调用消息更新,则自动终止程序的限制。

所以,没错,消失的窗口消息处理,实际上就封装在了Graphics.update里面。

所以Graphics.update的功能,现在看起来就像是这样了:窗口消息处理+渲染图像。但是,仅仅是这样吗?

不知道你有没有注意到,Graphics.frame_rate和Graphics.frame_count这两个Graphics模块的属性值,这说明RM是有帧速控制的。而从两个属性在RM文档里的说明来分析,帧速的控制很明显封装在了Graphics.update里来处理(至于什么是帧速控制?!这个可不是什么新鲜的东西,请自行搜索“regulating frame rate”)。

目前我们已知Graphics.update包含了窗口消息处理、帧速控制和图像渲染,而且它实际上可能还包含了更多东西(修改标题什么的?!天知道?!),不过那些我们现在都不关心了。接下来我想仔细说说的,就是图像渲染。

2.2 性能与偏见

RM的图像引擎用的是DirectDraw。这一点请不用怀疑,这可能是这篇文章中我最敢发誓是正确的观点……

不过rgssxxxx.dll并没有直接链接DirectDraw的库文件,而是在运行时加载的。这里我顺便提一下,微软从DirectX 8开始就不提供DirectDraw的文档支持了,而在之后,更是直接抛弃了DirectDraw 。但是,DirectX是一个COM组件,所以即使微软不再更新ddraw,它还是可以欢畅地在任何兼容它的新版本里运行的。

使用RM的人常常会有两个偏见。第一个是认为Ruby的解释器相对较慢,导致性能不佳;第二个则是认为DirectDraw是一个已经夭折的产品,基于它的RM引擎,必然性能表现不佳。

关于第一个偏见,我对ruby解释器速度的相关测试并不了解,但是就我个人使用的感受来说,一个设计得良好的RGSS脚本结构,不可能会慢到哪里去。很多人写脚本的时候并不考虑性能的开销,每一帧里都要做大量无用的循环检查,累得ruby解释器气喘吁吁(可怜的Ruby娘!J),这才是真正拖慢ruby解释器速度的元凶。

好吧,下面回到我们图像模块的正题上来,也就是第二个关于DirectDraw的偏见。固然,微软已经彻底地抛弃了DirectDraw,而DirectDraw也只能算一个半成品而已但这并不意味着DirectDraw就是一个低性能的东西。实际上,DirectDraw能满足制作2D画面的绝大部分需求,而且效率很不错。

可能有人心中会有疑问,既然DirectDraw能满足2D游戏的开发,为什么会有用Direct3D来开发的2D引擎?前面我说过了,DirectDraw只是一个半成品,很多功能微软并没有做,需要开发者自己去扩展,这无疑增加了开发者的使用难度。而之前我在国外某论坛上看洋人们讨论过这个问题,最后众洋人得出的结论是现在众多的硬件厂商在已经放弃产品对2D加速,也就是Blitter的支持(没错,Bitmap类里的blit兴许就是调用了它),而3D加速几乎是现在每块显卡都能支持的(我也不知道这结论是否属实,反正是洋人们说的!),所以Direct3D是更明智的选择……

话说回来,以上两点绝对不是导致你的游戏运行缓慢的性能瓶颈。当出现游戏运行迟缓的情况时,还是首先检查下你自己都写了些什么低效率的脚本吧,而不是一味地责怪RM愚笨!

RPG Maker的引擎分析(一)(二)相关推荐

  1. RPG Maker的引擎分析(一)

    转载请给出本文链接,以便读者检查更新,谢谢 http://blog.csdn.net/bsucat/archive/2010/03/01/5334619.aspx 目录 0.    前言 1.    ...

  2. gaia引擎分析(二)场景管理

    只是粗略的分析原理,大虾轻喷~~ Gaia引擎中没有场景管理器(scenemanager)这种东西,但是并不是没有场景管理,而是在cGameHost类中有一课场景树进行场景组织.一棵四叉树用来进行剪裁 ...

  3. RPG Maker XP游戏制作方法(二)

    (1)文件->新建项目 按自己喜欢取个名字就行了,这个不是重点 先简单的 介绍下,用这款软件做游戏的主要步骤就是创建地图和事件的安排 图层按钮 画图工具 事件按钮 图层按钮的最后一个 (2)新建 ...

  4. <2021SC@SDUSC>【Overload游戏引擎】OvUI源码模块分析(二)——ImGui

    <2021SC@SDUSC>[Overload游戏引擎]OvUI源码模块分析(二) 前言 案例分析 程序框架 1.基本案例 2.实现定制绑定/定制引擎 渲染函数 总结 前言 本篇我们来分析 ...

  5. 【RPG Maker MV】RPG游戏《机器人养成记》制作笔记 - 制作背景和引擎选择

    想让更多的人了解人工智能,学会机器学习,但机器学习本身有太高的入门门槛,导致很多人望而却步.因此一直在想办法让机器学习变得简单.有趣一些.做过一些尝试:比如用动画的形式介绍机器学习原理(点击查看),通 ...

  6. 学习RPG Maker MZ开发创建并发布PC和移动端游戏

    Complete RPG Maker MZ: Create and Publish for PC and Mobile 完整的RPG制造商MZ:为个人电脑和移动设备创建和发布 MP4 |视频:h264 ...

  7. b2c项目基础架构分析(二)前端框架 以及补漏的第一篇名词解释

    b2c项目基础架构分析(二)前端框架 以及补漏的第一篇名词解释 继续上篇,上篇里忘记了也很重要的前端部分,今天的网站基本上是以一个启示页,然后少量的整页切换,大量的浏览器后台调用web服务局部.动态更 ...

  8. RPG Maker MV插件系统详解与如何编写插件

    最新发布rmmv和以往的版本最大不同就是脚本系统了,整个脚本系统采用html5的javascript编写.和以往的ruby脚本简直天翻地覆 这也是为了实现跨平台运行,也是前所未有的高度编程自由,所有游 ...

  9. 试图速成的RPG Maker MV 学习笔记(一)

    参考学习的是B站UP主硕明云书的教程:[MV❀RPG制作大师]萌新基础速成教学全集_哔哩哔哩_bilianwa 首先安装完RPG Maker MV,然后熟悉一下软件界面,各个图标和工具都有什么作用. ...

最新文章

  1. nodejs之express -- 1
  2. Linux系统日志切割
  3. Android异步编程
  4. 年化利息100%,现金贷监管寒冬将至
  5. 更换锁定计算机图片,电脑锁屏图片怎么设置
  6. 相机标定(3) opencv中solvePnPRansac()和solvePnP()计算外参数
  7. 搭建自己的Unity Package
  8. Flask redirect
  9. VSAN效能监控利器-VSAN Observer
  10. WebService调用
  11. SCVMM 2012 R2运维管理十一之:添加Hyper-v群集
  12. c语言上机实践题库,C语言上机题库
  13. sqlserver数据库系统概论习题集
  14. 读写卡测试程序VFP源代码
  15. springboot获取视频时长以及截取视频第一帧
  16. 空间磁场分布测量仪器案例
  17. X86和X64的区别
  18. matplotlib 笔记: contourf contour
  19. 12月18日科技资讯|支付宝、微信回应3D面具破解人脸识别;ofo 否认「发币」;Kafka 2.4.0 发布
  20. how to do research

热门文章

  1. new关键字执行过程
  2. C++ TCP socket 非阻塞连接超时设定方式
  3. TypeScript学习(五):数组的定义方式及常见数组操作方法使用
  4. for循环连续创建对象
  5. Android逆向从入门到入土(smali修改,so修改)
  6. Effective C++ 条款42
  7. 折线图_手把手教你用ECharts画折线图
  8. [C#]System.Timers.Timer
  9. oracle 01157,Oracle数据库启动时出现ORA-01157和ORA-01110问题
  10. awk命令的使用案列