处理输入

文章目录

输入类型

游戏有很多输入, 如键盘, 鼠标, 手柄等. SDL库将这些处理变得非常简单, 我们这里将这几种输入统一到一起. 这里不讲太多, 因为目前我们对输入的处理就是检测输入设备的状态, 来更新游戏对象的状态.

上代码

看下代码就行了, 然后对于游戏中的对象怎么使用输入设备的状态, 自己发挥

// InputHandler.h
#ifndef INPUTHANDLER_H_INCLUDED
#define INPUTHANDLER_H_INCLUDED

#include <vector>
#include "SDL.h"
#include "Vector2D.h"

enum mouse_buttons
{
    LEFT = 0,
    MIDDLE = 1,
    RIGHT = 2
};

class InputHandler
{
public:
    static InputHandler* Instance();

    void initializeJoysticks();
    bool joysticksInitialized() { return m_bJoysticksInitialized; }

    int xvalue(int joy, int stick);
    int yvalue(int joy, int stick);
    bool getButtonState(int joy, int buttonNumber)
    {
        return m_buttonStates[joy][buttonNumber];
    }

    bool getMouseButtonState(int buttonNumber)
    {
        return m_mouseButtonStates[buttonNumber];
    }

    Vector2D* getMousePosition()
    {
        return m_mousePosition;
    }

    bool isKeyDown(SDL_Scancode key);

    void update();
    void clean();

private:
    InputHandler();
    ~InputHandler() {}

    // handle keyboard events
    void onKeyDown();
    void onKeyUp();

    // handle mouse events
    void onMouseMove(SDL_Event& event);
    void onMouseButtonDown(SDL_Event& event);
    void onMouseButtonUp(SDL_Event& event);

    // handle joysticks events
    void onJoystickAxisMove(SDL_Event& event);
    void onJoystickButtonDown(SDL_Event& event);
    void onJoystickButtonUp(SDL_Event& event);

private:
    static InputHandler* s_pInstance;

    Vector2D* m_mousePosition;
    const Uint8* m_keystate;

    std::vector<SDL_Joystick*> m_joysticks;
    std::vector<std::pair<Vector2D*, Vector2D*> > m_joystickValues;
    std::vector<std::vector<bool> > m_buttonStates;
    std::vector<bool> m_mouseButtonStates;

    bool m_bJoysticksInitialized;
    const int m_joystickDeadZone = 10000;
};

typedef InputHandler TheInputHandler;

#endif // INPUTHANDLER_H_INCLUDED
// InputHandler.cpp
#include <iostream>
#include "InputHandler.h"
#include "Game.h"

InputHandler* InputHandler::s_pInstance = nullptr;

InputHandler::InputHandler()
{
    for (int i = 0; i < 3; ++i) {
        m_mouseButtonStates.push_back(false);
    }

    m_mousePosition = new Vector2D(0, 0);
}

InputHandler* InputHandler::Instance()
{
    if (s_pInstance == nullptr) {
        s_pInstance = new InputHandler();
    }
    return s_pInstance;
}

void InputHandler::initializeJoysticks()
{
    if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) {
        SDL_InitSubSystem(SDL_INIT_JOYSTICK);
    }

    if (SDL_NumJoysticks() > 0) {
        for (int i = 0; i < SDL_NumJoysticks(); ++i) {
            SDL_Joystick* joy = SDL_JoystickOpen(i);
            if (joy) {
                m_joysticks.push_back(joy);
                m_joystickValues.push_back(std::make_pair(new Vector2D(0, 0), new Vector2D(0, 0)));

                std::vector<bool> tempButtons;

                for (int j = 0; j < SDL_JoystickNumButtons(joy); ++j) {
                    tempButtons.push_back(false);
                }

                m_buttonStates.push_back(tempButtons);
            }
            else {
                std::cout << SDL_GetError();
            }
        }

        SDL_JoystickEventState(SDL_ENABLE);
        m_bJoysticksInitialized = true;

        std::cout << "Initialised " << m_joysticks.size() << " joystick(s)\n";
    }
    else {
        m_bJoysticksInitialized = false;
    }
}

void InputHandler::clean()
{
    std::cout << "free resource in InputHandler.\n";

    if (m_bJoysticksInitialized) {
        for (int i = 0; i < SDL_NumJoysticks(); i++) {
            SDL_JoystickClose(m_joysticks[i]);
        }
    }

    delete m_mousePosition;
    delete s_pInstance;
}

