从0开发游戏引擎之Win32平台用户输入事件Input类实现

简介: Input类主要实现的功能是 监听用户鼠标键盘事件,当收到操作系统回调之后首先会调到场景管理类,然后通过场景管理类,会调到Input类,然后Input类会传递给KeyInput类和MouseInput处理鼠标和键盘相关的逻辑代码。

Input类主要实现的功能是 监听用户鼠标键盘事件,当收到操作系统回调之后首先会调到场景管理类,然后通过场景管理类,会调到Input类,然后Input类会传递给KeyInput类和MouseInput处理鼠标和键盘相关的逻辑代码。


MouseInput被调起的时候,会记录当前鼠标在屏幕中的坐标点,然后更新鼠标的状态。代码详见程序1.1


KeyInput被调起的时候,会更新当前键盘的状态,按下或者是抬起。详见程序1.2


程序1.1


LRESULT MouseInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (_code == LButton)
  {
    if (msg == WM_LBUTTONDOWN)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseDown;
    }
    else if (msg == WM_LBUTTONUP)
    {
      _event = MouseUp;
    }
  }
  else if (_code == MButton)
  {
    if (msg == WM_MBUTTONDOWN)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseDown;
    }
    else if (msg == WM_MBUTTONUP)
    {
      _event = MouseUp;
    }
  }
  else if (_code == RButton)
  {
    if (msg == WM_RBUTTONDOWN)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseDown;
    }
    else if (msg == WM_RBUTTONUP)
    {
      _event = MouseUp;
    }
  }
  else if (_code == Moving)
  {
    if (msg == WM_MOUSEMOVE)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseMove;
    }
  }
  else if (_code == Wheel)
  {
    if (msg == 0x020A/*WM_MOUSEWHEEL*/)
    {
      scroll = HIWORD(wParam);
      _event = WheelScroll;
    }
  }
  return 0;
}


程序1.2


LRESULT KeyInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (msg == WM_KEYDOWN)
  {
    if (_event == None && _code == wParam)
    {
      _event = KeyDown;
    }
  }
  else if (msg == WM_KEYUP)
  {
    if (_code == wParam)
    {
      _event = KeyUp;
    }
  }
  return 0;
}


完整代码


Input.h


#pragma once
enum InputEvent//输入消息的事件
{
  None,
  MouseDown,
  Mouseing,
  MouseUp,
  WheelScroll,
  KeyDown,
  Keying,
  KeyUp,
  MouseMove
};
class InputBase
{
protected:
  InputEvent _event;
  int _code;
public:
  virtual void nextState() = 0;
  virtual LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) = 0;
};
class KeyInput :public InputBase
{
public:
  KeyInput(int code);
  void nextState();
  LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  bool getKey()
  {
    return _event == Keying;
  }
  bool getKeyDown()
  {
    return _event == KeyDown;
  }
  bool getKeyUp()
  {
    return _event == KeyUp;
  }
};
struct MouseData
{
  short scroll;     //滚动码
  POINT delta;      //鼠标根据上一个点的偏移值
  POINT mousePos;     //现在的点
};
enum MouseCode
{
  LButton,
  MButton,
  RButton,
  Wheel,
  Moving
};
class MouseInput :public InputBase
{
private:
  short scroll;
  POINT ptLast;
  POINT pt;
public:
  MouseInput(MouseCode code);
  void nextState();
  LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  bool getMouse(MouseData * mouseData = NULL);
  bool getMouseMove(MouseData * mouseData = NULL);
  bool getMouseDown(MouseData * mouseData = NULL);
  bool getMouseUp(MouseData * mouseData = NULL);
  bool getMouseWheel(MouseData * mouseData = NULL);
};
class Input//管理类
{
private:
  static map<string, InputBase*> inputList;
public:
  static LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  static void flush();
  static bool getKey(int keyCode);
  static bool getKeyDown(int keyCode);
  static bool getKeyUp(int keyCode);
  static bool getMouse(MouseCode mouseCode, MouseData * mouseData = NULL);
  static bool getMouseDown(MouseCode mouseCode, MouseData * mouseData = NULL);
  static bool getMouseUp(MouseCode mouseCode, MouseData * mouseData = NULL);
  static bool getMouseWheel(MouseData * mouseData = NULL);
  static bool getMouseMove(MouseData * mouseData = NULL);
};


Input.cpp


