从零到一:Dora-SSR平台游戏开发框架全解析(含决策树AI实现)
你还在为跨平台2D游戏开发的物理碰撞、角色状态机、AI行为树而头疼吗?作为国产开源游戏引擎的新锐力量,Dora-SSR(Server-Side Rendering)以其独特的Web IDE设计和平台游戏开发框架,正在重新定义移动设备上的游戏开发体验。本文将深入剖析其Platformer模块的核心架构,带你掌握从角色控制器到智能AI的全栈开发能力,最终实现一个可在国产掌机、手机及PC端无缝运行的横版动作游戏原型。
读完本文你将获得:
- 掌握Platformer框架的五层架构设计
- 实现带物理反馈的角色动作系统(行走/攻击/跳跃)
- 构建可视化决策树AI的完整流程
- 学会图层视差滚动与相机跟随算法
- 适配多平台输入的事件处理方案
框架架构概览:从物理世界到行为逻辑
Dora-SSR的平台游戏开发框架采用分层设计,通过模块解耦实现高扩展性。其核心架构可分为五层,每层职责明确且通过接口交互:
flowchart TD
A[PlatformWorld 物理世界层] -->|管理物理引擎| B[Unit 角色实体层]
B -->|执行动作| C[UnitAction 行为控制层]
C -->|决策逻辑| D[DecisionTree 决策树层]
D -->|状态管理| E[BehaviorTree 行为树层]
A -->|相机控制| F[PlatformCamera 视口层]
B -->|碰撞检测| G[Sensor 传感器系统]
核心类关系图谱
平台游戏框架的核心类通过以下关系协同工作:
classDiagram
class PlatformWorld {
+addChild(Node)
+getLayer(int)
+setLayerRatio(int, Vec2)
+onCameraMoved(float, float)
}
class Unit {
+start(String action)
+isOnSurface() bool
+attachAction(String name) UnitAction
+CurrentAction UnitAction*
}
class UnitAction {
<<abstract>>
+run()
+update(float dt)
+stop()
+Status Status
}
class PlatformCamera {
+follow(Node target)
+limitArea(Rect bounds)
+shake(float intensity)
}
class Decision::Leaf {
+evaluate() Status
}
PlatformWorld "1" --> "contains" Unit : units
Unit "1" --> "has many" UnitAction : actions
UnitAction <|-- Walk
UnitAction <|-- Attack
UnitAction <|-- Jump
Unit "1" --> "uses" Decision::Leaf : decisionTree
PlatformWorld "1" --> "has one" PlatformCamera : camera
物理世界构建:PlatformWorld深度解析
PlatformWorld作为平台游戏的场景容器,继承自PhysicsWorld并扩展了图层管理和视差滚动功能。其核心创新在于将传统的场景节点树改造为分层渲染系统,通过Layer类实现不同滚动速率的视差效果。
图层管理实现原理
每个图层(Layer)拥有独立的滚动比率(ratio)和偏移量(offset),当相机移动时,不同图层根据比率计算位移量:
// PlatformWorld.cpp 核心实现代码
void PlatformWorld::onCameraMoved(float deltaX, float deltaY) {
for (auto& [order, layer] : _layers) {
if (layer) {
Vec2 newOffset = layer->getOffset();
newOffset.x += deltaX * (1 - layer->ratio.x);
newOffset.y += deltaY * (1 - layer->ratio.y);
layer->setOffset(newOffset);
}
}
}
使用示例:创建三层视差背景
local world = PlatformWorld.create()
world:setLayerRatio(0, Vec2(1.0, 1.0)) -- 前景层(不滚动)
world:setLayerRatio(1, Vec2(0.5, 0.5)) -- 中景层(半速滚动)
world:setLayerRatio(2, Vec2(0.2, 0.2)) -- 远景层(慢速滚动)
-- 添加图层内容
local bg = Sprite.create("background.png")
world:getLayer(2):addChild(bg)
local mid = Sprite.create("buildings.png")
world:getLayer(1):addChild(mid)
local player = Unit.create("player.json")
world:getLayer(0):addChild(player)
相机系统与边界限制
PlatformCamera提供专业的2D平台游戏相机控制,支持以下特性:
- 平滑跟随(带阻尼效果)
- 边界限制(防止查看场景外区域)
- 冲击效果(受击或跳跃时震动)
- 镜头缩放(支持动态视野调整)
相机跟随实现代码:
// PlatformCamera.cpp
void PlatformCamera::follow(Node* target) {
_target = target;
scheduleUpdate();
}
void PlatformCamera::update(float dt) {
if (!_target) return;
Vec2 targetPos = _target->getPosition();
Vec2 currentPos = getPosition();
Vec2 delta = targetPos - currentPos;
// 应用阻尼平滑
Vec2 newPos = currentPos + delta * (1 - pow(_damping, dt * 60));
setPosition(newPos);
// 边界检查
if (_boundsValid) {
newPos.x = clamp(newPos.x, _bounds.getMinX(), _bounds.getMaxX());
newPos.y = clamp(newPos.y, _bounds.getMinY(), _bounds.getMaxY());
}
}
角色控制器:Unit类与动作系统
Unit类是平台游戏的角色实体核心,继承自PhysicsBody并融合了动作系统、传感器和AI决策能力。其设计遵循"组合优于继承"原则,通过attachAction动态挂载行为组件。
角色状态机设计
Unit的动作系统基于有限状态机实现,每个动作(UnitAction)拥有优先级和状态,系统根据条件自动切换:
stateDiagram-v2
[*] --> Idle
Idle --> Walk: 移动输入
Walk --> Idle: 停止输入
Idle --> Jump: 跳跃输入
Walk --> Jump: 跳跃输入
Jump --> Fall: 上升到顶点
Fall --> Idle: 接触地面
Idle --> Attack: 攻击输入
Walk --> Attack: 攻击输入
Attack --> Idle: 攻击结束
Attack --> Hit: 被攻击
Hit --> Idle: 硬直结束
核心动作实现剖析
以MeleeAttack(近战攻击)为例,看动作系统如何实现完整的攻击流程:
// UnitAction.cpp MeleeAttack实现
void MeleeAttack::onAttack() {
// 1. 获取攻击范围
auto attackRange = _owner->getAttackRange();
pd::Shape shape = createPolygonShape(attackRange.width, attackRange.height);
// 2. 检测碰撞
_owner->getWorld()->queryAABB(
getAttackAABB(),
[this](Body* body) {
if (isEnemy(body)) {
applyDamage(dynamic_cast<Unit*>(body));
}
}
);
// 3. 播放特效
auto effect = Effect::create("sword_slash.efk");
_owner->addChild(effect);
// 4. 播放音效
Audio::play("sword_attack.wav");
}
攻击动作的完整生命周期包括:
- 前摇(Reaction):0.2秒动画准备
- 判定(AttackFrame):碰撞检测与伤害计算
- 后摇(Recovery):0.3秒硬直时间
- 结束(End):返回Idle状态
传感器系统:地面检测与敌人感知
Unit通过三种传感器实现环境交互:
- GroundSensor:检测地面接触(圆形碰撞体)
- DetectSensor:检测视野范围内敌人(矩形碰撞体)
- AttackSensor:攻击判定区域(多边形碰撞体)
// Unit.cpp 传感器初始化
bool Unit::init() {
// 创建地面传感器
_groundSensor = Sensor::createCircle(12);
_groundSensor->setTag(GroundSensorTag);
addChild(_groundSensor);
// 设置检测回调
_groundSensor->onEnter = [this](Body* other) {
_surfaceCount++;
};
_groundSensor->onExit = [this](Body* other) {
_surfaceCount--;
};
return true;
}
// 判断是否在地面上
bool Unit::isOnSurface() const {
return _surfaceCount > 0;
}
AI决策系统:从有限状态机到行为树
Dora-SSR提供双重AI系统:轻量级决策树(DecisionTree)和复杂行为树(BehaviorTree),满足不同复杂度的AI需求。平台游戏框架默认集成决策树系统,通过可视化节点组合实现敌人AI。
决策树节点类型
决策树由以下核心节点构成:
| 节点类型 | 功能描述 | 示例 |
|---|---|---|
| SelNode | 选择节点(或逻辑) | 找到敌人→攻击,否则→巡逻 |
| SeqNode | 序列节点(与逻辑) | 有弹药→瞄准→射击 |
| ConNode | 条件节点 | 生命值<30%→逃跑 |
| ActNode | 行为节点 | 播放"受伤"动画 |
敌人AI实现示例:追击型怪物
以下是一个完整的敌人AI决策树定义:
-- goblin_ai.lua
return {
type = "SelNode",
children = {
-- 条件1:如果生命值低则逃跑
{
type = "SeqNode",
children = {
{ type = "ConNode", condition = "hp_less_30%" },
{ type = "ActNode", action = "flee" }
}
},
-- 条件2:如果看到玩家则追击
{
type = "SeqNode",
children = {
{ type = "ConNode", condition = "see_player" },
{ type = "ActNode", action = "chase" }
}
},
-- 默认:巡逻
{ type = "ActNode", action = "patrol" }
}
}
在C++中加载并执行决策树:
// AI.cpp 决策树执行
void AI::update(float dt) {
if (_decisionTree) {
auto status = _decisionTree->evaluate();
if (status == Behavior::Status::Success) {
// 执行成功
}
}
}
实战开发:横版动作游戏快速上手
环境准备与项目创建
- 获取源码
git clone https://gitcode.com/ippclub/Dora-SSR
cd Dora-SSR
- 启动Web IDE
cd Tools/dora-dora
npm install
npm run dev
- 创建平台游戏项目 在Web IDE中选择"Platformer Game"模板,自动生成包含以下结构的项目:
game_project/
├── assets/ # 资源文件
├── scripts/ # Lua脚本
│ ├── player.lua # 玩家控制器
│ ├── enemy.lua # 敌人AI
│ └── level.lua # 关卡逻辑
└── config.json # 游戏配置
玩家控制器实现
以下是一个完整的玩家控制器实现,包含基本移动和攻击逻辑:
-- player.lua
local Unit = require("Unit")
local Player = class("Player", Unit)
function Player:init()
Player.super.init(self)
-- 初始化属性
self:setMaxHP(100)
self:setHP(100)
self:setSpeed(300)
-- 挂载动作
self:attachAction("walk")
self:attachAction("jump")
self:attachAction("melee_attack")
-- 绑定输入
Input:onKeyDown("a", function()
self:setFaceRight(false)
self:start("walk")
end)
Input:onKeyDown("d", function()
self:setFaceRight(true)
self:start("walk")
end)
Input:onKeyDown("space", function()
self:start("jump")
end)
Input:onKeyDown("j", function()
self:start("melee_attack")
end)
end
return Player
视差滚动实现
通过PlatformWorld的图层系统实现视差效果:
-- level.lua
local world = PlatformWorld.create()
-- 创建背景图层
world:setLayerRatio(1, Vec2(0.1, 0.1)) -- 远景云
world:setLayerRatio(2, Vec2(0.3, 0.3)) -- 中景山
world:setLayerRatio(3, Vec2(0.7, 0.7)) -- 近景树
-- 添加背景元素
local cloudLayer = world:getLayer(1)
for i=1,5 do
local cloud = Sprite.create("cloud.png")
cloud:setPosition(i*200, 100)
cloudLayer:addChild(cloud)
end
-- 设置相机跟随玩家
local camera = world:getCamera()
camera:follow(player)
camera:setBounds(Rect(0, 0, 3200, 240)) -- 限制在关卡范围内
多平台适配:从掌机到PC
Dora-SSR的平台游戏框架特别优化了国产掌机和移动设备的开发体验:
输入系统适配
框架自动适配不同设备的输入方式:
- 键盘:WASD移动,J攻击,K跳跃
- 手柄:左摇杆移动,A键跳跃,X键攻击
- 触摸屏:虚拟摇杆+按钮(自动显示)
// 输入适配代码
void InputAdapter::init() {
#ifdef TARGET_HANDHELD
// 掌机模式:手柄输入
_moveX = Input::getAxis("LeftX");
_jumpButton = Input::getButton("A");
#elif defined(TARGET_MOBILE)
// 移动模式:虚拟按键
createVirtualJoystick();
createVirtualButtons();
#else
// PC模式:键盘输入
_leftKey = Input::getKey("a");
_rightKey = Input::getKey("d");
#endif
}
性能优化策略
针对低配置设备,平台游戏框架提供多重优化:
- 图层剔除:只渲染相机可见区域
- 实体休眠:远离玩家的敌人停止更新
- 资源分级:根据设备性能加载不同分辨率资源
// 实体休眠系统
void PlatformWorld::update(float dt) {
auto cameraRect = _camera->getVisibleRect();
for (auto unit : _units) {
if (cameraRect.contains(unit->getPosition())) {
unit->setActive(true);
unit->update(dt);
} else {
unit->setActive(false);
}
}
}
进阶开发:自定义动作与AI
创建自定义动作
扩展UnitAction实现特殊能力,如冲刺:
// DashAction.h
class DashAction : public UnitAction {
public:
static Own<UnitAction> alloc(Unit* unit) {
return own<DashAction>(unit);
}
virtual void run() override {
// 应用冲刺速度
_owner->setVelocity(Vec2(
_owner->isFaceRight() ? 800 : -800,
_owner->getVelocity().y
));
// 播放特效
auto effect = Effect::create("dash.efk");
_owner->addChild(effect);
}
virtual void update(float dt) override {
_elapsedTime += dt;
if (_elapsedTime > 0.3f) {
stop();
}
}
};
// 注册动作
UnitAction::add("dash", [](){
auto def = new UnitActionDef();
def->name = "dash";
def->priority = 5;
def->reaction = 0.1f;
def->recovery = 0.2f;
def->queued = false;
return def;
}());
高级AI:行为树实现
对于复杂敌人AI,可使用行为树系统:
mindmap
root((Boss AI))
战斗状态
检测玩家
距离判断
近战范围→使用劈砍
中距离→使用突刺
远距离→发射火球
受伤状态
播放受伤动画
后退躲避
濒死状态
生命值<20%
召唤小弟
狂暴模式
总结与展望
Dora-SSR平台游戏开发框架通过模块化设计和跨平台优化,为开发者提供了从快速原型到完整游戏的全流程解决方案。其核心优势在于:
- 低门槛开发:Web IDE支持浏览器直接开发
- 高性能渲染:自研渲染器适配移动设备
- 完整生态链:从物理引擎到AI系统一应俱全
随着国产游戏掌机市场的崛起,Dora-SSR正成为嵌入式游戏开发的理想选择。未来版本将加入:
- 2.5D透视功能
- 骨骼动画融合系统
- 多人联机支持
立即访问项目仓库开始开发:
git clone https://gitcode.com/ippclub/Dora-SSR
cd Dora-SSR/Docs
yarn install
yarn start
通过http://localhost:3000即可打开Web IDE,开启你的平台游戏开发之旅!
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00