设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
楼主: guoxiaomi
打印 上一主题 下一主题

[胡扯] How to写一个全新的rpg maker

[复制链接]

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

11
 楼主| 发表于 2021-8-7 01:17:33 | 只看该作者
本帖最后由 guoxiaomi 于 2021-8-7 01:34 编辑

写了个渲染的循环: release.zip (3.94 MB, 下载次数: 6)
我准备了2个std::vector,分别在不同的线程(ruby线程和渲染线程)里添加和执行指令。
设计中ruby里的所有绘制相关的函数调用都不实际执行,而是向commands_in里push命令。
  1. void renderer_loop(cen::renderer &renderer, void(function(Command &&, cen::renderer &)))
  2.     {
  3.         while (!program_terminate)
  4.         {
  5.             if (commands_out.empty())
  6.             {
  7.                 if (!commands_in.empty())
  8.                 {
  9.                     swap_queues();
  10.                 }
  11.                 continue;
  12.             }

  13.             for (auto cmd : commands_out)
  14.             {
  15.                 if (cmd.id == Command_Code::Frame_End)
  16.                 {
  17.                     num_frame_out--;
  18.                     if (num_frame_out > 0)
  19.                     {
  20.                         continue;
  21.                     }
  22.                 }
  23.                 function(std::move(cmd), renderer);
  24.             }
  25.             commands_out.clear();
  26.         }
  27.     }
复制代码
然后增加了一个跳帧的设定,当负责渲染的线程检查到有多个Frame_End的指令时,只有最后一帧才会尝试渲染所有的画面,前面的Frame_End指令跳过。

评分

