您的位置:首页 > 产品设计 > UI/UE

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

2014-06-03 15:59 399 查看
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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: