Directx11学习笔记【二十一】 封装键盘鼠标响应类
摘要: 本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/p/5804565.html
由于我们练习的Demo一般都比较简单,对响应时间效率没有太高要求,因此键盘鼠标响应可以采用Win32的处理函数,而不必使用DirectInput,DirectInput在后面会专门再介绍。
为了方便使用,封装了一个Input类用于处理键盘鼠标消息,为了方便采用单例模式,代码很简单:
Input.h
1 #pragma once 2 #include <Windows.h> 3 4 class Input 5 { 6 public: 7 ~Input(); 8 9 public: 10 void Init(); 11 void Listen(UINT msg, float x, float y); // Listen to the user input 12 static Input* GetInstance() 13 { 14 static Input* instance = new Input(); 15 16 return instance; 17 } 18 19 public: 20 float GetMouseX() const; 21 float GetMouseY() const; 22 float GetLastMouseX() const; 23 float GetLastMouseY() const; 24 bool IsLMouseDown() const; 25 bool IsRMouseDown() const; 26 bool IsMouseUp() const; 27 bool IsMouseMove() const; 28 int IsKeyDown(int key) const; 29 30 private: 31 POINT m_lastMousePos; 32 POINT m_mousePos; 33 bool m_lMouseDown; 34 bool m_rMouseDown; 35 bool m_mouseUp; 36 bool m_mouseMove; 37 38 private: 39 Input(); 40 Input(const Input&); 41 void operator=(const Input&); 42 };
Input.cpp
1 #include "Input.h" 2 3 //****************** 4 //禁止构造复制 5 //****************** 6 Input::Input() {} 7 Input::Input(const Input&) {} 8 Input::~Input() {} 9 void Input::operator=(const Input&) {} 10 11 void Input::Init() 12 { 13 m_lastMousePos = { 0, 0 }; 14 m_mousePos = { 0, 0 }; 15 m_lMouseDown = false; 16 m_rMouseDown = false; 17 m_mouseUp = false; 18 m_mouseMove = false; 19 } 20 21 void Input::Listen(UINT msg, float x, float y) 22 { 23 m_lastMousePos.x = m_mousePos.x; 24 m_lastMousePos.y = m_mousePos.y; 25 26 m_mousePos.x = x; 27 m_mousePos.y = y; 28 29 switch (msg) 30 { 31 case WM_LBUTTONDOWN: 32 m_lMouseDown = true; 33 break; 34 case WM_RBUTTONDOWN: 35 m_rMouseDown = true; 36 break; 37 case WM_LBUTTONUP: 38 case WM_RBUTTONUP: 39 m_mouseUp = true; 40 m_lMouseDown = false; 41 m_rMouseDown = false; 42 break; 43 case WM_MOUSEMOVE: 44 m_mouseMove = true; 45 break; 46 default: 47 m_mouseMove = false; 48 break; 49 } 50 } 51 52 float Input::GetMouseX() const 53 { 54 return m_mousePos.x; 55 } 56 57 float Input::GetMouseY() const 58 { 59 return m_mousePos.y; 60 } 61 62 float Input::GetLastMouseX() const 63 { 64 return m_lastMousePos.x; 65 } 66 67 float Input::GetLastMouseY() const 68 { 69 return m_lastMousePos.y; 70 } 71 72 bool Input::IsLMouseDown() const 73 { 74 return m_lMouseDown; 75 } 76 77 bool Input::IsRMouseDown() const 78 { 79 return m_rMouseDown; 80 } 81 82 bool Input::IsMouseUp() const 83 { 84 return m_mouseUp; 85 } 86 87 bool Input::IsMouseMove() const 88 { 89 return m_mouseMove; 90 } 91 92 int Input::IsKeyDown(int vKey) const 93 { 94 return GetAsyncKeyState(vKey) & 0x8000; 95 }
使用的时候先在Dx11Base基类中初始化,并在消息处理函数WndProc中调用Listen函数:
bool SystemClass::init(HINSTANCE hInstance, int nCmdShow) { InputClass::getInstance()->init(); ... }
LRESULT CALLBACK Dx11Base::WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { Input::GetInstance()->Listen(uMsg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); ... }
以上个教程MeshDemo为例,Input类使用如下:
1 void MeshDemo::UpdateCamera(float dt) 2 { 3 //前后左右行走 4 if (Input::GetInstance()->IsKeyDown('A')) 5 { 6 m_camera.Strafe(-6.f*dt); 7 } 8 else if (Input::GetInstance()->IsKeyDown('D')) 9 { 10 m_camera.Strafe(6.f*dt); 11 } 12 if (Input::GetInstance()->IsKeyDown('W')) 13 { 14 m_camera.Walk(6.f*dt); 15 } 16 else if (Input::GetInstance()->IsKeyDown('S')) 17 { 18 m_camera.Walk(-6.f*dt); 19 } 20 21 22 if (Input::GetInstance()->IsMouseMove()) 23 { 24 float mouseX = Input::GetInstance()->GetMouseX(); 25 float mouseY = Input::GetInstance()->GetMouseY(); 26 if (Input::GetInstance()->IsLMouseDown()) 27 { 28 float dx = XMConvertToRadians(0.25f*(mouseX - m_lastMousePos.x)); 29 float dy = XMConvertToRadians(0.25f*(mouseY - m_lastMousePos.y)); 30 31 OutputDebugString(L"left btn click"); 32 m_camera.Pitch(dy); 33 m_camera.RotateY(dx); 34 } 35 m_lastMousePos.x = mouseX; 36 m_lastMousePos.y = mouseY; 37 } 38 39 m_camera.UpdateViewMatrix(); 40 }