UI引擎开发系列(二) 事件分发处理

UI场景中事件分发处理实例

#pragma once
#include "Tcl.h"
#include "Component/CTSingleton.h"

using namespace tcl;


//场景类 需要继承CSingleScene,场景类有自己的事件处理等 
class CLogicEventScene : public CSingleScene,public CTSingleton<CLogicEventScene>
{
public:
	CLogicEventScene();

	//这两个方法会在每帧渲染的时候都被调用,调用顺序是先调用UpdateSingleScene,然后是2DScene。
	//可以在OnUpdate2DScene中绘制FPS帧率,这样不会被3D物体遮挡。
	void OnUpdateSingleScene();
	
	//!
	void OnUpdate2DScene();

	//这两个方法用于加载blender资源

	//直接解析一个blender文件,将blender所包含的物体、动画、图片等数据都加载到引擎
	//需要走一次完整的blender解析流程
	void LoadBlenderScene();
	
	//需要先将blender解析成xml文件包,以后每次用下面的接口把解析结果加载到引擎
	//这种方法不需要每次都解析blender文件,只是加载解析好的资源,所以加快了加载速度。
	void LoadBlenderSceneXML();

	//场景事件处理
	bool OnEvent(const SEvent& in_event);

	int GetSingleSceneType(){return 0;}

	//创景logic层创建
	void CreateLogicNode();

	//Node for Logic
public:
	//当前场景鼠标选中物体实例
	ISceneNode* m_MouseCollisionNode;
	//主页面和全部应用页面的父节点,用于动画
	ISceneNode* m_HomeParent;
	ISceneNode* m_AllAppParent;
private:
	//单例实现
	CT_DECLARE_SINGLETON(CLogicEventScene)
	
};

#include "CLogicEventScene.h"
#include "CLogicNodeManager.h"
#include "CLogicTree.h"
#include "Component/CStateMachineLogic.h"
#include "CHomeLogic.h"
#include "CAllAppLogic.h"


CLogicEventScene::CLogicEventScene()
{
#ifdef ANDROID_NDK
	//android版本推荐使用xml加载方式,只需要TCLMainInterface的getDataName方法中返回资源包的名字即可。
	//不再需要单独调用。
#else
	//win版开发调试可以使用两种模式的任何一种。直接加载blender文件的优势在于当blender文件变动频繁时,
	//不需要每次都先把blender解析成xml。

	//LoadBlenderScene();
	LoadBlenderSceneXML();
#endif
	//创建logic层
	CreateLogicNode();
	//获取两个页面父节点,这两个父节点的名字从blender中获取
	m_HomeParent = m_pSmgr->getSceneNodeFromName("Empty_01a");
	m_AllAppParent = m_pSmgr->getSceneNodeFromName("Empty_02a");
}

//直接解析一个blender文件,将blender所包含的物体、动画、图片等数据都加载到引擎
//需要走一次完整的blender解析流程
void CLogicEventScene::LoadBlenderScene()
{
	m_pSmgr->loadBlenderFile("./data/launcher.blend");
}

//需要先将blender解析成xml文件包,以后每次用下面的接口把解析结果加载到引擎
//这种方法不需要每次都解析blender文件,只是加载解析好的资源,所以加快了加载速度。
void CLogicEventScene::LoadBlenderSceneXML()
{
	//打开资源包
	m_pISingleSceneManger->GetTclDevice()->getFileSystem()->addZipFileArchive("./data/libLogicEventData.so");
	//读取xml 
	io::IReadFile* xmlRead = m_pSmgr->getFileSystem()->createAndOpenFile("./data/secenDes.xml");
	if (xmlRead)
	{
		//加载场景
		m_pSmgr->loadScene(xmlRead); 
	}
	xmlRead->drop();
}
	

//纯虚函数 必须实现
void CLogicEventScene::OnUpdateSingleScene()
{
	
}

//每帧都会被调用。调用在物体绘制以后,所以这里面处理FPS等可以避免被3D物体遮挡。
void CLogicEventScene::OnUpdate2DScene()
{
	int fps = m_pSmgr->getVideoDriver()->getFPS(); //获取当前帧率
	gui::IGUIFont* m_pGuiFont = m_pDevice->getGUIEnvironment()->getFont("./data/bigfont.png");		//加载字母数字字体图片
	core::stringw fpsstr;
	fpsstr +=L"fps:";
	fpsstr += fps;  //包装字符串
	m_pGuiFont->draw(fpsstr, core::rect<s32>(0,0,300,60), video::SColor(255, 255, 0, 0));  //字符串绘制到屏幕区域
}