参与人数 2+2 收起 理由
哇哇哇啊叭叭 + 1 插不上话
89444640 + 1 完全看不懂,但是感觉很厉害XD.

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
1
星屑
175
在线时间
17 小时
注册时间
2017-4-24
帖子
9
12
发表于 2021-8-7 02:04:13 | 只看该作者
硬核……(码了就是跑了系列

评分

参与人数 1+1 收起 理由
guoxiaomi + 1 塞糖

查看全部评分

回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

13
 楼主| 发表于 2021-8-13 01:47:10 | 只看该作者
成功绘制了图片!https://gitee.com/rmxp/sdlrgss/releases/v0.0.6

ruby代码为:
RUBY 代码复制
  1. class Bitmap
  2.   attr_reader :x, :y
  3.  
  4.   def initialize(path)
  5.     @x = @y = 0
  6.     Core._bitmap_new_path(self, path)
  7.   end
  8.  
  9.   def x=(x)
  10.     @x = x
  11.     Core._bitmap_set_xy(self, @x, @y)
  12.   end
  13.  
  14.   def y=(y)
  15.     @y = y
  16.     Core._bitmap_set_xy(self, @x, @y)
  17.   end
  18.  
  19.   def dispose
  20.     Core._bitmap_dispose(self)
  21.   end
  22. end
  23.  
  24. b1 = Bitmap.new("resource/001-Fighter01.png")
  25. b2 = Bitmap.new("resource/001-Fighter01.png")
  26. t = Time.now
  27. 1000.times do
  28.   b1.y = (b1.y + 1) % 320
  29.   b2.x = (b2.x + 1) % 320
  30.  
  31.   Core.frame_end
  32.   Core.wait_renderer
  33. end
  34. p "FPS: #{1000 / (Time.now - t)}"
  35. b1.dispose
  36. b2.dispose
  37. b1 = b2 = nil
可以看到Bitmap(其实更像是RGSS的Sprite)其实是个没啥东西的类,而Core.XXX函数只是传输指令,并没有实际执行任何东西。图片的加载和渲染在另一个线程里异步完成。
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9617
在线时间
566 小时
注册时间
2017-9-28
帖子
208
14
发表于 2021-8-13 09:14:14 | 只看该作者
歪楼:其实 rpg maker 包含运行时编辑器两个部分,运行时全在 rgss.dll 里,你可以直接拿来调(注意这里只能用 RGSS300,因为 301 有壳不让 gcc 链接):
  1. #include <windows.h>
  2. int CALLBACK WinMain(HINSTANCE hInstance,
  3.                      HINSTANCE hPrevInstance,
  4.                      LPSTR lpCmdLine,
  5.                      int nCmdShow) {
  6.     wchar_t *rgssad = NULL;
  7.     RGSSInitialize3();
  8.     RGSSSetupFonts();
  9.     RGSSGameMain(
  10.         CreateWindowEx(0, "#32770", "RGSSGameMain", 0x90cf0000,
  11.             CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
  12.             0, 0, 0, 0),
  13.         L"Scripts.rvdata2",
  14.         &rgssad);
  15.     return 0;
  16. }
复制代码
  1. gcc -O3 -static -s -o player player.c RGSS300.dll -m32 -w && player
复制代码
而坛友的编辑器据我所知目前只有 UCCU 可以一战(逃
喵喵喵
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9617
在线时间
566 小时
注册时间
2017-9-28
帖子
208
15
发表于 2021-8-13 09:26:24 | 只看该作者
继续歪:从编辑器角度来说,你也可以从 rgss.dll 里偷一个 RGSSEval(或者 RGSSGetInt 等更容易使用的)来方便处理 Ruby Marshal 等数据。
一个我滥用 RGSSEval 的例子:https://github.com/hyrious/RgssS ... hEvent/RGSS.cs#L368

点评

c#居然可以加载rgss的dll,但是反过来却不行  发表于 2021-8-13 10:12
喵喵喵
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

16
 楼主| 发表于 2021-8-13 09:55:33 | 只看该作者
hyrious 发表于 2021-8-13 09:14
歪楼:其实 rpg maker 包含运行时和编辑器两个部分,运行时全在 rgss.dll 里,你可以直接拿来调(注意这里 ...

终于钓出大佬来讨论了!

借用dll里的RGSSEval我在论坛的帖子上看过。但貌似那样就只能用win32api来交互了,而且换不掉ruby的版本?感觉作为2D游戏引擎,“不太正规”。
我的工程里内置了完整的ruby,可以require .so库。除了不能-mwindows编译消掉初始的控制台窗口以外,其他的看上去都挺好的(情绪稳定)。然后,包装好RGSS的几个内部类就OK了。整体思路其实更接近zh99998的OpenRGSS:https://rpg.blue/thread-248776-1-1.html
不过相比OpenRGSS,我还有一个额外的设计是让ruby只负责处理逻辑,另一个线程负责绘制。

点评

突然灵机一动就搞定了-mwindows( •̀ ω •́ )y  发表于 2021-8-17 02:00
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
120
在线时间
22 小时
注册时间
2021-4-17
帖子
9
17
发表于 2021-8-13 18:07:53 | 只看该作者
本帖最后由 patchouli4869 于 2021-8-13 18:16 编辑

想起大二時弄的 crpg
https://github.com/mudream4869/crpg
那時候主要是用
1. python 當作每個事件的腳本語言
2. tiled 當作地圖編輯器

不過現在沒在維護了。還是需要先做幾個遊戲再設計架構,那時還是太年輕。

点评

感觉很不错啊,只是没有release版本……  发表于 2021-8-13 20:04
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

18
 楼主| 发表于 2021-8-16 01:54:39 | 只看该作者
实现了Viewport/Sprite/Bitmap的基础功能:https://gitee.com/rmxp/sdlrgss/releases/v0.1.0
1. Bitmap可以读取文件
2. Sprite需要绑定Viewport,在Viewport外不进行绘制
3. Sprite和Viewport都拥有Z值,Z值靠前的显示在前面

接下来可能要先做一下Bitmap#draw_text和Bitmap#blt,然后是图层透明度的混合
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

19
 楼主| 发表于 2021-9-1 14:02:41 | 只看该作者
仔细看了看发现openrgss很多函数都是空着的,其中Bitmap#change_hue可能比较难实现。根据参考文献里的说法,有多种对色调(Hue)的定义。如果使用第2种定义,把RGB值当成空间中的矢量,单纯的对色调进行修改其实是沿着(111)方向的旋转。这样就只需要简单的矩阵乘法即可完成变换。为了提升计算速度,这里甚至打了个表:
C 代码复制
  1. void bitmap_change_hue(uint8_t *data, int size, int hue)
  2. {
  3.     // make table
  4.     array<double, 256 * 3> table;
  5.     // thanks dongjx for generating the rotation matrix
  6. #define PI 3.14159265359
  7.     double k1 = (1 - cos(hue * PI / 180) - sqrt(3) * sin(hue * PI / 180)) / 3;
  8.     double k2 = (1 - cos(hue * PI / 180) + sqrt(3) * sin(hue * PI / 180)) / 3;
  9. #undef PI
  10.     double k0 = 1 - k1 - k2;
  11.     double temp;
  12.     temp = 0.0;
  13.     for (int i = 0; i < 256; i++)
  14.     {
  15.         table[i] = temp;
  16.         temp += k0;
  17.     }
  18.     temp = 0.0;
  19.     for (int i = 256; i < 256 * 2; i++)
  20.     {
  21.         table[i] = temp;
  22.         temp += k1;
  23.     }
  24.     temp = 0.0;
  25.     for (int i = 256 * 2; i < 256 * 3; i++)
  26.     {
  27.         table[i] = temp;
  28.         temp += k2;
  29.     }
  30.     // do convertion
  31.     double x, y, z;
  32.     for (int i = 0; i < size / 4; i++)
  33.     {
  34.         x = *(data);
  35.         y = *(data + 1);
  36.         z = *(data + 2);
  37. #define convert(x, y, z) (uint8_t)(min(255.0, max(0.0, table[x] + table[256 + y] + table[512 + z])))
  38.         *(data) = convert(x, y, z);
  39.         *(data + 1) = convert(y, z, x);
  40.         *(data + 2) = convert(z, x, y);
  41. #undef convert
  42.         data += 4;
  43.     }
  44. }


参考文献: A200804-1390.pdf (320.87 KB, 下载次数: 2)
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
2
星屑
1802
在线时间
179 小时
注册时间
2020-5-21
帖子
121
20
发表于 2021-9-1 14:16:08 | 只看该作者
比起重写一个,我还蛮想在Unity里面重现Rpg Maker的,
继承RPG Maker的各种直观可用性功能,又可以方便拓展更多的功能。

点评

感觉可行,前面楼层里就提到一个大神用GameMakerStudio做了个RMMV  发表于 2021-9-1 14:44
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-25 17:28

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表