void InputHandler::update()
{
    SDL_Event event;

    m_keystate = SDL_GetKeyboardState(NULL);

    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_QUIT:
            TheGame::Instance()->quit();
            break;

        case SDL_JOYAXISMOTION:
            onJoystickAxisMove(event);
            break;

        case SDL_JOYBUTTONDOWN:
            onJoystickButtonDown(event);
            break;

        case SDL_JOYBUTTONUP:
            onJoystickButtonUp(event);
            break;

        case SDL_MOUSEMOTION:
            onMouseMove(event);
            break;

        case SDL_MOUSEBUTTONDOWN:
            onMouseButtonDown(event);
            break;

        case SDL_MOUSEBUTTONUP:
            onMouseButtonUp(event);
            break;

        case SDL_KEYDOWN:
            onKeyDown();
            break;

        case SDL_KEYUP:
            onKeyUp();
            break;

        default:
            break;
        }
    }
}

int InputHandler::xvalue(int joy, int stick)
{
    if (m_joystickValues.size() > 0) {
        if (stick == 1) {
            return m_joystickValues[joy].first->getX();
        }
        else if (stick == 2) {
            return m_joystickValues[joy].second->getX();
        }
    }

    return 0;
}

int InputHandler::yvalue(int joy, int stick)
{
    if (m_joystickValues.size() > 0) {
        if (stick == 1) {
            return m_joystickValues[joy].first->getY();
        }
        else if (stick == 2) {
            return m_joystickValues[joy].second->getY();
        }
    }

    return 0;
}

bool InputHandler::isKeyDown(SDL_Scancode key)
{
    return m_keystate ? m_keystate[key] == 1 : false;
}


void InputHandler::onKeyDown()
{

}

void InputHandler::onKeyUp()
{

}

void InputHandler::onJoystickAxisMove(SDL_Event& event)
{
    int whichOne = event.jaxis.which;
    if (event.jaxis.axis == 0) {
        if (event.jaxis.value > m_joystickDeadZone) {
            m_joystickValues[whichOne].first->setX(1);
        }
        else if (event.jaxis.value < -m_joystickDeadZone) {
            m_joystickValues[whichOne].first->setX(-1);
        }
        else {
            m_joystickValues[whichOne].first->setX(0);
        }
    }

    if (event.jaxis.axis == 1) {
        if (event.jaxis.value > m_joystickDeadZone) {
            m_joystickValues[whichOne].first->setY(1);
        }
        else if (event.jaxis.value < -m_joystickDeadZone) {
            m_joystickValues[whichOne].first->setY(-1);
        }
        else {
            m_joystickValues[whichOne].first->setY(0);
        }
    }

    // right stick move left or right
    if (event.jaxis.axis == 3) {
        if (event.jaxis.value > m_joystickDeadZone) {
            m_joystickValues[whichOne].second->setX(1);
        }
        else if (event.jaxis.value < -m_joystickDeadZone) {
            m_joystickValues[whichOne].second->setX(-1);
        }
        else {
            m_joystickValues[whichOne].second->setX(0);
        }
    }

    // right stick move up or down
    if (event.jaxis.axis == 4) {
        if (event.jaxis.value > m_joystickDeadZone) {
            m_joystickValues[whichOne].second->setY(1);
        }
        else if (event.jaxis.value < -m_joystickDeadZone) {
            m_joystickValues[whichOne].second->setY(-1);
        }
        else {
            m_joystickValues[whichOne].second->setY(0);
        }
    }
}

void InputHandler::onJoystickButtonDown(SDL_Event& event)
{
    m_buttonStates[event.jaxis.which][event.jbutton.button] = true;
}

void InputHandler::onJoystickButtonUp(SDL_Event& event)
{
    m_buttonStates[event.jaxis.which][event.jbutton.button] = false;
}

void InputHandler::onMouseButtonDown(SDL_Event& event)
{
    if (event.button.button == SDL_BUTTON_LEFT) {
        m_mouseButtonStates[LEFT] = true;
    }

    if (event.button.button == SDL_BUTTON_MIDDLE) {
        m_mouseButtonStates[MIDDLE] = true;
    }

    if (event.button.button == SDL_BUTTON_RIGHT) {
        m_mouseButtonStates[RIGHT] = true;
    }
}

void InputHandler::onMouseButtonUp(SDL_Event& event)
{
    if (event.button.button == SDL_BUTTON_LEFT) {
        m_mouseButtonStates[LEFT] = false;
    }

    if (event.button.button == SDL_BUTTON_MIDDLE) {
        m_mouseButtonStates[MIDDLE] = false;
    }

    if (event.button.button == SDL_BUTTON_RIGHT) {
        m_mouseButtonStates[RIGHT] = false;
    }
}

void InputHandler::onMouseMove(SDL_Event& event)
{
    m_mousePosition->setX(event.motion.x);
    m_mousePosition->setY(event.motion.y);
}

猜你喜欢

转载自blog.csdn.net/creambean/article/details/88749160
今日推荐