Delta3D(9)教程:添加消息发送和可激活体

本文详细介绍了如何在Delta3D游戏中响应Space键启动引擎,使用↑键移动坦克,包括游戏事件的创建、发送、处理,以及可激活体的创建和注册。同时讲解了输入组件的实现,通过键盘监听实现坦克的移动控制。此外,还涵盖了游戏循环中的tick事件处理,用于控制坦克的前进和转向。

前面的教程我们创建了一个坦克角色,并通过场景编辑器STAGE,将它加载到场景中,并添加了自带的地形,并调整坦克坐标使贴近地面。
本节将设计让坦克响应Space按下事件来启动引擎,并按 ↑ 让坦克移动起来,即当我们按下Space键的时候发送一个消息,然后让坦克接受消息并根据消息控制引擎的开启和关闭,然后按下 ↑ 键,并在tick事件中让坦克向前贴地移动。

游戏事件

1、简介


Delta3D事件本身只是简单的字符串标识,当某个事件发生后以消息的形式发出,每一个游戏事件都代表一个单独的行为,如发现了苹果,解救了人质等,我们常常混淆了游戏事件和游戏消息。

  • 游戏事件是一个简单的GameEvent数据结构
  • 游戏消息是用来承载GameEvent,然后通过消息发送器发送出去的

Delta3D提供了一个简单的事件管理层,是一个单例类:dtCore::GameEventManager,通过它,可在任何地方查询任何游戏事件。

2、发送事件的过程:


  1. 创建事件并将其注册到事件管理器
m_toggleEngineEvent = new dtCore::GameEvent("ToggleEngine");
dtCore::GameEventManager::GetInstance().AddEvent(*m_toggleEngineEvent);

此时已经创建了游戏事件,然后再通过游戏消息进行承载后发送给其他角色或组件。

  1. 创建游戏消息并发送
    游戏消息是一种只有一个游戏事件作为参数的简单的消息类型。发送消息如下:
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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仿真推演

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值