//场景事件处理方法
bool CLogicEventScene::OnEvent(const SEvent& in_event)
{
	scene::ISceneCollisionManager* pCollisionManager = m_pSmgr->getSceneCollisionManager();

	//如果事件类型是鼠标时间,而且鼠标左键按下
	if(in_event.EventType == tcl::EET_MOUSE_INPUT_EVENT && in_event.MouseInput.isLeftPressed())
	{
		//获取当前鼠标位置射线,并获取鼠标击中的当前场景物体
		core::line3df ray = pCollisionManager->getRayFromScreenCoordinates(core::vector2di(in_event.MouseInput.X,in_event.MouseInput.Y));
		m_MouseCollisionNode = m_pSmgr->getCollionNodeByTray(ray);
	}
	//如果不是鼠标时间,则击中物体为空。
	else if(in_event.EventType != tcl::EET_MOUSE_INPUT_EVENT)
	{
		ISceneNode* m_pCollionNode = NULL;
	}

	//如果是鼠标或者键盘事件,则需要处理,将事件下发给逻辑层处理。
	if ( EET_KEY_INPUT_EVENT == in_event.EventType || EET_MOUSE_INPUT_EVENT== in_event.EventType)
	{
		CLogicNodeManger::getSingletonPtr()->readyToUpdate(in_event);
		CLogicNodeManger::getSingletonPtr()->callUpdate();

	}
	return true;
}

//创建逻辑层的代码。
void CLogicEventScene::CreateLogicNode()
{
	//创建logic层管理器和树状结构
	CLogicNodeManger* pLogicNodeMgr = new CLogicNodeManger();
	CLogicTree * pLogicTree = pLogicNodeMgr->createLogicTree();

	//创建状态管理器,创建主页面逻辑处理类,创建全部应用页面逻辑处理类
	CStateMachineLogic* pStateLogic = pLogicTree->createNode<CStateMachineLogic>();
	//Home页面逻辑和AllApp页面逻辑是本demo的两个逻辑模块。
	//可以参照这两个节点类弄清楚如何把逻辑进行分类,保持独立处理。
	//在逻辑类内部如何把小逻辑也分块独立处理
	pLogicTree->createNode<CHomeLogic>();
	pLogicTree->createNode<CAllAppLogic>();

	//设置状态管理器优先级 默认0  50意思排到后面
	pStateLogic->setPriority(50);
	//设置状态管理器实例
	CBaseLogic::setStateMachineLogic(pStateLogic);
}

//这个宏是单例实现
CT_IMPLEMENT_SINGLETON(CLogicEventScene)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Babylon.js引擎中,您可以使用`scene.onPointerObservable`方法来注册事件处理程序。此方法允许您将事件处理程序分配给不同的优先级,以确保UI事件处理程序的优先级高于相机事件处理程序。 下面是一个示例代码,演示如何将UI事件处理程序的优先级设置为高于相机事件处理程序: ```javascript // 创建一个指向画布元素的引用 var canvas = document.getElementById("renderCanvas"); // 注册事件处理程序 scene.onPointerObservable.add(function (pointerInfo) { // 检查是否点击了UI元素 if (pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.pickedMesh.isGUI3DControl) { // 处理UI事件 console.log("Clicked on UI element: " + pointerInfo.pickInfo.pickedMesh.name); } else { // 处理相机事件 console.log("Moved camera with virtual joystick"); } }, BABYLON.PointerEventTypes.POINTERDOWN, true); ``` 在上面的示例中,我们使用了`scene.onPointerObservable`方法来注册事件处理程序,第一个参数是事件处理函数,第个参数是事件类型(在这个例子中,我们使用了`BABYLON.PointerEventTypes.POINTERDOWN`,表示鼠标点击事件)。第三个参数是一个布尔值,表示事件处理程序的优先级,如果设置为`true`,则表示该事件处理程序具有高优先级,将在其他事件处理程序之前被调用。在本示例中,我们将UI事件处理程序的优先级设置为高于相机事件处理程序,因此当您点击UI元素时,UI事件处理程序将首先被调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值