#include "Engine.h"
KeyInput::KeyInput(int code)
{
  _event = None;
  _code = code;
}
void KeyInput::nextState()
{
  if (_event == KeyDown)
  {
    _event = Keying;
  }
  else if (_event == KeyUp)
  {
    _event = None;
  }
}
LRESULT KeyInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (msg == WM_KEYDOWN)
  {
    if (_event == None && _code == wParam)
    {
      _event = KeyDown;
    }
  }
  else if (msg == WM_KEYUP)
  {
    if (_code == wParam)
    {
      _event = KeyUp;
    }
  }
  return 0;
}
MouseInput::MouseInput(MouseCode code)
{
  _event = None;
  _code = code;
}
void MouseInput::nextState()
{
  if (_event == MouseDown)
  {
    _event = Mouseing;
  }
  else if (_event == MouseUp)
  {
    _event = None;
  }
  else if (_event == WheelScroll)
  {
    _event = None;
  }
  else if (_event==MouseMove&&_event==MouseUp)
  {
    _event = MouseMove;
  }
  else if (_event==Mouseing)
  {
    ptLast = pt;
  }
}
LRESULT MouseInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (_code == LButton)
  {
    if (msg == WM_LBUTTONDOWN)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseDown;
    }
    else if (msg == WM_LBUTTONUP)
    {
      _event = MouseUp;
    }
  }
  else if (_code == MButton)
  {
    if (msg == WM_MBUTTONDOWN)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseDown;
    }
    else if (msg == WM_MBUTTONUP)
    {
      _event = MouseUp;
    }
  }
  else if (_code == RButton)
  {
    if (msg == WM_RBUTTONDOWN)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseDown;
    }
    else if (msg == WM_RBUTTONUP)
    {
      _event = MouseUp;
    }
  }
  else if (_code == Moving)
  {
    if (msg == WM_MOUSEMOVE)
    {
      ptLast.x = LOWORD(lParam);
      ptLast.y = HIWORD(lParam);
      _event = MouseMove;
    }
  }
  else if (_code == Wheel)
  {
    if (msg == 0x020A/*WM_MOUSEWHEEL*/)
    {
      scroll = HIWORD(wParam);
      _event = WheelScroll;
    }
  }
  return 0;
}
bool MouseInput::getMouse(MouseData *mouseData)
{
  bool f = _event == Mouseing;
  if (f == true && mouseData != NULL)
  {
    GetCursorPos(&pt);
    ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt);
    mouseData->mousePos.x = pt.x;
    mouseData->mousePos.y = pt.y;
    mouseData->delta.x = pt.x - ptLast.x;
    mouseData->delta.y = pt.y - ptLast.y;
    mouseData->scroll = 0;
  }
  return f;
}
bool MouseInput::getMouseMove(MouseData *mouseData)
{
  bool f = _event == MouseMove;
  if (f == true && mouseData != NULL)
  {
    GetCursorPos(&pt);
    ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt);
    mouseData->mousePos.x = pt.x;
    mouseData->mousePos.y = pt.y;
    mouseData->delta.x = pt.x - ptLast.x;
    mouseData->delta.y = pt.y - ptLast.y;
    mouseData->scroll = 0;
    ptLast = pt;
    GLint   viewport[4]; //视口
    glGetIntegerv(GL_VIEWPORT, viewport); //得到的是最后一个设置视口的参数
    POINT st;
    st.x = viewport[2] * 0.5;
    st.y = viewport[3] * 0.5;
    ClientToScreen(CPlateForm::getInstance()->getHwnd(), &st);//应该是吧鼠标锁在窗口的中心点
    SetCursorPos(st.x, st.y);
  }
  return f;
}
bool MouseInput::getMouseDown(MouseData * mouseData)
{
  bool f = _event == MouseDown;
  if (f == true && mouseData != NULL)
  {
    POINT pt;
    GetCursorPos(&pt);
    ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt);
    memset(mouseData, 0, sizeof(MouseData));
    mouseData->mousePos.x = pt.x;
    mouseData->mousePos.y = pt.y;
  }
  return f;
}
bool MouseInput::getMouseUp(MouseData * mouseData)
{
  bool f = _event == MouseUp;
  if (f == true && mouseData != NULL)
  {
    POINT pt;
    GetCursorPos(&pt);
    ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt);//转换成像素点
    memset(mouseData, 0, sizeof(MouseData));
    mouseData->mousePos.x = pt.x;
    mouseData->mousePos.y = pt.y;
  }
  return f;
}
bool MouseInput::getMouseWheel(MouseData * mouseData)
{
  bool f = _event == WheelScroll;
  if (f == true && mouseData != NULL)
  {
    POINT pt;
    GetCursorPos(&pt);
    ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt);
    mouseData->mousePos.x = pt.x;
    mouseData->mousePos.y = pt.y;
    mouseData->scroll = scroll;
    ptLast = pt;
  }
  return f;
}
map<string, InputBase*> Input::inputList;
LRESULT Input::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  map<string, InputBase*>::iterator iter;
  for (iter = inputList.begin(); iter != inputList.end(); iter++)
  {
    iter->second->msgProc(hWnd, msg, wParam, lParam);
  }
  return 0;
}
void Input::flush()
{
  map<string, InputBase*>::iterator iter;
  for (iter = inputList.begin(); iter != inputList.end(); iter++)
  {
    iter->second->nextState();
  }
}
bool Input::getKey(int keyCode)
{
  static char str[20];
  sprintf(str, "key_%d", keyCode);
  if (inputList[str] == NULL)
  {
    inputList[str] = new KeyInput(keyCode);
  }
  return ((KeyInput*)inputList[str])->getKey();
}
bool Input::getKeyDown(int keyCode)
{
  static char str[20];
  sprintf(str, "key_%d", keyCode);
  if (inputList[str] == NULL)
  {
    inputList[str] = new KeyInput(keyCode);
  }
  return ((KeyInput*)inputList[str])->getKeyDown();
}
bool Input::getKeyUp(int keyCode)
{
  static char str[20];
  sprintf(str, "key_%d", keyCode);
  if (inputList[str] == NULL)
  {
    inputList[str] = new KeyInput(keyCode);
  }
  return ((KeyInput*)inputList[str])->getKeyUp();
}
bool Input::getMouse(MouseCode mouseCode, MouseData * mouseData)
{
  static char str[20];
  sprintf(str, "mouse_%d", mouseCode);
  if (inputList[str] == NULL)
  {
    inputList[str] = new MouseInput(mouseCode);
  }
  return ((MouseInput*)inputList[str])->getMouse(mouseData);
}
bool Input::getMouseDown(MouseCode mouseCode, MouseData * mouseData)
{
  static char str[20];
  sprintf(str, "mouse_%d", mouseCode);
  if (inputList[str] == NULL)
  {
    inputList[str] = new MouseInput(mouseCode);
  }
  return ((MouseInput*)inputList[str])->getMouseDown(mouseData);
}
bool Input::getMouseUp(MouseCode mouseCode, MouseData * mouseData)
{
  static char str[20];
  sprintf(str, "mouse_%d", mouseCode);
  if (inputList[str] == NULL)
  {
    inputList[str] = new MouseInput(mouseCode);
  }
  return ((MouseInput*)inputList[str])->getMouseUp(mouseData);
}
bool Input::getMouseWheel(MouseData * mouseData)
{
  if (inputList["wheel"] == NULL)
  {
    inputList["wheel"] = new MouseInput(MouseCode::Wheel);
  }
  return ((MouseInput*)inputList["wheel"])->getMouseWheel(mouseData);
}
bool Input::getMouseMove(MouseData * mouseData)
{
  if (inputList["move"] == NULL)
  {
    inputList["move"] = new MouseInput(MouseCode::Moving);
  }
  return ((MouseInput*)inputList["move"])->getMouseMove(mouseData);
}


