Project1
标题: How to写一个全新的rpg maker [打印本页]
作者: guoxiaomi 时间: 2021-7-29 16:56
标题: How to写一个全新的rpg maker 看到大家贡献了这么多的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学费
作者: 黑白界 时间: 2021-7-29 21:28
一看就是个大工程,可能需要一个经验丰富的团队开发很长时间。
作者: 真·可乐 时间: 2021-7-30 02:02
我记得B站有个叫红色激情的Up,用GMS仿制了一个RMMV https://b23.tv/GHqjZ4
作者: tuxyin 时间: 2021-7-30 08:24
这个课程之前的名字叫《Fundamentals of 2D Game Engines with C++ SDL and Lua》,曾在udemy上卖9.9$(该课程在udemy上貌似下架了)。现在换个名字卖的这么贵。。。当然,也许作者把课程内容优化的更好了。
作者: guoxiaomi 时间: 2021-8-1 03:32
本帖最后由 guoxiaomi 于 2021-8-1 03:44 编辑
成功写好了0.1个rpgmaker:
#include <rice/rice.hpp>
#include <iostream>
using namespace Rice;
extern "C" void Init_test()
{
Class rb_cTest = define_class("Test");
}
int main()
{
std::cout << "Hello, rice" << std::endl;
ruby_init();
Init_test();
rb_eval_string("p Test");
std::cout << "-- end --" << std::endl;
return ruby_cleanup(0);
} 复制代码 一顿编译后得到test.exe,执行结果:Hello, rice
Test
-- 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了: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 复制代码
作者: enghao_lim 时间: 2021-8-1 14:31
真是怀念的代码……
话说为了ruby用了rice么?
作者: guoxiaomi 时间: 2021-8-1 22:07
本帖最后由 guoxiaomi 于 2021-8-1 22:28 编辑
SDL也加进去了!#include <rice/rice.hpp>
#include <SDL2/SDL.h>
#include <iostream>
#include <windows.h>
using namespace Rice;
void Init_test()
{
Class rb_cTest = define_class("Test");
}
int main(int argc, char *argv[])
{
::ShowWindow(::GetConsoleWindow(), SW_HIDE);
std::cout << "Hello, rice" << std::endl;
SDL_Window *window = SDL_CreateWindow("demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
ruby_init();
Init_test();
rb_eval_string("sleep 10");
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
std::cout << "-- end --" << std::endl;
return ruby_cleanup(0);
}
复制代码 一顿编译后得到:
test2.zip
(2.86 MB, 下载次数: 10)
make
接下来写个事件循环就完事了
作者: guoxiaomi 时间: 2021-8-2 17:53
本帖最后由 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
作者: 哇哇哇啊叭叭 时间: 2021-8-2 19:46
这个水贴好硬核。突然有种想买的冲动...如果这是一贴广告的话,就更硬了
什么是runtime?百度上的翻译感觉完全翻成了另一种外语
作者: guoxiaomi 时间: 2021-8-3 23:26
本帖最后由 guoxiaomi 于 2021-8-4 00:22 编辑
写了个draw_text:[attach]381031[/attach]
跟右值引用干了一晚上,目前使用了全局变量,情绪非常稳定
20210731-rice-v0.0.2.zip
(4.15 MB, 下载次数: 8)
Screenshot 2021-08-03 232359.png
(52.71 KB, 下载次数: 39)
作者: guoxiaomi 时间: 2021-8-7 01:17
本帖最后由 guoxiaomi 于 2021-8-7 01:34 编辑
写了个渲染的循环:
release.zip
(3.94 MB, 下载次数: 6)
我准备了2个std::vector,分别在不同的线程(ruby线程和渲染线程)里添加和执行指令。
设计中ruby里的所有绘制相关的函数调用都不实际执行,而是向commands_in里push命令。void renderer_loop(cen::renderer &renderer, void(function(Command &&, cen::renderer &)))
{
while (!program_terminate)
{
if (commands_out.empty())
{
if (!commands_in.empty())
{
swap_queues();
}
continue;
}
for (auto cmd : commands_out)
{
if (cmd.id == Command_Code::Frame_End)
{
num_frame_out--;
if (num_frame_out > 0)
{
continue;
}
}
function(std::move(cmd), renderer);
}
commands_out.clear();
}
} 复制代码 然后增加了一个跳帧的设定,当负责渲染的线程检查到有多个Frame_End的指令时,只有最后一帧才会尝试渲染所有的画面,前面的Frame_End指令跳过。
作者: pporder 时间: 2021-8-7 02:04
硬核……(码了就是跑了系列
作者: guoxiaomi 时间: 2021-8-13 01:47
成功绘制了图片!https://gitee.com/rmxp/sdlrgss/releases/v0.0.6
ruby代码为:class Bitmap
attr_reader :x , :y
def initialize( path)
@x = @y = 0
Core._bitmap_new_path( self , path)
end
def x=( x)
@x = x
Core._bitmap_set_xy( self , @x , @y )
end
def y=( y)
@y = y
Core._bitmap_set_xy( self , @x , @y )
end
def dispose
Core._bitmap_dispose( self )
end
end
b1 = Bitmap.new ( "resource/001-Fighter01.png" )
b2 = Bitmap.new ( "resource/001-Fighter01.png" )
t = Time .now
1000 .times do
b1.y = ( b1.y + 1 ) % 320
b2.x = ( b2.x + 1 ) % 320
Core.frame_end
Core.wait_renderer
end
p "FPS: #{1000 / (Time.now - t)}"
b1.dispose
b2.dispose
b1 = b2 = nil
class Bitmap
attr_reader :x , :y
def initialize( path)
@x = @y = 0
Core._bitmap_new_path( self , path)
end
def x=( x)
@x = x
Core._bitmap_set_xy( self , @x , @y )
end
def y=( y)
@y = y
Core._bitmap_set_xy( self , @x , @y )
end
def dispose
Core._bitmap_dispose( self )
end
end
b1 = Bitmap.new ( "resource/001-Fighter01.png" )
b2 = Bitmap.new ( "resource/001-Fighter01.png" )
t = Time .now
1000 .times do
b1.y = ( b1.y + 1 ) % 320
b2.x = ( b2.x + 1 ) % 320
Core.frame_end
Core.wait_renderer
end
p "FPS: #{1000 / (Time.now - t)}"
b1.dispose
b2.dispose
b1 = b2 = nil
可以看到Bitmap(其实更像是RGSS的Sprite)其实是个没啥东西的类,而Core.XXX函数只是传输指令,并没有实际执行任何东西。图片的加载和渲染在另一个线程里异步完成。
作者: hyrious 时间: 2021-8-13 09:14
歪楼:其实 rpg maker 包含运行时 和编辑器 两个部分,运行时全在 rgss.dll 里,你可以直接拿来调(注意这里只能用 RGSS300,因为 301 有壳不让 gcc 链接):
#include <windows.h>
int CALLBACK WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
wchar_t *rgssad = NULL;
RGSSInitialize3();
RGSSSetupFonts();
RGSSGameMain(
CreateWindowEx(0, "#32770", "RGSSGameMain", 0x90cf0000,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
0, 0, 0, 0),
L"Scripts.rvdata2",
&rgssad);
return 0;
} 复制代码 gcc -O3 -static -s -o player player.c RGSS300.dll -m32 -w && player 复制代码 而坛友的编辑器据我所知目前只有 UCCU 可以一战(逃
作者: hyrious 时间: 2021-8-13 09:26
继续歪:从编辑器 角度来说,你也可以从 rgss.dll 里偷一个 RGSSEval(或者 RGSSGetInt 等更容易使用的)来方便处理 Ruby Marshal 等数据。
一个我滥用 RGSSEval 的例子:https://github.com/hyrious/RgssS ... hEvent/RGSS.cs#L368
作者: guoxiaomi 时间: 2021-8-13 09:55
终于钓出大佬来讨论了!
借用dll里的RGSSEval我在论坛的帖子上看过。但貌似那样就只能用win32api来交互了,而且换不掉ruby的版本?感觉作为2D游戏引擎,“不太正规”。
我的工程里内置了完整的ruby,可以require .so库。除了不能-mwindows编译消掉初始的控制台窗口以外,其他的看上去都挺好的(情绪稳定)。然后,包装好RGSS的几个内部类就OK了。整体思路其实更接近zh99998的OpenRGSS:https://rpg.blue/thread-248776-1-1.html
不过相比OpenRGSS,我还有一个额外的设计是让ruby只负责处理逻辑,另一个线程负责绘制。
作者: patchouli4869 时间: 2021-8-13 18:07
本帖最后由 patchouli4869 于 2021-8-13 18:16 编辑
想起大二時弄的 crpg
https://github.com/mudream4869/crpg
那時候主要是用
1. python 當作每個事件的腳本語言
2. tiled 當作地圖編輯器
不過現在沒在維護了。還是需要先做幾個遊戲再設計架構,那時還是太年輕。
作者: guoxiaomi 时间: 2021-8-16 01:54
实现了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,然后是图层透明度的混合
作者: guoxiaomi 时间: 2021-9-1 14:02
仔细看了看发现openrgss很多函数都是空着的,其中Bitmap#change_hue可能比较难实现。根据参考文献里的说法,有多种对色调(Hue)的定义。如果使用第2种定义,把RGB值当成空间中的矢量,单纯的对色调进行修改其实是沿着(111)方向的旋转。这样就只需要简单的矩阵乘法即可完成变换。为了提升计算速度,这里甚至打了个表:
void bitmap_change_hue( uint8_t *data, int size, int hue)
{
// make table
array<double, 256 * 3 > table;
// thanks dongjx for generating the rotation matrix
#define PI 3.14159265359
double k1 = ( 1 - cos( hue * PI / 180 ) - sqrt( 3 ) * sin( hue * PI / 180 ) ) / 3 ;
double k2 = ( 1 - cos( hue * PI / 180 ) + sqrt( 3 ) * sin( hue * PI / 180 ) ) / 3 ;
#undef PI
double k0 = 1 - k1 - k2;
double temp;
temp = 0.0 ;
for ( int i = 0 ; i < 256 ; i++)
{
table[ i] = temp;
temp += k0;
}
temp = 0.0 ;
for ( int i = 256 ; i < 256 * 2 ; i++)
{
table[ i] = temp;
temp += k1;
}
temp = 0.0 ;
for ( int i = 256 * 2 ; i < 256 * 3 ; i++)
{
table[ i] = temp;
temp += k2;
}
// do convertion
double x, y, z;
for ( int i = 0 ; i < size / 4 ; i++)
{
x = *( data) ;
y = *( data + 1 ) ;
z = *( data + 2 ) ;
#define convert(x, y, z) (uint8_t)(min(255.0, max(0.0, table[x] + table[256 + y] + table[512 + z])))
*( data) = convert( x, y, z) ;
*( data + 1 ) = convert( y, z, x) ;
*( data + 2 ) = convert( z, x, y) ;
#undef convert
data += 4 ;
}
}
void bitmap_change_hue( uint8_t *data, int size, int hue)
{
// make table
array<double, 256 * 3 > table;
// thanks dongjx for generating the rotation matrix
#define PI 3.14159265359
double k1 = ( 1 - cos( hue * PI / 180 ) - sqrt( 3 ) * sin( hue * PI / 180 ) ) / 3 ;
double k2 = ( 1 - cos( hue * PI / 180 ) + sqrt( 3 ) * sin( hue * PI / 180 ) ) / 3 ;
#undef PI
double k0 = 1 - k1 - k2;
double temp;
temp = 0.0 ;
for ( int i = 0 ; i < 256 ; i++)
{
table[ i] = temp;
temp += k0;
}
temp = 0.0 ;
for ( int i = 256 ; i < 256 * 2 ; i++)
{
table[ i] = temp;
temp += k1;
}
temp = 0.0 ;
for ( int i = 256 * 2 ; i < 256 * 3 ; i++)
{
table[ i] = temp;
temp += k2;
}
// do convertion
double x, y, z;
for ( int i = 0 ; i < size / 4 ; i++)
{
x = *( data) ;
y = *( data + 1 ) ;
z = *( data + 2 ) ;
#define convert(x, y, z) (uint8_t)(min(255.0, max(0.0, table[x] + table[256 + y] + table[512 + z])))
*( data) = convert( x, y, z) ;
*( data + 1 ) = convert( y, z, x) ;
*( data + 2 ) = convert( z, x, y) ;
#undef convert
data += 4 ;
}
}
参考文献:
A200804-1390.pdf
(320.87 KB, 下载次数: 2)
作者: yayapipifly 时间: 2021-9-1 14:16
比起重写一个,我还蛮想在Unity里面重现Rpg Maker的,
继承RPG Maker的各种直观可用性功能,又可以方便拓展更多的功能。
作者: xiaohuangdi 时间: 2021-9-1 18:02
大佬不如用Unity做一個開源 RPGmaker的功能啊
11區的幾個黃油大社團現在都用同一個Unity模板
作者: guoxiaomi 时间: 2021-9-23 00:40
本帖最后由 guoxiaomi 于 2021-9-23 00:43 编辑
把Sprite、Plane、Window和Tilemap都写好了:
其实Tilemap没有想象中难写……反而是window最麻烦。
1920x1080的Tilemap轻松120帧
作者: phunmung5173 时间: 2021-9-23 09:53
渲染怎麽解決的... 感覺這方面是最難的坎 但是看樓主好像跳過了。
作者: 搞事 时间: 2021-9-23 10:39
牛逼啊,改天发我的看看有啥问题
作者: 搞事 时间: 2021-9-23 10:42
我的只是一个引擎,没有用来写rm,只是自己写游戏用的
作者: 搞事 时间: 2021-9-23 21:56
/*
* 游戏引擎
*/
#ifndef _GAMENGINE_H_
#define _GAMENGINE_H_
// 包含库
#include "Configure_Engine.h" // 引擎配置参数
#include "Engine_Graphics.h" // 渲染部分
#include "Engine_DataBase.h" // 数据部分
#include "Manager_UI.h" // UI部分
#include "Manager_View.h" // 场景部分
// 声明类
class GameEngine;
// 外部定义
extern GameEngine* g_eng; // 全局 - 游戏引擎
// 游戏引擎 实现类
class GameEngine {
private:
// 基础属性
bool eng_iskeep; // 可持续
unsigned int eng_errorvalue; // 错误值
unsigned int eng_state; // 引擎状态
// 错误类型
private:
// win32程序属性 -- 句柄
HWND m_hwnd; // 句柄
HINSTANCE m_hinstance; // 线程进程
HMENU m_hemnu; // 菜单
HCURSOR m_hcursor; // 光标
HICON m_hicon; // 图标
HBRUSH m_hbrush; // 画刷
// win32程序属性 -- 基础属性
int m_x, m_y, m_width, m_height;
bool m_fullscreen;
private:
vector<Data_San9Event*> eng_eventlist; // 事件列表
public:
// 构造
GameEngine();
// 析构
~GameEngine();
// 释放引擎
void ReleaseEngine();
// 初始化句柄
void InithInst(HINSTANCE hinstance);
// 初始化引擎
void InitEngine();
// 初始化引擎
// x,y,width,height == 程序窗口大小
// Fullscreen == 全屏(默认全屏)
void InitEngine(int x,int y,int width,int height,bool full = true);
// 运行引擎
void RunEngine();
public: // 相关 win32程序
// 接收win32消息
void CheckWin32Msg(UINT msg, WPARAM wp, LPARAM lp);
public:
// 判定引擎是否结束更新
bool IsActivity();
private:
// 发送结束引擎消息
void SelfKill();
private:
// 初始化win32程序
void InitWin32Process();
// 初始化渲染部分
void InitGraphicsProcess();
// 初始化数据库部分
void InitDataBaseProcess();
// 初始化场景控制部分
void InitViewControlProcess();
// 处理事件
void Engine_CheckEvent();
// 处理更新
void Engine_Update();
// 处理渲染
void Engine_Draw();
};
#endif // !_GAMENGINE_H_
作者: 搞事 时间: 2021-9-23 21:57
#include "GameEngine.h"
// 游戏引擎生成
GameEngine* g_eng = new GameEngine();
// 游戏引擎 - win32回调函数
// 唯一性
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_KEYDOWN:
case WM_KEYUP:
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_CHAR:
case WM_ACTIVATE:
{
if (g_eng != nullptr) {
g_eng->CheckWin32Msg(msg, wp, lp);
}
}
break;
case WM_DESTROY:
{
bool result = false;
if (g_eng != nullptr) {
result = g_eng->IsActivity();
}
if (result) {
PostQuitMessage(0);
}
}
break;
default:
break;
}
return DefWindowProc(hwnd, msg, wp, lp);
}
// 构造
GameEngine::GameEngine() {
// 基础属性
eng_iskeep = true; // 可持续
eng_errorvalue = 0x00; // 错误值 - 0
eng_state = SYS_STATE_BEGIN; // 引擎状态 - 刚开始
// win32程序属性 -- 句柄
// win32程序属性 -- 基础属性
m_x = 0, m_y = 0, m_width = 1024, m_height = 769; // 固定像素大小
m_fullscreen = true; // 默认全屏
}
// 析构
GameEngine::~GameEngine() {
}
// 释放引擎
void GameEngine::ReleaseEngine() {
}
// 初始化句柄
void GameEngine::InithInst(HINSTANCE hinstance) {
m_hinstance = hinstance;
}
// 初始化引擎
void GameEngine::InitEngine() {
// 初始化 win32程序
InitWin32Process();
// 初始化 渲染部分
InitGraphicsProcess();
// 初始化 数据库部分
InitDataBaseProcess();
// 初始化场景控制部分
InitViewControlProcess();
}
// 初始化引擎
// x,y,width,height == 程序窗口大小
// Fullscreen == 全屏(默认全屏)
void GameEngine::InitEngine(int x, int y, int width, int height, bool full) {
// 设置属性
m_fullscreen = full;
if (!m_fullscreen) {
m_x = x;
m_y = y;
m_width = width;
m_height = height;
}
else {
m_x = 0;
m_y = 0;
m_width = GetSystemMetrics(SM_CXSCREEN) - 1;
m_height = GetSystemMetrics(SM_CYSCREEN) - 1;
}
// 初始化引擎
InitEngine();
}
// 初始化win32程序
void GameEngine::InitWin32Process() {
// 属性配置
// 背景画刷
if (m_hbrush == nullptr) {
m_hbrush = CreateSolidBrush(RGB(0, 0, 0));
}
// 默认光标
if (m_hcursor == nullptr) {
m_hcursor = LoadCursor(NULL, IDC_ARROW);
}
// 默认图标
if (m_hicon == nullptr) {
m_hicon = LoadIcon(NULL, IDI_APPLICATION);
}
// 窗口创建
// 信息结构体
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = m_hbrush;
wc.hCursor = m_hcursor;
wc.hIcon = m_hicon;
wc.lpfnWndProc = WindowProc;
wc.hInstance = m_hinstance;
wc.lpszClassName = "youguess";
wc.lpszMenuName = "sometitle";
// 注册
if (!RegisterClassEx(&wc)) {
return;
}
else {
// 创建窗口
DWORD tmp_style = m_fullscreen ? (WS_MAXIMIZE | WS_POPUP) : WS_POPUP;
m_hwnd = CreateWindow(
wc.lpszClassName, "san9pk",
tmp_style,
m_x, m_y, m_width, m_height,
NULL, NULL, m_hinstance, NULL
);
// 创建失败
if (m_hwnd == NULL) {
}
}
}
// 初始化渲染部分
void GameEngine::InitGraphicsProcess() {
bool result = true;
// 非全屏
if (!m_fullscreen) {
result = Engine_Graphics::InitGraphics(m_hwnd, RECT{ (LONG)m_x, (LONG)m_y, (LONG)m_width, (LONG)m_height });
}
}
// 初始化数据库部分
void GameEngine::InitDataBaseProcess() {
if (g_data != nullptr) {
return;
}
g_data = new DataBase();
g_data->InitDataBase();
}
// 初始化场景控制部分
void GameEngine::InitViewControlProcess() {
if (g_view != nullptr) {
return;
}
g_view = new Manager_View();
g_view->Init();
}
// 处理事件
void GameEngine::Engine_CheckEvent() {
// 处理事件
unsigned int index = 0;
while (1) {
// 索引
if (index >= eng_eventlist.size()) {
break;
}
index++;
}
// 清空事件列表
eng_eventlist.clear();
}
// 处理更新
void GameEngine::Engine_Update() {
//
if (eng_state == SYS_STATE_EXIT) {
return;
}
else {
if (eng_state == SYS_STATE_BEGIN) {
eng_state = SYS_STATE_KEEP;
}
else {
// 场景更新
if (g_view != nullptr) {
g_view->Update();
}
}
}
// 渲染系统更新
Manager_UI::Update();
}
// 处理渲染
void GameEngine::Engine_Draw() {
// 开始 + 清屏
Engine_Graphics::Begin();
//
if (eng_state == SYS_STATE_EXIT) {
return;
}
else {
// 场景渲染
if (g_view != nullptr) {
g_view->Draw();
}
}
// UI系统绘制
Manager_UI::Draw();
// 结束
Engine_Graphics::End();
}
// 运行引擎
void GameEngine::RunEngine() {
// 窗体已创建
if (m_hwnd != NULL) {
// 显示和更新窗口
if (m_fullscreen) {
ShowWindow(m_hwnd, SW_MAXIMIZE);
}
else {
ShowWindow(m_hwnd, SW_SHOW);
}
UpdateWindow(m_hwnd);
// 消息循环
MSG msg = { 0 };
while (1) {
// 窗口消息
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
// 系统处理机制
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT) {
break;
}
}
else {
// 计时器
Engine_CheckEvent();
Engine_Update();
Engine_Draw();
}
}
}
}
// 接收win32消息
void GameEngine::CheckWin32Msg(UINT msg, WPARAM wp, LPARAM lp) {
// 渲染部分
Manager_UI::CheckUpdate(msg, wp, lp);
// 场景部分
if (g_view != nullptr) {
g_view->CheckUpdate(msg, wp, lp);
}
}
// 判定引擎是否结束更新
bool GameEngine::IsActivity() {
return (eng_state == SYS_STATE_EXIT);
}
// 发送结束引擎消息
void GameEngine::SelfKill() {
if (m_hwnd != nullptr) {
// 状态值更新
eng_state = SYS_STATE_EXIT;
// 立即发送摧毁窗口消息
PostMessage(m_hwnd, WM_DESTROY, 0, 0);
}
}
作者: 搞事 时间: 2021-9-23 21:58
感觉直接发代码好像不太好
作者: guoxiaomi 时间: 2021-9-24 01:37
没有用SDL嘛,那画面上的内容是用什么画的?
作者: 搞事 时间: 2021-9-24 10:10
用的direct2d渲染的
作者: guoxiaomi 时间: 2021-9-26 01:09
渐变也做好了!现在绘图相关的应该都完成了。
作者: 小凡哥 时间: 2021-9-27 12:20
太强了,大佬
如果能顺利重写引擎的话,感觉可以直接超出“RPG maker”这个限制了
作者: b565185756 时间: 2021-10-1 13:31
先捕捉了宇宙最强的郭兄大人再说。。
作者: guoxiaomi 时间: 2021-10-3 15:46
本帖最后由 guoxiaomi 于 2021-10-3 16:09 编辑
做了个勉强能发布的版本v0.7.4:https://7niu.gxmatmars.com/p1/asxp/release_v0.7.4.zip
1. 已经在windows10沙盒里测试完毕。沙盒里安装RMXP后,工程可以正常打开
2. 工程里使用了默认素材。如果RTP没有安装在默认路径(C:\Program Files (x86)\RPG Maker XP\RGSS\Standard)下,就必须把RTP的Audio和Graphics拷贝到工程目录下,否则会找不到素材。
3. 这个版本没有声音。双击exe到窗口出现,以及标题画面出现各有一点点延迟
4. 可以修改Core/main.rb里的帧率
接下来的计划是测试完所有RGSS默认的事件确保兼容性,然后添加Audio模块,就差不多可以发布了吧?
自问:道理我都懂,但那个xxx.dll为什么那么大
自答:那是enigma virtual box打包的package,里面有完整的ruby3.0.0和SDL2全家桶的DLL。后缀名改为.dll是迷惑使用者。
打开后你应该能看到这个:
作者: siry冷月 时间: 2021-10-3 22:13
过于硬核的水贴,插眼。
作者: 哇哇哇啊叭叭 时间: 2021-10-4 09:10
本帖最后由 哇哇哇啊叭叭 于 2021-10-4 15:13 编辑
突然觉得做游戏不香了想要转头学习脚本
[line]6[/line]
这个runtime是干什么用的呢?
试着下载了一下,感觉跟正常的xp没太有区别呢(但其实肯定是有区别 啦)。看题目和之前的楼,是不是:
1. 楼主把RM重写了一遍
2. 可以在脚本中使用Ruby3.0和SDL。因此可以使用一些Ruby中比较新的语法、可以实现跨平台
这个引擎是不是就是做这些用的呢?
作者: RPGzh500223 时间: 2021-10-4 10:14
哈哈,不明觉厉。
可惜是我不能用的样子,电脑太烂了,配置什么的不懂,举个例子,玩英雄联盟都卡的那种。
我打开资源管理器,与RMXP做了下对比。内存不知道干什么了(地图和菜单场景都差不多??),是RMXP的4倍的样子,
地图场景时,CPU占用高,与菜单场景和RMXP的地图场景比较的话,我大胆的猜测tilemap写得不算好……
切换场景好像GPU(不知道是干什么用的)也用了。
然后就是事件开天气之后,非常卡,慢镜头的感觉,关闭天气时,报错
小问题:场景切换有点“生硬”
error.png
(181.5 KB, 下载次数: 36)
作者: guoxiaomi 时间: 2021-10-4 17:44
本帖最后由 guoxiaomi 于 2021-10-4 17:47 编辑
感谢测试!
我其实只测完了动画就放出来了,天气还没测试。内存占用目前也没有仔细测试,感觉好像就40M左右的样子,但应该没有内存泄漏(指内存占用会随着运行时间不停的增长)?如果你是集显,会使用内存当显存,可能会占的比较多?
场景切换的生硬具体是指啥?以及你的cpu型号和占用比例大概是多少?我这个是异步的需要2核才能正常运行。
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1