hge source explor 0x5 input module

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hge source explor 0x5 input module相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

hge source explor 0x8 timer

hge source explor 0x4 input module

hge source explor 0x6 input module

hge source explor 0x3 windows module

hge source explor 0xB graphics Ⅱ

hge source explor 0xD graphics Ⅳ