输入类型
游戏有很多输入, 如键盘, 鼠标, 手柄等. 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);
}