码迷,mamicode.com
首页 > 其他好文 > 详细

hge source explor 0x5 input module

时间:2016-05-22 10:57:55      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

Input Module

  前面提到输入事件,那么对输入事件分类,分类如下

/*
** HGE Input Event type constants
*/
#define INPUT_KEYDOWN          1
#define INPUT_KEYUP            2
#define INPUT_MBUTTONDOWN      3
#define INPUT_MBUTTONUP        4
#define INPUT_MOUSEMOVE        5
#define INPUT_MOUSEWHEEL       6

  接下来看每个函数


 

_InputInit

  在引擎中初始化鼠标和键盘信息,在引擎 的初始化过程(构造函数)中会遇到(system.cpp:hge_impl)。

技术分享
void HGE_Impl::_InputInit()
{
    POINT    pt;
    GetCursorPos(&pt);
    ScreenToClient(hwnd, &pt);
    Xpos = (float)pt.x;
    Ypos = (float)pt.y;

    memset(&keyz, 0, sizeof(keyz));
}
_InputInit

 

_UpdateMouse

  这个函数会在主循环(system.cpp:system_start)中被调用,每一帧都更新鼠标的信息。

  1.更新获得鼠标的位置;2.判断如果鼠标被按下(bCaptured==true)同时在游戏窗口内,则设置标志bMouseOver(鼠标是否在游戏窗口内)。

技术分享
void HGE_Impl::_UpdateMouse()
{
    POINT    pt;
    RECT    rc;

    GetCursorPos(&pt);
    GetClientRect(hwnd, &rc);
    MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2);

    if(bCaptured || (PtInRect(&rc, pt) && WindowFromPoint(pt)==hwnd))
        bMouseOver=true;
    else
        bMouseOver=false;
}
_UpdateMouse

 

_BuildEvent(int type, int key, int scan, int flags, int x, int y)  核心!核心!核心!

  在这个函数中,根据type的不同选填不同的参数,创建不同的事件,填写事件结构,在window的消息处理函数中调用。(system.cpp:WindowProc)

  • 将事件类型设置为传递过来的类型;键码设置为0;鼠标位置更新为传递进来的x,y
  • GetKeyboardState(kbstate)获取当时的键盘信息
  • 按键按下类型:如果重复按下则不更新,否则更新引擎所管理的按键信息(全局)
  • 按键弹起类型:更新按键信息弹起信息
  • 滚轮类型:是的情况下,按键设置为0,将滚轮属性定位key值;否的情况下,则将按键属性更新为key值,否则为0
  • 鼠标按键按下类型:设置按键信息;设置焦点
  • 鼠标按键弹起类型:设置按键信息,取消焦点;重新设置鼠标坐标,更新鼠标位置信息
  • 对于功能键的属性的按键的更新
  • 如果传递进来的x=-1,则为按键类型的事件,现在讲事件的鼠标信息更新;否则判断鼠标是否出界,并更新鼠标位置
  • 将事件加入输入事件队列
  • 更新引擎所掌握的鼠标位置、按键信息
技术分享
void HGE_Impl::_BuildEvent(int type, int key, int scan, int flags, int x, int y)
{
    CInputEventList *last, *eptr=new CInputEventList;
    unsigned char kbstate[256];
    POINT pt;

    eptr->event.type=type;
    eptr->event.chr=0;
    pt.x=x; pt.y=y;

    GetKeyboardState(kbstate);
    if(type==INPUT_KEYDOWN)
    {
        if((flags & HGEINP_REPEAT) == 0) keyz[key] |= 1;
        ToAscii(key, scan, kbstate, (unsigned short *)&eptr->event.chr, 0);
    }
    if(type==INPUT_KEYUP)
    {
        keyz[key] |= 2;
        ToAscii(key, scan, kbstate, (unsigned short *)&eptr->event.chr, 0);
    }
    if(type==INPUT_MOUSEWHEEL)
    {
        eptr->event.key=0; eptr->event.wheel=key;
        ScreenToClient(hwnd,&pt);
    }
    else { eptr->event.key=key; eptr->event.wheel=0; }

    if(type==INPUT_MBUTTONDOWN)
    {
        keyz[key] |= 1;
        SetCapture(hwnd);
        bCaptured=true;
    }
    if(type==INPUT_MBUTTONUP)
    {
        keyz[key] |= 2;
        ReleaseCapture();
        Input_SetMousePos(Xpos, Ypos);
        pt.x=(int)Xpos; pt.y=(int)Ypos;
        bCaptured=false;
    }
    
    if(kbstate[VK_SHIFT] & 0x80) flags|=HGEINP_SHIFT;
    if(kbstate[VK_CONTROL] & 0x80) flags|=HGEINP_CTRL;
    if(kbstate[VK_MENU] & 0x80) flags|=HGEINP_ALT;
    if(kbstate[VK_CAPITAL] & 0x1) flags|=HGEINP_CAPSLOCK;
    if(kbstate[VK_SCROLL] & 0x1) flags|=HGEINP_SCROLLLOCK;
    if(kbstate[VK_NUMLOCK] & 0x1) flags|=HGEINP_NUMLOCK;
    eptr->event.flags=flags;

    if(pt.x==-1) { eptr->event.x=Xpos;eptr->event.y=Ypos; }
    else
    {
        if(pt.x<0) pt.x=0;
        if(pt.y<0) pt.y=0;
        if(pt.x>=nScreenWidth) pt.x=nScreenWidth-1;
        if(pt.y>=nScreenHeight) pt.y=nScreenHeight-1;

        eptr->event.x=(float)pt.x;
        eptr->event.y=(float)pt.y;
    }

    eptr->next=0; 

    if(!queue) queue=eptr;
    else
    {
        last=queue;
        while(last->next) last=last->next;
        last->next=eptr;
    }

    if(eptr->event.type==INPUT_KEYDOWN || eptr->event.type==INPUT_MBUTTONDOWN)
    {
        VKey=eptr->event.key;Char=eptr->event.chr;
    }
    else if(eptr->event.type==INPUT_MOUSEMOVE)
    {
        Xpos=eptr->event.x;Ypos=eptr->event.y;
    }
    else if(eptr->event.type==INPUT_MOUSEWHEEL)
    {
        Zpos+=eptr->event.wheel;
    }
}
_BuildEvent

 

