从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);
}


相关文章
|
4月前
|
Java Maven
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
该博客文章介绍了如何使用Java Swing中的JFrame创建一个窗体来收集用户输入的内容,并提供了详细的实现步骤和完整代码示例。
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
|
5月前
|
人工智能
AI,代码库-代码助手---代码输入提示框,询问加上特性,让他返回
AI,代码库-代码助手---代码输入提示框,询问加上特性,让他返回
|
5月前
|
开发者
Qt中的事件该如何学习?(附带案例)
事件是Qt中比较重要的一部分,在初期如果理解不当学习可能会比较困难,这里提一嘴当初教我的那位老师水平是真的高,让我很轻易的就理解了事件的概念。 在平时我们见到那些界面上的某些快捷键就有可能是事件做的,例如ESC关闭窗口,Enter提交或者登录这种类似的,这也是事件的强大之处。
129 0
|
6月前
|
数据可视化 C# 图形学
【推荐100个unity插件之18】Unity 新版输入系统Input System的基础使用
【推荐100个unity插件之18】Unity 新版输入系统Input System的基础使用
180 0
|
7月前
uni-app 81聊天类封装(十五)-读取会话功能
uni-app 81聊天类封装(十五)-读取会话功能
38 1
vue--ios手机input点击手机输入键盘顶起页面解决方案
vue--ios手机input点击手机输入键盘顶起页面解决方案
|
新能源
APICloud AVM框架封装车牌号输入键盘组件
APICloud AVM框架 封装车牌号输入键盘组件实例分享。封装了车牌号输入键盘,支持燃油汽车、新能源车辆、教练车、挂车、警车5种模式。针对输入的车牌号进行了正则验证。
144 0
PyQt5 技术篇-调用输入对话框(QInputDialog)获取用户输入内容。
PyQt5 技术篇-调用输入对话框(QInputDialog)获取用户输入内容。
935 0
PyQt5 技术篇-调用输入对话框(QInputDialog)获取用户输入内容。
|
XML 测试技术 数据安全/隐私保护
一起谈.NET技术,VS2010测试功能之旅:编码的UI测试(2)-操作动作的录制原理(上)
  回顾    在之前我们介绍了如何用VS2010的UI测试功能创建一个简单的示例,大致描述了如何使用编码的UI测试进行录制和回放,在这章会着重描述VS2010是如何录制操作,并且生成代码,以及初步介绍如何通过自己写代码的方式进行测试。
1152 0
|
测试技术 数据安全/隐私保护
一起谈.NET技术,VS2010测试功能之旅:编码的UI测试(2)-操作动作的录制原理(下)
  回顾   在本章上部分介绍了操作动作的录制原理,描述了操作动作是如何录制,UIMap.uitest和UIMap.Designer.cs的代码如何生成,以及他们的结构。在这个部分,将着重说明如何通过修改UIMap1.uitest文件的操作动作部分的代码来控制UIMap1.Designer.cs操作动作部分代码的生成,实现第一种方式的自定义编码。
1048 0