zoukankan      html  css  js  c++  java
  • hge source explor 0x6 input module

    Input Module

      封装与输入相关的属性,函数。

    input.h
    struct CInputEventList
    {
        GEInputEvent        event;
        CInputEventList*    next;
    };
    
    class Input
    {
    public:
        Input();
    
        void    GetMousePos(float* x, float* y);
        void    SetMousePos(float x, float y);
        int        GetMouseWheel();
        bool    IsMouseOver();
        bool    KeyDown(int key);
        bool    KeyUp(int key);
        bool    GetKeyState(int key);
        char*    GetKeyName(int key);
        int        GetKey();
        int        GetChar();
        bool    GetEvent(GEInputEvent* event);
    
        void    UpdateMouse();
        void    Init();
        void    ClearQueue();
        void    BuildEvent(int type, int key, int scan, int flags, int x, int y);
    
    public:
        int        VKey;
        int        Char;
        int        Zpos;
        float    Xpos;
        float    Ypos;
        bool    bMouseOver;
        bool    bCaptured;
        char    keyz[256];
    
        CInputEventList*    queue;
    
    };
    class Input

    input.cpp
    //************* 输入系统内部接口 *****************
    
    Input::Input()
    {
        queue = 0;
        Char = VKey = Zpos = 0;
        Xpos = Ypos = 0;
        bMouseOver = false;
        bCaptured = false;
        
        // keyz保存着现在键盘的信息,在同一帧可以实现多按键
        memset(&keyz, 0, sizeof(keyz));
    }
    
    void Input::Init()
    {
        POINT    pt;
        GetCursorPos(&pt);
        ScreenToClient(pge->win->hwnd, &pt);
        Xpos = (float)pt.x;
        Ypos = (float)pt.y;
    
    }
    
    // 创建输入事件
    void Input::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&GEINP_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(pge->win->hwnd, &pt);        // 这里把位置设为(0,0),其实可以不用
        }
        else
        {
            eptr->event.key = key;    eptr->event.wheel = 0;
        }
    
        if (type == INPUT_MBUTTONDOWN)            // 鼠标按键按下,要设置成焦点
        {
            keyz[key] |= 1;
            SetCapture(pge->win->hwnd);
            bCaptured = true;
        }
    
        if (type == INPUT_MBUTTONUP)            // 鼠标弹起,释放焦点
        {
            keyz[key] |= 2;
            ReleaseCapture();
            SetMousePos(Xpos, Ypos);
            pt.x = (int)Xpos;    pt.y = (int)Ypos;
            bCaptured = false;
        }
    
        // 检测功能键
        if (kbstate[VK_SHIFT] & 0x80) flags |= GEINP_SHIFT;
        if (kbstate[VK_CONTROL] & 0x80) flags |= GEINP_CTRL;
        if (kbstate[VK_MENU] & 0x80) flags |= GEINP_ALT;
        if (kbstate[VK_CAPITAL] & 0x1) flags |= GEINP_CAPSLOCK;
        if (kbstate[VK_SCROLL] & 0x1) flags |= GEINP_SCROLLLOCK;
        if (kbstate[VK_NUMLOCK] & 0x1) flags |= GEINP_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 >= pge->win->nScreenWidth)        pt.x = pge->win->nScreenWidth - 1;
            if (pt.y >= pge->win->nScreenHeight)    pt.y = pge->win->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;
        }
    }
    
    // 获得事件,事件队列的第一件事情
    bool Input::GetEvent(GEInputEvent* event)
    {
        CInputEventList* eptr;
    
        if (queue)
        {
            eptr = queue;
            memcpy(event, &eptr->event, sizeof(GEInputEvent));
            queue = eptr->next;
            delete eptr;
            return true;
        }
    
        return false;
    }
    
    void Input::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;
    }
    
    
    //*********  鼠标 **************
    
    void Input::UpdateMouse()
    {
        POINT        pt;
        RECT        rc;
    
        GetCursorPos(&pt);
        GetClientRect(pge->win->hwnd, &rc);
        MapWindowPoints(pge->win->hwnd, NULL, (LPPOINT)&rc, 2);
    
        if (bCaptured || (PtInRect(&rc, pt) && WindowFromPoint(pt) == pge->win->hwnd))
            bMouseOver = true;
        else
            bMouseOver = false;
    }
    
    void Input::GetMousePos(float* x, float *y)
    {
        *x = Xpos;    *y = Ypos;
    }
    
    void Input::SetMousePos(float x, float y)
    {
        POINT    pt;
        pt.x = (long)x;    pt.y = (long)y;
        ClientToScreen(pge->win->hwnd, &pt);
        SetCursorPos(pt.x, pt.y);
    }
    
    int Input::GetMouseWheel()
    {
        return Zpos;
    }
    
    bool Input::IsMouseOver()
    {
        return bMouseOver;
    }
    
    //************* 键盘 ******************
    
    bool Input::KeyDown(int key)
    {
        return (keyz[key] & 1) != 0;
    }
    
    bool Input::KeyUp(int key)
    {
        return (keyz[key] & 2) != 0;
    }
    
    bool Input::GetKeyState(int key)
    {
        return ((::GetKeyState(key) & 0x8000) != 0);        // ::GetKeyState(key) 调用window中的
    }
    
    char* Input::GetKeyName(int key)
    {
        return KeyNames[key];
    }
    
    int Input::GetKey()
    {
        return VKey;
    }
    
    int Input::GetChar()
    {
        return Char;
    }
    input.cpp

      在主循环中测试输入,如图:

  • 相关阅读:
    开灯问题
    独木舟上的旅行
    剑指offer--从尾到头打印链表
    映芬视觉网页练习
    游标的使用
    数据库操作
    关系型数据库
    数据库基础知识
    TCPSocket系列二
    HTML5新标签与css3选择器
  • 原文地址:https://www.cnblogs.com/yoru/p/5510125.html
Copyright © 2011-2022 走看看