尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

GDevelop 导出器与平台(Platform)机制完全指南:GDJS 平台的架构、源码定位与扩展路径

GDevelop 导出器与平台(Platform)机制完全指南:GDJS 平台的架构、源码定位与扩展路径 GDevelop 导出器与平台Platform机制完全指南GDJS 平台的架构、源码定位与扩展路径【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop本文基于 newIDE/docs/How-are-exporters-and-platforms-working.md 展开并结合 GDevelop 仓库中的 C/TypeScript 源码Exporter、EventsCodeGenerator、Runtime 等进行纵深验证。GDevelop 是一个开源、跨平台的 2D/3D 游戏引擎。当你点击“预览”或“导出”按钮时幕后其实有一套层次分明的机制在协同工作——这套机制的核心概念叫做Platform平台。本文面向希望理解 GDevelop 导出体系、阅读其源码、甚至为其增加新导出目标的开发者系统讲解 Platform 的定义、GDJSGDevelop JavaScript 平台的落地实现、一次完整导出在源码中的调用链以及“让 GDevelop 导出到 XXX”的三条可行路线。一、核心概念什么是 Platform在 GDevelop 代码库中Platform是一个用于描述某条游戏目标平台的类。阅读本文前建议先阅读架构总览那里给出了Core、GDJS、GDevelop.js、newIDE、Extensions五个主要目录的分工表。一个 Platform 在 GDevelop 中承担四项职责提供事件代码生成器code generator for events把可视化事件翻译成目标语言代码提供“导出整个游戏或预览”的生成器接收一个gd::Project作为参数负责拷贝全部资源、导出文件、并调用事件代码生成器提供游戏引擎game engine即 Runtime可以理解为一批会被拷贝到游戏资源与事件旁边的文件存储扩展Extensions扩展可以视为游戏引擎的小零件按需被拷贝进最终游戏中。从源码结构看gd::Platform是定义在 Core/GDCore/Extensions/Platform.h 中的一个抽象基类它提供GetName()、GetFullName()、GetIcon()等描述性接口还负责扩展管理AddExtension、GetExtension、ReloadBuiltinExtensions与工厂方法CreateObjectConfiguration、CreateEvent。平台实例由单例 Core/GDCore/IDE/PlatformManager.h 统一管理——GetPlatform(platformName)按名字取平台GetAllPlatforms()列出所有已加载平台。二、当前唯一的平台GDJS到目前为止GDevelop 编辑器里只使用一个Platform即GDJSGDevelop JavaScript platform。你在编辑器里看到的各种导出选项HTML5、Cordova、Electron、Facebook Instant Games 等底层调用的其实是同一个“导出整个游戏”的生成器只是传入了不同的参数例如target不同。这一事实可以在源码中得到印证Exporter::ExportWholePixiProject的主体逻辑只有一份按options.target分支处理cordova、electron、facebookInstantGames以及默认的 HTML5 导出见 GDJS/GDJS/IDE/Exporter.cpp。三、在源码中定位 GDJS 平台的关键零件原文档给出了四个查找入口下面是它们在当前仓库中的具体位置平台零件源码位置事件代码生成器GDJS/GDJS/Events/CodeGeneration导出整个游戏的生成器GDJS/GDJS/IDE游戏引擎RuntimeGDJS/Runtime扩展Extensions 目录中通过JsExtension.cpp或JsExtension.js声明的那些扩展3.1 事件代码生成器GDJS/GDJS/Events/CodeGeneration 目录下可以看到一整套按粒度拆分的生成器EventsCodeGenerator.cpp/h事件整体翻译入口LayoutCodeGenerator.cpp/h场景Layout级别的事件代码生成ObjectCodeGenerator.cpp/h、BehaviorCodeGenerator.cpp/h对象与行为相关代码生成EventsFunctionsExtensionCodeGenerator.cpp/h事件函数扩展的代码生成。正如架构总览所说明的事件在运行时并不存在“RuntimeEvent”这种东西它们会被“编译/转译”成真实语言的代码这一过程就是 Code Generation在 GDJS 中即上述目录见 Core/GDevelop-Architecture-Overview.md。3.2 导出生成器ExporterGDJS/GDJS/IDE 目录包含Exporter.cpp/h与ExporterHelper.cpp/h两个文件。其中gdjs::Exporter对外暴露ExportProjectForPixiPreview(const PreviewExportOptions)生成预览与ExportWholePixiProject(const ExportOptions)整包导出两个核心方法见 Exporter.hgdjs::ExporterHelper承载导出流水线的具体步骤资源拷贝、库文件装配、事件代码生成、index.html生成等。3.3 游戏引擎RuntimeGDJS/Runtime 是 GDJS 的游戏引擎全部用 TypeScript 编写。从目录结构可以看到runtimegame.ts、runtimescene.ts、runtimeobject.ts、runtimebehavior.ts、variablescontainer.ts、timemanager.ts等运行时类还有index.html作为导出 HTML 的模板。渲染部分独立放在 GDJS/Runtime/pixi-renderers 下例如spriteruntimeobject-pixi-renderer.ts、runtimescene-pixi-renderer.ts。3.4 扩展扩展分散在 Extensions 目录。以 Extensions/ExampleJsExtension 为例JsExtension.js是扩展对IDE的“声明”文件dummyruntimeobject.ts、dummyruntimebehavior.ts等则是运行时实现。扩展是平台的一部分只有被项目实际用到的扩展及其依赖文件才会进入最终导出产物。四、一次导出在源码中的完整调用链以“导出为 HTML5 整包”为例结合 GDJS/GDJS/IDE/Exporter.cpp 的ExportWholePixiProject实现整个流程大致是扫描用到的扩展调用gd::UsedExtensionsFinder::ScanProject定义于 Core/GDCore/IDE/Events/UsedExtensionsFinder.h得到一个包含usedExtensions、usedIncludeFiles、usedRequiredFiles、has3DObjects等信息的UsedExtensionsResult准备导出目录fs.MkDir(exportDir)清空includesFiles导出资源helper.ExportResources(...)把项目资源拷贝到导出目录底层会用到 Core/GDCore/IDE/Project/ProjectResourcesCopier.h 的CopyAllResourcesTo一类的工具并更新资源文件名——之所以要先拷资源再生成事件代码是因为事件代码可能依赖更新后的资源文件名装配引擎库helper.AddLibsInclude(...)把 Pixi 渲染器、3D 支持当usedExtensionsResult.Has3DObjects()为真时、加载屏样式等 Runtime 文件加入includesFiles与resourcesFiles追加扩展文件把扫描结果中的GetUsedIncludeFiles()与GetUsedRequiredFiles()合并进上述两个列表——这正是“只有用到的扩展才会被打包”的实现位置导出特效helper.ExportEffectIncludes(...)生成事件代码helper.ExportScenesEventsCode(...)把每个场景的事件翻译为名为codeX.jsX 为场景序号的 JS 文件并写进includesFiles序列化项目数据把去掉事件后的项目结构序列化为data.js含gdjs.runtimeGameOptions加入includesFiles拷贝所有 include 文件与资源文件helper.ExportIncludesAndLibs(includesFiles, exportDir, false)生成index.htmlhelper.ExportIndexFile(...)以gdjsRoot /Runtime/index.html为模板把!--GDJS_CODE_FILES --注释替换为script引入标签。ExportOptions.target会改变模板来源cordova用Runtime/Cordova/www/index.htmlfacebookInstantGames用Runtime/FacebookInstantGames/index.html。ExportWholePixiProject随后按target分支做差异化收尾见 Exporter.cppcordova导出到exportPath/www再生成config.xmlExportCordovaFileselectron导出到exportPath/app再生成 Electron 打包文件与构建资源ExportElectronFiles、ExportBuildResourcesElectronFilesfacebookInstantGames导出后补充 Instant Games 专属文件ExportFacebookInstantGamesFiles默认HTML5导出后补充通用 HTML5 文件ExportHtml5Files其中还包括生成 Web ManifestGenerateWebManifest使导出结果可以成为 PWA。4.1 预览与导出的区别预览走的是ExportProjectForPixiPreview(const PreviewExportOptions)。与整包导出相比PreviewExportOptions定义于 GDJS/GDJS/IDE/ExporterHelper.h携带大量“预览特有”的参数例如SetLayoutName/SetExternalLayoutName指定预览首先运行哪个场景、是否在场景开始时实例化某个外部布局UseWebsocketDebuggerClientWithServerAddress/UseWindowMessageDebuggerClient/UseMinimalDebuggerClient选择调试器客户端连接方式SetIncludeFileHash记录 include 文件的哈希用于预览热重载判断文件是否变化SetNonRuntimeScriptsCacheBurst非零时给非 Runtime 脚本 URL 追加缓存穿透参数强制浏览器重新加载SetIsInGameEdition/SetInGameEditorSettingsJson预览支持“游戏内编辑”时使用AddScreenshotCapture设置延迟秒数与签名/公开 URL供截图/录像采集使用。4.2 从 C 到编辑器的桥接编辑器是纯 JavaScript 应用因此gdjs.Exporter被通过 Emscripten 暴露到 JS 层。在 GDevelop.js/Bindings/Bindings.idl约第 4526–4527 行可以看到boolean ExportProjectForPixiPreview([Const, Ref] PreviewExportOptions options); boolean ExportWholePixiProject([Const, Ref] ExportOptions options);编辑器侧的调用则集中在 newIDE/app/src/ExportAndShareGenericExporters/HTML5Export.js定义html5Exporter导出流水线元信息BrowserExporters/BrowserHTML5Export.js浏览器环境下的 HTML5 导出实现——prepareExporter通过findGDJS(web)定位 GDJS 根目录launchExport里构造new gd.ExportOptions(project, outputDir)并调用exporter.exportWholePixiProject(exportOptions)随后把产出文件打成game.zip供下载BrowserExporters 与 LocalExporters 分别对应浏览器内导出与桌面端本地文件系统导出覆盖 HTML5、Cordova、Electron、Facebook Instant Games 及“在线导出”等变体。另外ExportOptions同文件定义的关键字段target的取值注释明确为cordova、facebookInstantGames、electron见 ExporterHelper.h。五、如何让 GDevelop 导出到 XXX原文档给出了三条路线视目标环境而定情形一目标是现代浏览器环境JavaScript WebGL如果只是想支持一个跑在浏览器里的新目标最省事的做法不是新建平台而是在 IDE 里新增一个导出选项定义一个新的导出流水线外加少量差异化文件比如一个自定义的index.html或一组待导出文件。仓库中 newIDE/app/src/ExportAndShare/GenericExporters/HTML5Export.js 的html5Exporter对象key: webexport、name: HTML5以及 BrowserExporters/BrowserHTML5Export.js 的browserHTML5ExportPipeline就是现成的参照模板。情形二目标是运行 JavaScript 的环境可以继续使用 GDJS但为对象定义新的渲染器。原文档明确举了实验性 Cocos2d-JS 导出的例子对象渲染器用 JavaScript 编写用 Cocos2d-JS 的 API 取代 Pixi.js 来渲染。也就是说逻辑与事件代码生成不变只有“画”这一层被替换。仓库中渲染器分离的现状为此提供了结构支撑对象实现如Extensions/ExampleJsExtension/dummyruntimeobject.ts与 Pixi 渲染器如dummyruntimeobject-pixi-renderer.ts是两个文件渲染器集中在 GDJS/Runtime/pixi-renderers。情形三目标是不运行 JavaScript 的环境这时需要重新创建一个平台像 GDJS 那样。虽然Core库能帮上大忙但你仍然必须重写一个代码生成器面向新语言打造一个全新的游戏引擎或改造现有引擎用新引擎/新渲染器重写各扩展的对象。六、为什么建议写平台Core 库替你做掉的重活写平台确实要写 C 代码但原文档强调“高度推荐”这样做因为Core 库已经替你做了大量工作。结合源码可以验证这些承诺可特化的代码生成器Core的代码生成器支持继承与特化覆盖事件代码生成、表达式代码生成、对象/行为处理以及潜在优化。GDJS 一侧的 EventsCodeGenerator 就是建立在Core基类之上的具体化实例基类见 Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.h。遍历游戏的分析器Analyzers剔除未使用部分ProjectStripper::StripProjectForExport见 Core/GDCore/IDE/ProjectStripper.h在导出前清理项目冗余数据列出资源导出资源拷贝由 ProjectResourcesCopier 等完成检查场景、外部布局、外部事件间的依赖DependenciesAnalyzer::Analyze见 Core/GDCore/IDE/DependenciesAnalyzer.h负责依赖分析。其他工具例如“把所有资源拷贝到某个文件夹”的类即ProjectResourcesCopier等等。从导出调用链可以看出这些分析器是真实串联在ExportWholePixiProject流程中的UsedExtensionsFinder决定打包哪些扩展与 include 文件ProjectStripper保证导出产物不携带编辑器专属冗余DependenciesAnalyzer用于分析场景间依赖。七、别忘了扩展兼容性原文档最后给出一个务实的提醒导出游戏只是一半工作——如果新平台/新导出目标要与 GDevelop 现有生态兼容你多半还要支持与现有平台相同的扩展取决于你追求多高的兼容度。也就是说平台、代码生成器、游戏引擎、扩展四者是耦合的整体评估工作量时应一并考虑。总结Platform是 GDevelop 对“目标平台”的抽象负责事件代码生成、整包导出、游戏引擎与扩展四个部分目前编辑器只有GDJS一个平台所有导出HTML5/Cordova/Electron/Instant Games共用同一套导出生成器仅参数不同完整导出调用链可从 GDJS/GDJS/IDE/Exporter.cpp 读起经ExporterHelper、UsedExtensionsFinder、ExportScenesEventsCode最终由ExportIndexFile装配出可运行的index.html要支持新目标按“浏览器环境 → 加导出选项”、“JS 环境 → 换渲染器”、“非 JS 环境 → 新建平台”三档选择投入量Core 库提供的可特化代码生成器、分析器与工具类是搭建新平台的最大红利扩展兼容性是规划时不可忽略的成本项。建议的下一步阅读架构总览、GDJS 导出生成器头文件、GDevelop.js 绑定定义、编辑器导出流水线。【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表