From d180c4dd7446b48a567284900aaa2e974b3821dd Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Mon, 16 Jul 2018 22:11:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8C=89=E9=94=AE=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E3=80=81=E9=BC=A0=E6=A0=87=E6=B6=88=E6=81=AF=E3=80=81?= =?UTF-8?q?=E7=A2=B0=E6=92=9E=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/GC.cpp | 1 - core/Base/Game.cpp | 6 - core/Base/Input.cpp | 12 +- core/Base/Window.cpp | 31 +++- core/Common/Collision.cpp | 34 ---- core/Common/Resource.cpp | 15 +- core/Common/Scene.cpp | 16 ++ core/Common/String.cpp | 2 +- core/Event/Collision.cpp | 27 ++++ core/Event/KeyEvent.cpp | 85 ++++++++++ core/Event/MouseEvent.cpp | 46 ++++++ core/Manager/CollisionManager.cpp | 147 +----------------- core/Manager/InputManager.cpp | 162 ------------------- core/Manager/SceneManager.cpp | 22 +++ core/Node/Button.cpp | 6 +- core/Node/Node.cpp | 87 ++++++++++- core/Tool/Listener.cpp | 57 ------- core/e2dbase.h | 79 +--------- core/e2dcommon.h | 216 +++++++++++++++++++++++--- core/e2dmanager.h | 139 ++--------------- core/e2dnode.h | 28 +++- core/e2dtool.h | 53 ------- project/vs2012/Easy2D.vcxproj | 1 - project/vs2012/Easy2D.vcxproj.filters | 3 - project/vs2013/Easy2D.vcxproj | 1 - project/vs2013/Easy2D.vcxproj.filters | 3 - project/vs2017/Easy2D.vcxproj | 6 +- project/vs2017/Easy2D.vcxproj.filters | 17 +- 28 files changed, 573 insertions(+), 729 deletions(-) delete mode 100644 core/Common/Collision.cpp create mode 100644 core/Event/Collision.cpp create mode 100644 core/Event/KeyEvent.cpp create mode 100644 core/Event/MouseEvent.cpp delete mode 100644 core/Manager/InputManager.cpp delete mode 100644 core/Tool/Listener.cpp diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index 00cb7505..d459e3b5 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -58,7 +58,6 @@ e2d::GC::~GC() Player::destroyInstance(); SceneManager::destroyInstance(); ActionManager::destroyInstance(); - InputManager::destroyInstance(); CollisionManager::destroyInstance(); } diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index bcec101c..8fd4443b 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -44,7 +44,6 @@ void e2d::Game::start(bool cleanup) auto timer = Timer::getInstance(); auto sceneManager = SceneManager::getInstance(); auto actionManager = ActionManager::getInstance(); - auto inputManager = InputManager::getInstance(); // 显示窗口 ::ShowWindow(window->getHWnd(), SW_SHOWNORMAL); @@ -75,7 +74,6 @@ void e2d::Game::start(bool cleanup) input->update(); // 获取用户输入 timer->update(); // 更新定时器 actionManager->update(); // 更新动作管理器 - inputManager->update(); // 更新输入监听器 sceneManager->update(); // 更新场景内容 renderer->render(); // 渲染游戏画面 GC::flush(); // 刷新内存池 @@ -146,10 +144,6 @@ void e2d::Game::cleanup() Timer::getInstance()->clearAllTasks(); // 清除所有动作 ActionManager::getInstance()->clearAll(); - // 删除碰撞监听器 - CollisionManager::getInstance()->clearAllListeners(); - // 删除输入监听器 - InputManager::getInstance()->clearAllListeners(); // 清空图片缓存 Image::clearCache(); // 清空音乐缓存 diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index 435c9482..62e1f0f7 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -151,14 +151,14 @@ void e2d::Input::update() ScreenToClient(Window::getInstance()->getHWnd(), &_mousePos); } -bool e2d::Input::isDown(Key key) +bool e2d::Input::isDown(KeyCode key) { if (s_KeyBuffer[static_cast(key)] & 0x80) return true; return false; } -bool e2d::Input::isPress(Key key) +bool e2d::Input::isPress(KeyCode key) { if ((s_KeyBuffer[static_cast(key)] & 0x80) && !(s_KeyRecordBuffer[static_cast(key)] & 0x80)) @@ -166,7 +166,7 @@ bool e2d::Input::isPress(Key key) return false; } -bool e2d::Input::isRelease(Key key) +bool e2d::Input::isRelease(KeyCode key) { if (!(s_KeyBuffer[static_cast(key)] & 0x80) && (s_KeyRecordBuffer[static_cast(key)] & 0x80)) @@ -174,14 +174,14 @@ bool e2d::Input::isRelease(Key key) return false; } -bool e2d::Input::isDown(Mouse code) +bool e2d::Input::isDown(MouseCode code) { if (_mouseState.rgbButtons[static_cast(code)] & 0x80) return true; return false; } -bool e2d::Input::isPress(Mouse code) +bool e2d::Input::isPress(MouseCode code) { if ((_mouseState.rgbButtons[static_cast(code)] & 0x80) && !(_mouseStateRecord.rgbButtons[static_cast(code)] & 0x80)) @@ -189,7 +189,7 @@ bool e2d::Input::isPress(Mouse code) return false; } -bool e2d::Input::isRelease(Mouse code) +bool e2d::Input::isRelease(MouseCode code) { if (!(_mouseState.rgbButtons[static_cast(code)] & 0x80) && (_mouseStateRecord.rgbButtons[static_cast(code)] & 0x80)) diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 45912dca..ce4f7a9d 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -90,7 +90,7 @@ HWND e2d::Window::__create() WNDCLASSEX wcex = { 0 }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.lpszClassName = L"Easy2DApp"; - wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wcex.lpfnWndProc = Window::WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = sizeof(LONG_PTR); @@ -385,6 +385,35 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar switch (message) { + // 处理鼠标消息 + case WM_LBUTTONUP: + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + { + SceneManager::getInstance()->dispatch(MouseEvent(message, wParam, lParam)); + } + result = 0; + hasHandled = true; + break; + + // 处理按键消息 + case WM_KEYDOWN: + case WM_KEYUP: + { + SceneManager::getInstance()->dispatch(KeyEvent(message, wParam, lParam)); + } + result = 0; + hasHandled = true; + break; + // 处理窗口大小变化消息 case WM_SIZE: { diff --git a/core/Common/Collision.cpp b/core/Common/Collision.cpp deleted file mode 100644 index 10030fe2..00000000 --- a/core/Common/Collision.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "..\e2dcommon.h" - -e2d::Collision::Collision() - : _active(nullptr) - , _passive(nullptr) - , _relation(Collider::Relation::Unknown) -{ -} - -e2d::Collision::Collision(Node* active, Node* passive, Collider::Relation relation) - : _active(active) - , _passive(passive) - , _relation(relation) -{ -} - -e2d::Collision::~Collision() -{ -} - -e2d::Node * e2d::Collision::getActive() const -{ - return _active; -} - -e2d::Node * e2d::Collision::getPassive() const -{ - return _passive; -} - -e2d::Collider::Relation e2d::Collision::getRelation() const -{ - return _relation; -} diff --git a/core/Common/Resource.cpp b/core/Common/Resource.cpp index 225fc0eb..343c01a7 100644 --- a/core/Common/Resource.cpp +++ b/core/Common/Resource.cpp @@ -8,7 +8,7 @@ e2d::Resource::Resource(const String & fileName) { } -e2d::Resource::Resource(int resNameId, const String & resType) +e2d::Resource::Resource(size_t resNameId, const String & resType) : _isResource(true) , _fileName() , _resNameId(resNameId) @@ -26,7 +26,7 @@ const e2d::String & e2d::Resource::getFileName() const return _fileName; } -int e2d::Resource::getResNameId() const +size_t e2d::Resource::getResNameId() const { return _resNameId; } @@ -36,16 +36,9 @@ const e2d::String & e2d::Resource::getResType() const return _resType; } -int e2d::Resource::getKey() const +size_t e2d::Resource::getKey() const { - if (_isResource) - { - return _resNameId; - } - else - { - return _fileName.getHashCode(); - } + return _isResource ? _resNameId : _fileName.getHashCode(); } bool e2d::Resource::operator>(const Resource &res) const diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index 1229c6fe..865986ce 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -44,6 +44,22 @@ void e2d::Scene::update() _root->_update(); } +void e2d::Scene::dispatch(const MouseEvent & e) +{ + if (this->onMouseEvent(e)) + { + _root->dispatch(e); + } +} + +void e2d::Scene::dispatch(const KeyEvent & e) +{ + if (this->onKeyEvent(e)) + { + _root->dispatch(e); + } +} + void e2d::Scene::setAutoUpdate(bool bAutoUpdate) { _autoUpdate = bAutoUpdate; diff --git a/core/Common/String.cpp b/core/Common/String.cpp index a9c8ebed..65a39ae6 100644 --- a/core/Common/String.cpp +++ b/core/Common/String.cpp @@ -357,7 +357,7 @@ int e2d::String::getLength() const return static_cast(_str.size()); } -unsigned int e2d::String::getHashCode() const +size_t e2d::String::getHashCode() const { std::hash hash; return hash(_str); diff --git a/core/Event/Collision.cpp b/core/Event/Collision.cpp new file mode 100644 index 00000000..26833cc1 --- /dev/null +++ b/core/Event/Collision.cpp @@ -0,0 +1,27 @@ +#include "..\e2dcommon.h" + +e2d::Collision::Collision() + : _node(nullptr) + , _relation(Collider::Relation::Unknown) +{ +} + +e2d::Collision::Collision(Node* node, Collider::Relation relation) + : _node(node) + , _relation(relation) +{ +} + +e2d::Collision::~Collision() +{ +} + +e2d::Node * e2d::Collision::getNode() const +{ + return _node; +} + +e2d::Collider::Relation e2d::Collision::getRelation() const +{ + return _relation; +} diff --git a/core/Event/KeyEvent.cpp b/core/Event/KeyEvent.cpp new file mode 100644 index 00000000..7ab30a63 --- /dev/null +++ b/core/Event/KeyEvent.cpp @@ -0,0 +1,85 @@ +#include "..\e2dcommon.h" + + +e2d::KeyEvent::KeyEvent(UINT message, WPARAM wParam, LPARAM lParam) + : _code(KeyCode(wParam)) + , _type(Type(message)) + , _count(static_cast((DWORD)lParam & 0x0000FFFF)) +{ +} + +e2d::KeyCode e2d::KeyEvent::getCode() const +{ + return _code; +} + +int e2d::KeyEvent::getCount() const +{ + return _count; +} + +e2d::KeyEvent::Type e2d::KeyEvent::getType() const +{ + return _type; +} + +e2d::KeyCode e2d::KeyEvent::convertKeyCode(WPARAM wParam) +{ + switch (wParam) + { + case 'A': return KeyCode::A; + case 'B': return KeyCode::B; + case 'C': return KeyCode::C; + case 'D': return KeyCode::D; + case 'E': return KeyCode::E; + case 'F': return KeyCode::F; + case 'G': return KeyCode::G; + case 'H': return KeyCode::H; + case 'I': return KeyCode::I; + case 'J': return KeyCode::J; + case 'K': return KeyCode::K; + case 'L': return KeyCode::L; + case 'M': return KeyCode::M; + case 'N': return KeyCode::N; + case 'O': return KeyCode::O; + case 'P': return KeyCode::P; + case 'Q': return KeyCode::Q; + case 'R': return KeyCode::R; + case 'S': return KeyCode::S; + case 'T': return KeyCode::T; + case 'U': return KeyCode::U; + case 'V': return KeyCode::V; + case 'W': return KeyCode::W; + case 'X': return KeyCode::X; + case 'Y': return KeyCode::Y; + case 'Z': return KeyCode::Z; + case '0': return KeyCode::Num0; + case '1': return KeyCode::Num1; + case '2': return KeyCode::Num2; + case '3': return KeyCode::Num3; + case '4': return KeyCode::Num4; + case '5': return KeyCode::Num5; + case '6': return KeyCode::Num6; + case '7': return KeyCode::Num7; + case '8': return KeyCode::Num8; + case '9': return KeyCode::Num9; + case VK_NUMPAD0: return KeyCode::Numpad0; + case VK_NUMPAD1: return KeyCode::Numpad1; + case VK_NUMPAD2: return KeyCode::Numpad2; + case VK_NUMPAD3: return KeyCode::Numpad3; + case VK_NUMPAD4: return KeyCode::Numpad4; + case VK_NUMPAD5: return KeyCode::Numpad5; + case VK_NUMPAD6: return KeyCode::Numpad6; + case VK_NUMPAD7: return KeyCode::Numpad7; + case VK_NUMPAD8: return KeyCode::Numpad8; + case VK_NUMPAD9: return KeyCode::Numpad9; + case VK_UP: return KeyCode::Up; + case VK_DOWN: return KeyCode::Down; + case VK_LEFT: return KeyCode::Left; + case VK_RIGHT: return KeyCode::Right; + case VK_RETURN: return KeyCode::Enter; + case VK_SPACE: return KeyCode::Space; + case VK_ESCAPE: return KeyCode::Esc; + default: return KeyCode::Unknown; + } +} diff --git a/core/Event/MouseEvent.cpp b/core/Event/MouseEvent.cpp new file mode 100644 index 00000000..0673ae99 --- /dev/null +++ b/core/Event/MouseEvent.cpp @@ -0,0 +1,46 @@ +#include "..\e2dcommon.h" + + +e2d::MouseEvent::MouseEvent(UINT message, WPARAM wParam, LPARAM lParam) + : _pos(LOWORD(lParam), HIWORD(lParam)) + , _shiftDown(GET_KEYSTATE_WPARAM(wParam) == MK_SHIFT) + , _ctrlDown(GET_KEYSTATE_WPARAM(wParam) == MK_CONTROL) + , _wheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)) + , _type(Type(message)) +{ +} + +double e2d::MouseEvent::getX() const +{ + return _pos.x; +} + +double e2d::MouseEvent::getY() const +{ + return _pos.y; +} + +e2d::Point e2d::MouseEvent::getPos() const +{ + return _pos; +} + +bool e2d::MouseEvent::isShiftDown() const +{ + return _shiftDown; +} + +bool e2d::MouseEvent::isCtrlDown() const +{ + return _ctrlDown; +} + +double e2d::MouseEvent::getWheelDelta() const +{ + return _wheelDelta; +} + +e2d::MouseEvent::Type e2d::MouseEvent::getType() const +{ + return _type; +} diff --git a/core/Manager/CollisionManager.cpp b/core/Manager/CollisionManager.cpp index c6370276..e3c71fc7 100644 --- a/core/Manager/CollisionManager.cpp +++ b/core/Manager/CollisionManager.cpp @@ -70,13 +70,11 @@ void e2d::CollisionManager::__updateCollider(Collider* collider) if (relation != Collider::Relation::Unknown && relation != Collider::Relation::Disjoin) { - _collision = Collision(active, passive, relation); - active->onCollision(_collision); - // 更新碰撞监听器 - CollisionManager::__updateListeners(); + Collision collision(passive, relation); + SceneManager::getInstance()->getCurrentScene()->onCollision(collision); + active->onCollision(collision); } } - _collision = Collision(); } void e2d::CollisionManager::addName(const String & name1, const String & name2) @@ -105,7 +103,7 @@ bool e2d::CollisionManager::isCollidable(Node * node1, Node * node2) bool e2d::CollisionManager::isCollidable(const String & name1, const String & name2) { - UINT hashName1 = name1.getHashCode(), + size_t hashName1 = name1.getHashCode(), hashName2 = name2.getHashCode(); auto pair1 = std::make_pair(hashName1, hashName2), pair2 = std::make_pair(hashName2, hashName1); @@ -118,140 +116,3 @@ bool e2d::CollisionManager::isCollidable(const String & name1, const String & na } return false; } - -e2d::Collision e2d::CollisionManager::getCollision() const -{ - return _collision; -} - -void e2d::CollisionManager::__updateListeners() -{ - if (_listeners.empty() || Game::getInstance()->isPaused()) - return; - - for (size_t i = 0; i < _listeners.size(); ++i) - { - auto listener = _listeners[i]; - // 清除已停止的监听器 - if (listener->_stopped) - { - GC::safeRelease(listener); - _listeners.erase(_listeners.begin() + i); - } - else - { - // 更新监听器 - listener->_update(); - ++i; - } - } -} - -e2d::Listener * e2d::CollisionManager::addListener(const Function& func, const String& name, bool paused) -{ - auto listener = new (e2d::autorelease) Listener(func, name, paused); - GC::retain(listener); - _listeners.push_back(listener); - return listener; -} - -void e2d::CollisionManager::addListener(Listener * listener) -{ - if (listener) - { - auto iter = std::find(_listeners.begin(), _listeners.end(), listener); - if (iter == _listeners.end()) - { - GC::retain(listener); - _listeners.push_back(listener); - } - } -} - -void e2d::CollisionManager::removeListener(Listener * listener) -{ - if (listener) - { - auto iter = std::find(_listeners.begin(), _listeners.end(), listener); - if (iter != _listeners.end()) - { - GC::safeRelease(listener); - _listeners.erase(iter); - } - } -} - -void e2d::CollisionManager::stopListener(const String& name) -{ - if (_listeners.empty() || name.isEmpty()) - return; - - for (auto listener : _listeners) - { - if (listener->_name == name) - { - listener->stop(); - } - } -} - -void e2d::CollisionManager::startListener(const String& name) -{ - if (_listeners.empty() || name.isEmpty()) - return; - - for (auto listener : _listeners) - { - if (listener->_name == name) - { - listener->start(); - } - } -} - -void e2d::CollisionManager::removeListener(const String& name) -{ - if (_listeners.empty() || name.isEmpty()) - return; - - for (auto listener : _listeners) - { - if (listener->_name == name) - { - listener->_stopped = true; - } - } -} - -void e2d::CollisionManager::stopAllListeners() -{ - for (auto listener : _listeners) - { - listener->stop(); - } -} - -void e2d::CollisionManager::startAllListeners() -{ - for (auto listener : _listeners) - { - listener->start(); - } -} - -void e2d::CollisionManager::removeAllListeners() -{ - for (auto listener : _listeners) - { - listener->_stopped = true; - } -} - -void e2d::CollisionManager::clearAllListeners() -{ - for (auto listener : _listeners) - { - GC::release(listener); - } - _listeners.clear(); -} diff --git a/core/Manager/InputManager.cpp b/core/Manager/InputManager.cpp deleted file mode 100644 index 496fa77b..00000000 --- a/core/Manager/InputManager.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "..\e2dbase.h" -#include "..\e2dmanager.h" -#include "..\e2dtool.h" - - -e2d::InputManager * e2d::InputManager::_instance = nullptr; - -e2d::InputManager * e2d::InputManager::getInstance() -{ - if (!_instance) - _instance = new (std::nothrow) InputManager; - return _instance; -} - -void e2d::InputManager::destroyInstance() -{ - if (_instance) - { - delete _instance; - _instance = nullptr; - } -} - -e2d::InputManager::InputManager() -{ -} - -e2d::InputManager::~InputManager() -{ -} - -e2d::Listener * e2d::InputManager::addListener(const Function& func, const String& name, bool paused) -{ - auto listener = new (e2d::autorelease) Listener(func, name, paused); - GC::retain(listener); - _listeners.push_back(listener); - return listener; -} - -void e2d::InputManager::addListener(Listener * listener) -{ - if (listener) - { - auto iter = std::find(_listeners.begin(), _listeners.end(), listener); - if (iter == _listeners.end()) - { - GC::retain(listener); - _listeners.push_back(listener); - } - } -} - -void e2d::InputManager::removeListener(Listener * listener) -{ - if (listener) - { - auto iter = std::find(_listeners.begin(), _listeners.end(), listener); - if (iter != _listeners.end()) - { - GC::safeRelease(listener); - _listeners.erase(iter); - } - } -} - -void e2d::InputManager::stopListener(const String& name) -{ - if (_listeners.empty() || name.isEmpty()) - return; - - for (auto listener : _listeners) - { - if (listener->_name == name) - { - listener->stop(); - } - } -} - -void e2d::InputManager::startListener(const String& name) -{ - if (_listeners.empty() || name.isEmpty()) - return; - - for (auto listener : _listeners) - { - if (listener->_name == name) - { - listener->start(); - } - } -} - -void e2d::InputManager::removeListener(const String& name) -{ - if (_listeners.empty() || name.isEmpty()) - return; - - for (auto listener : _listeners) - { - if (listener->_name == name) - { - listener->_stopped = true; - } - } -} - -void e2d::InputManager::stopAllListeners() -{ - for (auto listener : _listeners) - { - listener->stop(); - } -} - -void e2d::InputManager::startAllListeners() -{ - for (auto listener : _listeners) - { - listener->start(); - } -} - -void e2d::InputManager::removeAllListeners() -{ - for (auto listener : _listeners) - { - listener->_stopped = true; - } -} - -void e2d::InputManager::clearAllListeners() -{ - for (auto listener : _listeners) - { - GC::release(listener); - } - _listeners.clear(); -} - -void e2d::InputManager::update() -{ - if (_listeners.empty() || Game::getInstance()->isPaused()) - return; - - for (size_t i = 0; i < _listeners.size(); ++i) - { - auto listener = _listeners[i]; - // 清除已停止的监听器 - if (listener->_stopped) - { - GC::safeRelease(listener); - _listeners.erase(_listeners.begin() + i); - } - else - { - // 更新监听器 - listener->_update(); - ++i; - } - } -} diff --git a/core/Manager/SceneManager.cpp b/core/Manager/SceneManager.cpp index 707fc274..b553f846 100644 --- a/core/Manager/SceneManager.cpp +++ b/core/Manager/SceneManager.cpp @@ -183,3 +183,25 @@ void e2d::SceneManager::render() } } } + +void e2d::SceneManager::dispatch(const MouseEvent & e) +{ + if (_transition != nullptr) + return; + + if (_currScene) + { + _currScene->dispatch(e); + } +} + +void e2d::SceneManager::dispatch(const KeyEvent & e) +{ + if (_transition != nullptr) + return; + + if (_currScene) + { + _currScene->dispatch(e); + } +} diff --git a/core/Node/Button.cpp b/core/Node/Button.cpp index 12db44f0..71b5cc2c 100644 --- a/core/Node/Button.cpp +++ b/core/Node/Button.cpp @@ -185,7 +185,7 @@ void e2d::Button::_fixedUpdate() if (_enabled && _visible && _normal) { - if (input->isRelease(Input::Mouse::Left)) + if (input->isRelease(MouseCode::Left)) { // 鼠标左键抬起时,判断鼠标坐标是否在按钮内部 if (_isSelected && @@ -197,7 +197,7 @@ void e2d::Button::_fixedUpdate() _isSelected = false; } - if (input->isPress(Input::Mouse::Left)) + if (input->isPress(MouseCode::Left)) { if (_normal->containsPoint(input->getMousePos())) { @@ -207,7 +207,7 @@ void e2d::Button::_fixedUpdate() } } - if (_isSelected && input->isDown(Input::Mouse::Left)) + if (_isSelected && input->isDown(MouseCode::Left)) { if (_normal->containsPoint(input->getMousePos())) { diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 56b8aa9b..60519c01 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -94,9 +94,6 @@ void e2d::Node::_update() } else { - // 子节点排序 - _sortChildren(); - // 遍历子节点 size_t i; for (i = 0; i < _children.size(); ++i) @@ -286,6 +283,82 @@ void e2d::Node::updateTransform() } } +bool e2d::Node::dispatch(const MouseEvent & e) +{ + if (_children.empty()) + { + return onMouseEvent(e); + } + else + { + size_t i; + for (i = 0; i < _children.size(); ++i) + { + auto child = _children[i]; + if (child->getOrder() < 0) + { + if (!child->dispatch(e)) + { + return false; + } + } + else + { + break; + } + } + + if (!onMouseEvent(e)) + { + return false; + } + + for (; i < _children.size(); ++i) + if (!_children[i]->dispatch(e)) + return false; + + return true; + } +} + +bool e2d::Node::dispatch(const KeyEvent & e) +{ + if (_children.empty()) + { + return onKeyEvent(e); + } + else + { + size_t i; + for (i = 0; i < _children.size(); ++i) + { + auto child = _children[i]; + if (child->getOrder() < 0) + { + if (!child->dispatch(e)) + { + return false; + } + } + else + { + break; + } + } + + if (!onKeyEvent(e)) + { + return false; + } + + for (; i < _children.size(); ++i) + if (!_children[i]->dispatch(e)) + return false; + + return true; + } +} + void e2d::Node::_sortChildren() { if (_needSort) @@ -322,7 +395,7 @@ e2d::String e2d::Node::getName() const return _name; } -unsigned int e2d::Node::getHashName() const +size_t e2d::Node::getHashName() const { return _hashName; } @@ -680,7 +753,7 @@ e2d::Scene * e2d::Node::getParentScene() const std::vector e2d::Node::getChildren(const String& name) const { std::vector vChildren; - unsigned int hash = name.getHashCode(); + size_t hash = name.getHashCode(); for (auto child : _children) { @@ -695,7 +768,7 @@ std::vector e2d::Node::getChildren(const String& name) const e2d::Node * e2d::Node::getChild(const String& name) const { - unsigned int hash = name.getHashCode(); + size_t hash = name.getHashCode(); for (auto child : _children) { @@ -765,7 +838,7 @@ void e2d::Node::removeChildren(const String& childName) } // 计算名称 Hash 值 - unsigned int hash = childName.getHashCode(); + size_t hash = childName.getHashCode(); size_t size = _children.size(); for (size_t i = 0; i < size; ++i) diff --git a/core/Tool/Listener.cpp b/core/Tool/Listener.cpp deleted file mode 100644 index fc1bfb99..00000000 --- a/core/Tool/Listener.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "..\e2dcommon.h" -#include "..\e2dtool.h" - - -e2d::Listener::Listener() - : _name() - , _callback() - , _running(true) - , _stopped(false) -{ -} - -e2d::Listener::Listener(const Function & func, const String & name, bool paused) - : _name(name) - , _callback(func) - , _running(!paused) - , _stopped(false) -{ -} - -void e2d::Listener::_update() -{ - if (_callback) - { - _callback(); - } -} - -bool e2d::Listener::isRunning() const -{ - return _running; -} - -e2d::String e2d::Listener::getName() const -{ - return _name; -} - -void e2d::Listener::setName(const String & name) -{ - _name = name; -} - -void e2d::Listener::setFunc(const Function & func) -{ - _callback = func; -} - -void e2d::Listener::start() -{ - _running = true; -} - -void e2d::Listener::stop() -{ - _running = false; -} diff --git a/core/e2dbase.h b/core/e2dbase.h index 9d744466..9e91fca2 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -229,73 +229,6 @@ private: // 输入设备 class Input { -public: - // 鼠标键值 - enum class Mouse : int - { - Left, /* 鼠标左键 */ - Right, /* 鼠标右键 */ - Middle /* 鼠标中键 */ - }; - - // 键盘键值 - enum class Key : int - { - Up = 0xC8, - Left = 0xCB, - Right = 0xCD, - Down = 0xD0, - Enter = 0x1C, - Space = 0x39, - Esc = 0x01, - Q = 0x10, - W = 0x11, - E = 0x12, - R = 0x13, - T = 0x14, - Y = 0x15, - U = 0x16, - I = 0x17, - O = 0x18, - P = 0x19, - A = 0x1E, - S = 0x1F, - D = 0x20, - F = 0x21, - G = 0x22, - H = 0x23, - J = 0x24, - K = 0x25, - L = 0x26, - Z = 0x2C, - X = 0x2D, - C = 0x2E, - V = 0x2F, - B = 0x30, - N = 0x31, - M = 0x32, - Num1 = 0x02, - Num2 = 0x03, - Num3 = 0x04, - Num4 = 0x05, - Num5 = 0x06, - Num6 = 0x07, - Num7 = 0x08, - Num8 = 0x09, - Num9 = 0x0A, - Num0 = 0x0B, - Numpad7 = 0x47, - Numpad8 = 0x48, - Numpad9 = 0x49, - Numpad4 = 0x4B, - Numpad5 = 0x4C, - Numpad6 = 0x4D, - Numpad1 = 0x4F, - Numpad2 = 0x50, - Numpad3 = 0x51, - Numpad0 = 0x52 - }; - public: // 获取输入设备实例 static Input * getInstance(); @@ -305,32 +238,32 @@ public: // 检测键盘某按键是否正被按下 bool isDown( - Key key + KeyCode key ); // 检测键盘某按键是否被点击 bool isPress( - Key key + KeyCode key ); // 检测键盘某按键是否正在松开 bool isRelease( - Key key + KeyCode key ); // 检测鼠标按键是否正被按下 bool isDown( - Mouse code + MouseCode code ); // 检测鼠标按键是否被点击 bool isPress( - Mouse code + MouseCode code ); // 检测鼠标按键是否正在松开 bool isRelease( - Mouse code + MouseCode code ); // 获得鼠标X轴坐标值 diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 0d69142b..6b1d61ac 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -142,7 +142,7 @@ public: int getLength() const; // 获取该字符串的散列值 - unsigned int getHashCode() const; + size_t getHashCode() const; // 获取 Unicode 字符串 std::wstring getWString() const; @@ -440,6 +440,167 @@ public: }; +// 鼠标键值 +enum class MouseCode : int +{ + Left, /* 鼠标左键 */ + Right, /* 鼠标右键 */ + Middle /* 鼠标中键 */ +}; + + +// 键盘键值 +enum class KeyCode : int +{ + Unknown = 0, + Up = 0xC8, + Left = 0xCB, + Right = 0xCD, + Down = 0xD0, + Enter = 0x1C, + Space = 0x39, + Esc = 0x01, + Q = 0x10, + W = 0x11, + E = 0x12, + R = 0x13, + T = 0x14, + Y = 0x15, + U = 0x16, + I = 0x17, + O = 0x18, + P = 0x19, + A = 0x1E, + S = 0x1F, + D = 0x20, + F = 0x21, + G = 0x22, + H = 0x23, + J = 0x24, + K = 0x25, + L = 0x26, + Z = 0x2C, + X = 0x2D, + C = 0x2E, + V = 0x2F, + B = 0x30, + N = 0x31, + M = 0x32, + Num1 = 0x02, + Num2 = 0x03, + Num3 = 0x04, + Num4 = 0x05, + Num5 = 0x06, + Num6 = 0x07, + Num7 = 0x08, + Num8 = 0x09, + Num9 = 0x0A, + Num0 = 0x0B, + Numpad7 = 0x47, + Numpad8 = 0x48, + Numpad9 = 0x49, + Numpad4 = 0x4B, + Numpad5 = 0x4C, + Numpad6 = 0x4D, + Numpad1 = 0x4F, + Numpad2 = 0x50, + Numpad3 = 0x51, + Numpad0 = 0x52, +}; + + +// 按键消息 +class KeyEvent +{ +public: + // 按键消息类型 + enum class Type : int + { + Down = 0x0100, // 按下 + Up // 抬起 + }; + +public: + explicit KeyEvent( + UINT message, + WPARAM wParam, + LPARAM lParam + ); + + // 获取按键键值 + KeyCode getCode() const; + + // 获取按键次数 + int getCount() const; + + // 获取事件类型 + KeyEvent::Type getType() const; + + // VK 键值转换 + static KeyCode convertKeyCode( + WPARAM wParam + ); + +protected: + int _count; + KeyCode _code; + KeyEvent::Type _type; +}; + + +// 鼠标消息 +class MouseEvent +{ +public: + // 鼠标消息类型 + enum class Type : int + { + Move = 0x0200, // 鼠标移动 + LeftDown, // 鼠标左键按下 + LeftUp, // 鼠标左键抬起 + LeftDoubleClick, // 鼠标左键双击 + RightDown, // 鼠标右键按下 + RightUp, // 鼠标右键抬起 + RightDoubleClick, // 鼠标右键双击 + MiddleDown, // 鼠标中键按下 + MiddleUp, // 鼠标中键抬起 + MiddleDoubleClick, // 鼠标中键双击 + Wheel // 滑动滚轮 + }; + +public: + explicit MouseEvent( + UINT message, + WPARAM wParam, + LPARAM lParam + ); + + double getX() const; + + double getY() const; + + Point getPos() const; + + // 获取事件类型 + MouseEvent::Type getType() const; + + double getWheelDelta() const; + + // Shift 键是否按下 + bool isShiftDown() const; + + // Ctrl 键是否按下 + bool isCtrlDown() const; + +protected: + bool _shiftDown; + bool _ctrlDown; + double _wheelDelta; + Point _pos; + MouseEvent::Type _type; +}; + + class Node; // 碰撞体 @@ -466,7 +627,7 @@ public: }; public: - Collider( + explicit Collider( Node * parent ); @@ -549,26 +710,21 @@ class Collision public: Collision(); - Collision( - Node* active, - Node* passive, + explicit Collision( + Node* node, Collider::Relation relation ); ~Collision(); - // 获取发生碰撞的主动方 - Node* getActive() const; - - // 获取发生碰撞的被动方 - Node* getPassive() const; + // 获取发生碰撞节点 + Node* getNode() const; // 获取交集关系 Collider::Relation getRelation() const; protected: - Node * _active; - Node* _passive; + Node* _node; Collider::Relation _relation; }; @@ -582,7 +738,7 @@ public: ); Resource( - int resNameId, /* 资源名称 */ + size_t resNameId, /* 资源名称 */ const String& resType /* 资源类型 */ ); @@ -591,11 +747,11 @@ public: const String& getFileName() const; - int getResNameId() const; + size_t getResNameId() const; const String& getResType() const; - int getKey() const; + size_t getKey() const; // 比较运算符 bool operator> (const Resource &) const; @@ -605,7 +761,7 @@ public: protected: bool _isResource; - int _resNameId; + size_t _resNameId; String _resType; String _fileName; }; @@ -741,13 +897,25 @@ public: virtual ~Scene(); - // 重写这个函数,它将在进入这个场景时自动执行 + // 进入场景 virtual void onEnter() {} - // 重写这个函数,它将在离开这个场景时自动执行 + // 退出场景 virtual void onExit() {} - // 重写这个函数,它将在关闭窗口时执行(返回 false 将阻止窗口关闭) + // 按键消息 + // 说明:返回 false 将阻止消息继续传递 + virtual bool onKeyEvent(KeyEvent e) { return true; } + + // 鼠标消息 + // 说明:返回 false 将阻止消息继续传递 + virtual bool onMouseEvent(MouseEvent e) { return true; } + + // 碰撞消息 + virtual void onCollision(Collision collision) { } + + // 关闭窗口 + // 说明:返回 false 将阻止窗口关闭 virtual bool onCloseWindow() { return true; } // 重写这个函数,它将在每一帧画面刷新时执行 @@ -797,6 +965,16 @@ public: // 更新场景内容 void update(); + // 分发鼠标消息 + void dispatch( + const MouseEvent& e + ); + + // 分发按键消息 + void dispatch( + const KeyEvent& e + ); + protected: E2D_DISABLE_COPY(Scene); diff --git a/core/e2dmanager.h b/core/e2dmanager.h index 73c5a69d..e9f00d8d 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -52,6 +52,16 @@ public: // 渲染场景画面 void render(); + // 分发鼠标消息 + void dispatch( + const MouseEvent& e + ); + + // 分发按键消息 + void dispatch( + const KeyEvent& e + ); + private: SceneManager(); @@ -166,81 +176,6 @@ private: }; -class Listener; - -// 用户输入管理器 -class InputManager -{ - friend class Node; - -public: - // 获取碰撞体管理器实例 - static InputManager * getInstance(); - - // 销毁实例 - static void destroyInstance(); - - // 添加输入监听 - Listener * addListener( - const Function& func, /* 监听到用户输入时的执行函数 */ - const String& name = L"", /* 监听器名称 */ - bool paused = false /* 是否暂停 */ - ); - - // 添加碰撞监听 - void addListener( - Listener * listener /* 监听器 */ - ); - - // 移除监听器 - void removeListener( - Listener * listener /* 监听器 */ - ); - - // 启动输入监听 - void startListener( - const String& name - ); - - // 停止输入监听 - void stopListener( - const String& name - ); - - // 移除输入监听 - void removeListener( - const String& name - ); - - // 启动所有监听器 - void startAllListeners(); - - // 停止所有监听器 - void stopAllListeners(); - - // 移除所有监听器 - void removeAllListeners(); - - // 强制清空所有监听器 - void clearAllListeners(); - - // 更新监听器 - void update(); - -private: - InputManager(); - - ~InputManager(); - - E2D_DISABLE_COPY(InputManager); - -private: - std::vector _listeners; - - static InputManager * _instance; -}; - - // 碰撞体管理器 class CollisionManager { @@ -277,53 +212,6 @@ public: const String& name2 ); - // 获取碰撞事件 - Collision getCollision() const; - - // 添加碰撞监听 - Listener * addListener( - const Function& func, /* 监听到碰撞时的执行函数 */ - const String& name = L"", /* 监听器名称 */ - bool paused = false /* 是否暂停 */ - ); - - // 添加碰撞监听 - void addListener( - Listener * listener /* 监听器 */ - ); - - // 移除监听器 - void removeListener( - Listener * listener /* 监听器 */ - ); - - // 启动碰撞监听 - void startListener( - const String& name - ); - - // 停止碰撞监听 - void stopListener( - const String& name - ); - - // 移除碰撞监听 - void removeListener( - const String& name - ); - - // 启动所有监听器 - void startAllListeners(); - - // 停止所有监听器 - void stopAllListeners(); - - // 移除所有监听器 - void removeAllListeners(); - - // 强制清除所有监听器 - void clearAllListeners(); - private: CollisionManager(); @@ -346,14 +234,9 @@ private: Collider* collider ); - // 更新监听器 - void __updateListeners(); - private: - Collision _collision; std::vector _colliders; - std::vector _listeners; - std::set> _collisionList; + std::set> _collisionList; static CollisionManager * _instance; }; diff --git a/core/e2dnode.h b/core/e2dnode.h index a75fee81..a883a895 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -50,10 +50,16 @@ public: // 渲染节点 virtual void onRender() {} - // 节点发生碰撞 - virtual void onCollision( - Collision other - ) {} + // 按键消息 + // 说明:返回 false 将阻止消息继续传递 + virtual bool onKeyEvent(KeyEvent e) { return true; } + + // 鼠标消息 + // 说明:返回 false 将阻止消息继续传递 + virtual bool onMouseEvent(MouseEvent e) { return true; } + + // 碰撞消息 + virtual void onCollision(Collision collision) { } // 获取节点显示状态 virtual bool isVisible() const; @@ -72,7 +78,7 @@ public: virtual String getName() const; // 获取节点名称的 Hash 值 - virtual unsigned int getHashName() const; + virtual size_t getHashName() const; // 获取节点绘图顺序 virtual int getOrder() const; @@ -388,6 +394,16 @@ public: // 更新转换矩阵 void updateTransform(); + // 分发鼠标消息 + bool dispatch( + const MouseEvent& e + ); + + // 分发按键消息 + bool dispatch( + const KeyEvent& e + ); + protected: E2D_DISABLE_COPY(Node); @@ -422,7 +438,7 @@ protected: protected: String _name; - unsigned _hashName; + size_t _hashName; float _posX; float _posY; float _width; diff --git a/core/e2dtool.h b/core/e2dtool.h index 4ba4a6ed..f5684cde 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -377,59 +377,6 @@ private: }; -class InputManager; -class CollisionManager; - -// 监听器 -class Listener : - public Ref -{ - friend class InputManager; - friend class CollisionManager; - -public: - Listener(); - - explicit Listener( - const Function& func, - const String& name, - bool paused - ); - - // 启动监听 - void start(); - - // 停止监听 - void stop(); - - // 获取监听器运行状态 - bool isRunning() const; - - // 获取名称 - String getName() const; - - // 设置名称 - void setName( - const String& name - ); - - // 设置监听回调函数 - void setFunc( - const Function& func - ); - -protected: - // 更新监听器状态 - virtual void _update(); - -protected: - bool _running; - bool _stopped; - String _name; - Function _callback; -}; - - // 数据管理工具 class Data { diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index 0303e5c2..6f8e2110 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -93,7 +93,6 @@ - diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index c20ee156..f91bf190 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -212,9 +212,6 @@ Tool - - Tool - Tool diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index e941eb34..a10727f2 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -237,7 +237,6 @@ - diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 3c2b8a39..daa42ee3 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -212,9 +212,6 @@ Tool - - Tool - Tool diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 5718ded1..0635fa13 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -222,7 +222,6 @@ - @@ -239,9 +238,11 @@ + + + - @@ -256,7 +257,6 @@ - diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 49728c3b..44d35575 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -28,6 +28,9 @@ {3475b59d-d50c-43b1-8334-bcb9e1703ed2} + + {6c9657de-02d5-4d3b-9e1d-bc921eb5aea3} + @@ -174,9 +177,6 @@ Custom - - Tool - Common @@ -240,11 +240,14 @@ Manager - - Manager + + Event - - Common + + Event + + + Event