前面的教程我们创建了一个坦克角色,并通过场景编辑器STAGE,将它加载到场景中,并添加了自带的地形,并调整坦克坐标使贴近地面。
本节将设计让坦克响应Space按下事件来启动引擎,并按 ↑ 让坦克移动起来,即当我们按下Space键的时候发送一个消息,然后让坦克接受消息并根据消息控制引擎的开启和关闭,然后按下 ↑ 键,并在tick事件中让坦克向前贴地移动。
游戏事件
1、简介
Delta3D事件本身只是简单的字符串标识,当某个事件发生后以消息的形式发出,每一个游戏事件都代表一个单独的行为,如发现了苹果,解救了人质等,我们常常混淆了游戏事件和游戏消息。
- 游戏事件是一个简单的GameEvent数据结构
- 游戏消息是用来承载GameEvent,然后通过消息发送器发送出去的
Delta3D提供了一个简单的事件管理层,是一个单例类:dtCore::GameEventManager,通过它,可在任何地方查询任何游戏事件。
2、发送事件的过程:
- 创建事件并将其注册到事件管理器
m_toggleEngineEvent = new dtCore::GameEvent("ToggleEngine");
dtCore::GameEventManager::GetInstance().AddEvent(*m_toggleEngineEvent);
此时已经创建了游戏事件,然后再通过游戏消息进行承载后发送给其他角色或组件。
- 创建游戏消息并发送
游戏消息是一种只有一个游戏事件作为参数的简单的消息类型。发送消息如下:
dtCore::RefPtr<dtGame::GameEventMessage> eventMsg;
this->GetGameManager()->GetMessageFactory().CreateMessage(dtGame::MessageType::INFO_GAME_EVENT, eventMsg);
eventMsg->SetGameEvent(*m_toggleEngineEvent);
this->GetGameManager()->SendMessage(*eventMsg);
以上代码通过游戏管理器的消息工厂创建了一个游戏消息,然后向该消息绑定事件,并通过游戏管理器发送该消息。
可激活体
1、简介
可以把可激活体想象成事件回调,它可以像属性一样被处理,即可激活体和方法调用的概念就像属性和数据成员的概念。
可激活体在角色代理被创建的时候创建,有名称,通过名称可对其进行访问。以下是创建可激活体的示例:
// 这是系统默认的可激活体,即父类定义的虚函数,子类继承可重写实现,用于系统消息的处理
void TankActor::ProcessMessage(const dtGame::Message& message)
{
const dtGame::GameEventMessage& eventMsg = static_cast<const dtGame::GameEventMessage&>(message);
if (eventMsg.GetGameEvent() != nullptr)
{
auto eventName = eventMsg.GetGameEvent()->GetName();
if (eventName == "ToggleEngine") // 启动引擎的消息
{
m_isEngineRunning = !m_isEngineRunning;
m_dust->SetEnabled(m_isEngineRunning); // m_dust在头文件中定义的粒子系统,dtCore::RefPtr<dtCore::ParticleSystem>,在OnEnteredWorld中创建
/*
m_dust = new dtCore::ParticleSystem;
m_dust->LoadFile("resources/Particles/dust.osg");
m_dust->SetEnabled(false);
AddChild(m_dust);
*/
}
else if (eventName == "SpeedBoost")
{
setVelocity(m_velocity + -5);
}
}
}

2、创建可激活体
为了创建自定义的可激活体,我们要创建自己的消息处理函数并把它封装到一个可激活体中,这个工作可以在游戏角色代理GameActorProxy的BuildInvokables()函数中完
成,BuildInvokables在游戏角色被创建时调用。
2.1 创建格式
void TankActorProxy::BuildInvokables()
{
dtActors::GameMeshActor::BuildInvokables();
TankActor* actor = this->GetDrawable<TankActor>();
// 创建自定义的可激活体
this->AddInvokable(*new dtGame::Invokable("MyInvokableName",
dtUtil::MakeFunctor(&TankActor::MyInvokableFunc, actor))); // MyInvokableFunc为自定义响应函数,原型为:void MyInvokable(const dtGame::Message& message);
}
2.2 注册可激活体
我们需要将可激活体注册到游戏管理器GameManager,一般在Proxy的OnEnterWorld()中完成这项工作,该函数会在角色被添加到游戏管理器中的时候被调用,创建和注册自定义的可激活体需要使用相同的名称,如下:
// TankActorProxy.cpp
void TankActorProxy::OnEnteredWorld()
{
// 注册自定义的可激活体
RegisterForMessages(MyGameMessageType::MyInvokableMessageType, "MyInvokableName");
// 注册消息有两种方式
/*
RegisterForMessageAboutOtherActor() 和 RegisterForMessageAboutSelf()
第二种可以只处理自己Actor发送的消息,即别的Actor关闭了引擎,不会影响自己
需要在创建事件时设置角色Id,eventMsg->setAboutActorId();
*/
// 以下为系统默认的可激活体注册方式
// 注册游戏消息,会自动发送到ProcessMessage可激活体
RegisterForMessages(dtGame

本文详细介绍了如何在Delta3D游戏中响应Space键启动引擎,使用↑键移动坦克,包括游戏事件的创建、发送、处理,以及可激活体的创建和注册。同时讲解了输入组件的实现,通过键盘监听实现坦克的移动控制。此外,还涵盖了游戏循环中的tick事件处理,用于控制坦克的前进和转向。
教程:添加消息发送和可激活体&spm=1001.2101.3001.5002&articleId=126474835&d=1&t=3&u=7a4f8594a1a24daa97344146a006aa5b)
1920

被折叠的 条评论
为什么被折叠?