相关文章
|
3月前
|
Java Maven
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
该博客文章介绍了如何使用Java Swing中的JFrame创建一个窗体来收集用户输入的内容,并提供了详细的实现步骤和完整代码示例。
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
|
Windows
万能脚本录制器(支持鼠标/键盘的前台和后台,支持多种绑定模式)
本人现承接各种脚本/程序。包括:网页脚本(网页数据读取,post提交,自动下注等。)办公脚本(Word Excel Xls操作等)安卓模拟器脚本游戏脚本(自动喊话等简单功能,复杂暂不接)等其他脚本各种程序。
15480 0
万能脚本录制器(支持鼠标/键盘的前台和后台,支持多种绑定模式)
|
4月前
|
开发者
Qt中的事件该如何学习?(附带案例)
事件是Qt中比较重要的一部分,在初期如果理解不当学习可能会比较困难,这里提一嘴当初教我的那位老师水平是真的高,让我很轻易的就理解了事件的概念。 在平时我们见到那些界面上的某些快捷键就有可能是事件做的,例如ESC关闭窗口,Enter提交或者登录这种类似的,这也是事件的强大之处。
101 0
|
5月前
|
数据可视化 C# 图形学
【推荐100个unity插件之18】Unity 新版输入系统Input System的基础使用
【推荐100个unity插件之18】Unity 新版输入系统Input System的基础使用
138 0
|
6月前
|
开发框架 算法 程序员
【Qt 元对象系统】深入探索Qt事件过滤:从基础到高级应用
【Qt 元对象系统】深入探索Qt事件过滤:从基础到高级应用
167 7
|
测试技术
开源按键组件MultiButton支持菜单操作(事件驱动型)
开源按键组件MultiButton支持菜单操作(事件驱动型)
495 0
开源按键组件MultiButton支持菜单操作(事件驱动型)
|
新能源
APICloud AVM框架封装车牌号输入键盘组件
APICloud AVM框架 封装车牌号输入键盘组件实例分享。封装了车牌号输入键盘,支持燃油汽车、新能源车辆、教练车、挂车、警车5种模式。针对输入的车牌号进行了正则验证。
141 0
|
开发框架 开发工具 iOS开发
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展(二)
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展
247 0
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展(二)
|
iOS开发 UED
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展
302 0
|
内存技术 容器
Win32编程点滴5 - 响应ActiveX控件的事件
在最近的一篇文章中说到了,如何创建ActiveX,这次我们来响应事件。这次,我们将创建一个类:CGeneralEventSink,它能够响应任何Dispatch事件(事件的接口继承与IDispatch)。
1022 0