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

Project1

 找回密码
 注册会员
搜索
查看: 7692|回复: 66
打印 上一主题 下一主题

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

[复制链接]

Lv5.捕梦者 (版主)

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

开拓者

跳转到指定楼层
1
发表于 2021-7-29 16:56:39 | 显示全部楼层 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
看到大家贡献了这么多的runtime,就想了解一下写这个需要多少知识,然后我发现了这个课程:

Create a 2D Game Engine with C++ & Lua
https://courses.pikuma.com/courses/2dgameengine

共有如下几大章,每章里还有若干小节,果然很难啊……

1 Introduction
2 Libraries & Dependencies
3 Displaying the Game Window
4 Rendering SDL Objects
5 Fixing the Game Time Step
6 Logger
7 Files & Folder Structure
8 Organizing Game Objects
9 ECS Design
10 ECS Implementation
11 Creating Entities & Components
12 Creating Systems
13 Managing Assets
14 Animation System
15 Collision System
16 Killing Entities
17 Event System
18 Other Useful Components & Systems
19 Tagging & Grouping Entities
20 Data-Oriented Design
21 Displaying True-Type Fonts
22 Dear ImGui
23 Culling & Map Control
24 Lua Scripting
25 Next Steps
26 Bonus: The Map Editor
27 Moving Forward

众筹$29.99学费

评分

参与人数 2+2 收起 理由
域外 + 1 非常有帮助!感谢分享
哇哇哇啊叭叭 + 1 仰止

查看全部评分

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

Lv5.捕梦者 (版主)

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

开拓者

2
 楼主| 发表于 2021-8-1 03:32:24 | 显示全部楼层
本帖最后由 guoxiaomi 于 2021-8-1 03:44 编辑

成功写好了0.1个rpgmaker:
  1. #include <rice/rice.hpp>
  2. #include <iostream>

  3. using namespace Rice;

  4. extern "C" void Init_test()
  5. {
  6.     Class rb_cTest = define_class("Test");
  7. }

  8. int main()
  9. {
  10.     std::cout << "Hello, rice" << std::endl;
  11.     ruby_init();
  12.     Init_test();
  13.     rb_eval_string("p Test");
  14.     std::cout << "-- end --" << std::endl;
  15.     return ruby_cleanup(0);
  16. }
复制代码
一顿编译后得到test.exe,执行结果:
  1. Hello, rice
  2. Test
  3. -- end --
复制代码
,范例: test.zip (2.45 MB, 下载次数: 4)
现在只要把SDL加进去
参考资料:
1. rice:https://jasonroelofs.com/rice/4.x/tutorial.html
2. embed ruby:https://silverhammermba.github.io/emberb/embed

编译方法是用rice在mingw64里编译出test.o文件,然后把最终g++编译.so文件的那部分内容改为输出exe就OK了:
  1. g++ -o test.exe test.o -L. -LC:/Ruby30-x64/lib -L. -pipe -s -fstack-protector-strong -pipe -s -fstack-protector-strong -Wl,--enable-auto-image-base,--enable-auto-import test-x64-mingw32.def -m64 -static -Wl,-Bdynamic -lx64-msvcrt-ruby300 -Wl,-Bstatic -lstdc++ -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi
复制代码
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

3
 楼主| 发表于 2021-8-1 22:07:11 | 显示全部楼层
本帖最后由 guoxiaomi 于 2021-8-1 22:28 编辑

SDL也加进去了!
  1. #include <rice/rice.hpp>
  2. #include <SDL2/SDL.h>
  3. #include <iostream>
  4. #include <windows.h>

  5. using namespace Rice;

  6. void Init_test()
  7. {
  8.     Class rb_cTest = define_class("Test");
  9. }

  10. int main(int argc, char *argv[])
  11. {
  12.     ::ShowWindow(::GetConsoleWindow(), SW_HIDE);

  13.     std::cout << "Hello, rice" << std::endl;
  14.     SDL_Window *window = SDL_CreateWindow("demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
  15.     SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

  16.     ruby_init();
  17.     Init_test();
  18.     rb_eval_string("sleep 10");
  19.     SDL_DestroyRenderer(renderer);
  20.     SDL_DestroyWindow(window);
  21.     std::cout << "-- end --" << std::endl;
  22.     return ruby_cleanup(0);
  23. }
复制代码
一顿编译后得到: test2.zip (2.86 MB, 下载次数: 10)
make

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

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

4
 楼主| 发表于 2021-8-2 17:53:57 | 显示全部楼层
本帖最后由 guoxiaomi 于 2021-8-2 17:56 编辑

v0.0.1版发布成功!话说为什么要带这么多的dll…… lib.zip (4.54 MB, 下载次数: 4)
https://gitee.com/rmxp/sdlrgss/releases/v0.0.1
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

5
 楼主| 发表于 2021-8-3 23:26:26 | 显示全部楼层
本帖最后由 guoxiaomi 于 2021-8-4 00:22 编辑

写了个draw_text:
跟右值引用干了一晚上,目前使用了全局变量,情绪非常稳定
20210731-rice-v0.0.2.zip (4.15 MB, 下载次数: 8)

Screenshot 2021-08-03 232359.png (52.71 KB, 下载次数: 21)

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

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

6
 楼主| 发表于 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 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

7
 楼主| 发表于 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 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

8
 楼主| 发表于 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 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

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

开拓者

9
 楼主| 发表于 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

开拓者

10
 楼主| 发表于 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 网络脚本 *
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-5-3 07:05

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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