_ClearQueue

  清理输入事件队列,清理键盘,在主循环中会被调用。

技术分享
void HGE_Impl::_ClearQueue()
{
    CInputEventList *nexteptr, *eptr=queue;

    memset(&keyz, 0, sizeof(keyz));
    
    while(eptr)
    {
        nexteptr=eptr->next;
        delete eptr;
        eptr=nexteptr;
    }

    queue=0; VKey=0; Char=0; Zpos=0;
}
_ClearQueue

 

Input_GetEvent(hgeInputEvent *event)

  获取输入事件队列的第一个事件。

技术分享
bool CALL HGE_Impl::Input_GetEvent(hgeInputEvent *event)
{
    CInputEventList *eptr;

    if(queue)
    {
        eptr=queue;
        memcpy(event, &eptr->event, sizeof(hgeInputEvent));
        queue=eptr->next;
        delete eptr;
        return true;
    }
    
    return false;
}
Input_GetEvent

 

 Input_GetMousePos(float *x, float *y)

  获取鼠标当前的位置信息。

技术分享
void CALL HGE_Impl::Input_GetMousePos(float *x, float *y)
{
    *x=Xpos; *y=Ypos;
}
Input_GetMousePos

 

 Input_SetMousePos(float x, float y)

  设置鼠标位置:需要先ClientToScreen,再SetCursorPos。

技术分享
void CALL HGE_Impl::Input_SetMousePos(float x, float y)
{
    POINT pt;
    pt.x=(long)x; pt.y=(long)y;
    ClientToScreen(hwnd, &pt);
    SetCursorPos(pt.x,pt.y);
}
Input_SetMousePos

 

 Input_GetMouseWheel

  获取鼠标的滚轮信息。

技术分享
int CALL HGE_Impl::Input_GetMouseWheel()
{
    return Zpos;
}
Input_GetMouseWheel

 

 Input_IsMouseOver

   返回鼠标是否在游戏窗口上。

技术分享
bool CALL HGE_Impl::Input_IsMouseOver()
{
    return bMouseOver;
}
Input_IsMouseOver

 

Input_GetKeyState(int key)

  返回键盘按键key是否被按键,在这里并没有调用引擎管理的当前键盘的状态来获取,而是直接通过GetKeyState(key)&0x8000来获取即时信息。

技术分享
bool CALL HGE_Impl::Input_GetKeyState(int key)
{
    return ((GetKeyState(key) & 0x8000) != 0);
}
Input_GetKeyState

 

 Input_KeyDown

   按键是否被按下,这里按键按下是通过查看引擎管理的键盘信息来查看。

技术分享
bool CALL HGE_Impl::Input_KeyDown(int key)
{
    return (keyz[key] & 1) != 0;
}
Input_KeyDown

 

 Input_KeyUp

  按键是否弹起,这里也是通过引擎管理的键盘信息来查看。

技术分享
bool CALL HGE_Impl::Input_KeyUp(int key)
{
    return (keyz[key] & 2) != 0;
}
Input_KeyUp

 

 Input_GetKeyName

  获取某一个按键的名字。

技术分享
char* CALL HGE_Impl::Input_GetKeyName(int key)
{
    return KeyNames[key];
}
Input_GetKeyName

 

 Input_GetKey

  获取当前被触发的按键。   

技术分享
int CALL HGE_Impl::Input_GetKey()
{
    return VKey;
}
Input_GetKey

 

 Input_GetChar

  获取当前被触发按键的键码 。

技术分享
int CALL HGE_Impl::Input_GetChar()
{
    return Char;
}
Input_GetChar

 

hge source explor 0x5 input module

标签:

原文地址:http://www.cnblogs.com/yoru/p/5506925.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!