English
Mapování kláves.
07.06.2006
Program načte ze souboru K3dEngine.lua hodnoty akcí a přiřazených kláves.
--KeyMap
KeyMap=
{
GoForward= "w" ,
GoBackward= "s" ,
GoUp= "r" ,
GoDown= "f" ,
StrafeLeft= "a" ,
StrafeRight= "d" ,
LurchLeft= "q" ,
LurchRight= "e" ,
TurnLeft= "left" ,
TurnRight= "right" ,
TurnUp= "up" ,
TurnDown= "down"
}
Klávesy můžeme nastavit podle definicí
#define K_STR_ESC "esc"
#define K_STR_A "a"
#define K_STR_B "b"
#define K_STR_C "c"
#define K_STR_D "d"
#define K_STR_E "e"
#define K_STR_F "f"
#define K_STR_G "g"
#define K_STR_H "h"
#define K_STR_I "i"
#define K_STR_J "j"
#define K_STR_K "k"
#define K_STR_L "l"
#define K_STR_M "m"
#define K_STR_N "n"
#define K_STR_O "o"
#define K_STR_P "p"
#define K_STR_Q "q"
#define K_STR_R "r"
#define K_STR_S "s"
#define K_STR_T "t"
#define K_STR_U "u"
#define K_STR_V "v"
#define K_STR_W "w"
#define K_STR_X "x"
#define K_STR_Y "y"
#define K_STR_Z "z"
#define K_STR_1 "1"
#define K_STR_2 "2"
#define K_STR_3 "3"
#define K_STR_4 "4"
#define K_STR_5 "5"
#define K_STR_6 "6"
#define K_STR_7 "7"
#define K_STR_8 "8"
#define K_STR_9 "9"
#define K_STR_ZERO "0"
#define K_STR_F1 "f1"
#define K_STR_F2 "f2"
#define K_STR_F3 "f3"
#define K_STR_F4 "f4"
#define K_STR_F5 "f5"
#define K_STR_F6 "f6"
#define K_STR_F7 "f7"
#define K_STR_F8 "f8"
#define K_STR_F9 "f9"
#define K_STR_F10 "f10"
#define K_STR_F11 "f11"
#define K_STR_F12 "f12"
#define K_STR_LEFT "left"
#define K_STR_RIGHT "right"
#define K_STR_UP "up"
#define K_STR_DOWN "down"
#define K_STR_INSERT "insert"
#define K_STR_DELETE "delete"
#define K_STR_HOME "home"
#define K_STR_END "end"
#define K_STR_PLUS "+"
#define K_STR_MINUS "-"
#define K_STR_MULT "*"
#define K_STR_SPACE "space"
#define K_STR_LSHIFT "lshift"
#define K_STR_RSHIFT "rshift"
#define K_STR_LALT "lalt"
#define K_STR_RALT "ralt"
#define K_STR_LCTRL "lctrl"
#define K_STR_RCTRL "rctrl"
#define K_STR_ENTER "enter"
#define K_STR_BACKSPACE "backspace"
#define K_STR_SPACE "space"
#define K_STR_SLASH "/"
#define K_STR_CONSOLE "~"
#define K_STR_LEFT_BRACKET "["
#define K_STR_RIGHT_BRACKET "]"
#define K_STR_SEMICOLON ";"
#define K_STR_DOT "."
#define K_STR_COMMA ","
#define K_STR_ACUTE "'"
#define K_STR_TAB "tab"
#define K_STR_CAPS_LOCK "capslock"
#define K_STR_PAGE_UP "pageup"
#define K_STR_PAGE_DOWN "pagedown"
Načtené hodnoty uložíme do keymapy.
typedef std::map<EKeyMapAction, int > TKeyMap;
TKeyMap m_tKeyMap;
EKeyMapAction je enumerátor akcí
int je SDL index klávesy
enum EKeyMapAction
{
K_GO_FORWARD= 0 ,
K_GO_BACKWARD,
K_GO_UP,
K_GO_DOWN,
K_STRAFE_LEFT,
K_STRAFE_RIGHT,
K_LURCH_LEFT,
K_LURCH_RIGHT,
K_TURN_LEFT,
K_TURN_RIGHT,
K_TURN_UP,
K_TURN_DOWN,
K_NUM_ACTION
};
Volaná akce se vyhledává v keymapě, která vrácí SDL index klávesy.
/// \brief Test if is key pressed
bool CKeyMap::IsKeyPressed(EKeyMapAction _eKey)
{
return IsSdlKeyPressed(m_tKeyMap[_eKey]);
}
Pokud je klávesa stisknuta, akce se provede.
/// \brief Check if key pressed
/// \retval bool True if key pressed
bool IsSdlKeyPressed( const int _iSDLKey)
{
if (m_puiKeys[_iSDLKey] == SDL_PRESSED)
{
return true ;
}
else
{
return false ;
}
}
Proměnná m_puiKeys je pointer na Uint8
Uint8* m_puiKeys;
Tento pointer se inicializuje v konstruktoru třídy CKeyboard
CKeyboard()
{
m_puiKeys = SDL_GetKeyState(NULL);
}
A v každém snímku se updatuje stavové pole kláves
inline void CKeyboard::UpdateKeyboard()
{
SDL_PumpEvents();
}
Jak naplnit keymapu?
Budeme potřebovat dvě pomocné mapy.
typedef std::map<std::string, int > TStrIntMap;
typedef std::pair<std::string, int > TStrIntPair;
typedef std::map<std::string, EKeyMapAction> TStrActionMap;
typedef std::pair<std::string, EKeyMapAction> TStrActionPair;
TStrActionMap m_tActionTransferMap;
TStrIntMap m_tKeyTransferMap;
Které naplníme v konstruktoru třídy CKeyMapBuild
CKeyMapBuild(CGameData *_pGameData)
{
// Set global data
m_pGameData = _pGameData;
// Initialize key maps
m_tActionTransferMap.insert(TStrActionPair(K_STR_GO_FORWARD, K_GO_FORWARD));
m_tActionTransferMap.insert(TStrActionPair(K_STR_GO_BACKWARD,K_GO_BACKWARD));
m_tActionTransferMap.insert(TStrActionPair(K_STR_GO_UP,K_GO_UP));
m_tActionTransferMap.insert(TStrActionPair(K_STR_GO_DOWN, K_GO_DOWN));
m_tActionTransferMap.insert(TStrActionPair(K_STR_STRAFE_LEFT,K_STRAFE_LEFT));
m_tActionTransferMap.insert(TStrActionPair(K_STR_STRAFE_RIGHT,K_STRAFE_RIGHT));
m_tActionTransferMap.insert(TStrActionPair(K_STR_LURCH_LEFT,K_LURCH_LEFT));
m_tActionTransferMap.insert(TStrActionPair(K_STR_LURCH_RIGHT,K_LURCH_RIGHT));
m_tActionTransferMap.insert(TStrActionPair(K_STR_TURN_LEFT,K_TURN_LEFT));
m_tActionTransferMap.insert(TStrActionPair(K_STR_TURN_RIGHT,K_TURN_RIGHT));
m_tActionTransferMap.insert(TStrActionPair(K_STR_TURN_UP,K_TURN_UP));
m_tActionTransferMap.insert(TStrActionPair(K_STR_TURN_DOWN,K_TURN_DOWN));
// Initialize keyboard keys
m_tKeyTransferMap.insert(TStrIntPair(K_STR_ESC,SDLK_ESCAPE));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_A,SDLK_a));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_B,SDLK_b));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_C,SDLK_c));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_D,SDLK_d));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_E,SDLK_e));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F,SDLK_f));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_G,SDLK_g));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_H,SDLK_h));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_I,SDLK_i));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_J,SDLK_j));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_K,SDLK_k));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_L,SDLK_l));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_M,SDLK_m));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_N,SDLK_n));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_O,SDLK_o));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_P,SDLK_p));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_Q,SDLK_q));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_R,SDLK_r));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_S,SDLK_s));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_T,SDLK_t));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_U,SDLK_u));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_V,SDLK_v));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_W,SDLK_w));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_X,SDLK_x));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_Y,SDLK_y));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_Z,SDLK_z));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F1,SDLK_F1));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F2,SDLK_F2));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F3,SDLK_F3));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F4,SDLK_F4));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F5,SDLK_F5));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F6,SDLK_F6));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F7,SDLK_F7));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F8,SDLK_F8));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F9,SDLK_F9));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F10,SDLK_F10));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F11,SDLK_F11));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_F12,SDLK_F12));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_LEFT,SDLK_LEFT));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_RIGHT,SDLK_RIGHT));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_UP,SDLK_UP));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_DOWN,SDLK_DOWN));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_PAGE_DOWN,SDLK_PAGEDOWN));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_PAGE_UP,SDLK_PAGEUP));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_HOME, SDLK_HOME));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_END, SDLK_END));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_INSERT, SDLK_INSERT));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_DELETE, SDLK_DELETE));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_CONSOLE, SDLK_BACKQUOTE));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_ZERO, SDLK_KP0));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_1, SDLK_KP1));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_2, SDLK_KP2));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_3, SDLK_KP3));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_4, SDLK_KP4));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_5, SDLK_KP5));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_6, SDLK_KP6));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_7, SDLK_KP7));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_8, SDLK_KP8));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_9, SDLK_KP9));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_PLUS, SDLK_PLUS));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_MINUS, SDLK_MINUS));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_BACKSPACE, SDLK_BACKSPACE));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_SPACE, SDLK_SPACE));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_ENTER, SDLK_KP_ENTER));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_LSHIFT, SDLK_LSHIFT));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_RSHIFT, SDLK_RSHIFT));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_LCTRL, SDLK_LCTRL));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_RCTRL, SDLK_RCTRL));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_LALT, SDLK_LALT));
m_tKeyTransferMap.insert(TStrIntPair(K_STR_RALT, SDLK_RALT));
}
Do mapy
m_tActionTransferMap
přidáváme jako klíč string hodnotu akcí a jako hodnotu enumerator akcí.
#define K_STR_GO_FORWARD "GoForward"
#define K_STR_GO_BACKWARD "GoBackward"
#define K_STR_GO_UP "GoUp"
#define K_STR_GO_DOWN "GoDown"
#define K_STR_STRAFE_LEFT "StrafeLeft"
#define K_STR_STRAFE_RIGHT "StrafeRight"
#define K_STR_LURCH_LEFT "LurchLeft"
#define K_STR_LURCH_RIGHT "LurchRight"
#define K_STR_TURN_LEFT "TurnLeft"
#define K_STR_TURN_RIGHT "TurnRight"
#define K_STR_TURN_UP "TurnUp"
#define K_STR_TURN_DOWN "TurnDown"
Do mapy
m_tKeyTransferMap
přidáváme jako klíč string hodnotu kláves a jako hodnotu SDL index kláves.
Nyní načteme hodnoty ze souboru K3dEngine.lua . Tutorial jak načítat LUA konfigurační soubory naleznete
zde .
/// \brief Load key map information from K3dEngine file
void CKeyMapBuild::LoadKeyMap()
{
CString strFc = "void COptions::LoadGraphics() -- " ;
CString strOut;
LuaGetGlobal(K_STR_KEY_MAP);
if (!LuaIsTable(- 1 ))
{
strOut = strFc + K_STR_KEY_MAP;
strOut += " is not a valid key map table" ;
LuaError(strOut.GetString().c_str());
}
std::string kStr = LuaGetFieldString(K_STR_GO_FORWARD);
CheckLoadError(kStr, K_STR_GO_FORWARD);
GenerateKeyMap(kStr, K_STR_GO_FORWARD);
kStr = LuaGetFieldString(K_STR_GO_BACKWARD);
CheckLoadError(kStr, K_STR_GO_BACKWARD);
GenerateKeyMap(kStr, K_STR_GO_BACKWARD);
kStr = LuaGetFieldString(K_STR_GO_UP);
CheckLoadError(kStr, K_STR_GO_UP);
GenerateKeyMap(kStr, K_STR_GO_UP);
kStr = LuaGetFieldString(K_STR_GO_DOWN);
CheckLoadError(kStr, K_STR_GO_DOWN);
GenerateKeyMap(kStr, K_STR_GO_DOWN);
kStr = LuaGetFieldString(K_STR_STRAFE_LEFT);
CheckLoadError(kStr, K_STR_STRAFE_LEFT);
GenerateKeyMap(kStr, K_STR_STRAFE_LEFT);
kStr = LuaGetFieldString(K_STR_STRAFE_RIGHT);
CheckLoadError(kStr, K_STR_STRAFE_RIGHT);
GenerateKeyMap(kStr, K_STR_STRAFE_RIGHT);
kStr = LuaGetFieldString(K_STR_LURCH_LEFT);
CheckLoadError(kStr, K_STR_LURCH_LEFT);
GenerateKeyMap(kStr, K_STR_LURCH_LEFT);
kStr = LuaGetFieldString(K_STR_LURCH_RIGHT);
CheckLoadError(kStr, K_STR_LURCH_RIGHT);
GenerateKeyMap(kStr, K_STR_LURCH_RIGHT);
kStr = LuaGetFieldString(K_STR_TURN_LEFT);
CheckLoadError(kStr, K_STR_TURN_LEFT);
GenerateKeyMap(kStr, K_STR_TURN_LEFT);
kStr = LuaGetFieldString(K_STR_TURN_RIGHT);
CheckLoadError(kStr, K_STR_TURN_RIGHT);
GenerateKeyMap(kStr, K_STR_TURN_RIGHT);
kStr = LuaGetFieldString(K_STR_TURN_UP);
CheckLoadError(kStr, K_STR_TURN_UP);
GenerateKeyMap(kStr, K_STR_TURN_UP);
kStr = LuaGetFieldString(K_STR_TURN_DOWN);
CheckLoadError(kStr, K_STR_TURN_DOWN);
GenerateKeyMap(kStr, K_STR_TURN_DOWN);
}
Funkce načítá hodnoty, které předává funkci
GenerateKeyMap(std::string _strKeyMap, std::string _strActionMap)
/// \brief Find from m_tActionTransferMap and m_tKeyTransferMap antion and key indexes and add to the final key map
/// \param _strKeyMap Key map string
/// \param _strActionMap Action map string
void CKeyMapBuild::GenerateKeyMap(std::string _strKeyMap, std::string _strActionMap)
{
bool bActionFound = false ;
bool bKeyFound = false ;
int iKey = 0 ;
EKeyMapAction eAction = K_NUM_ACTION;
if (!m_tActionTransferMap.count(_strActionMap))
{
std::cerr << "void CKeyMapBuild::GenerateKeyMap() -- " << _strActionMap << " doesn`t in action map." << std::endl;
}
else
{
eAction = m_tActionTransferMap[_strActionMap];
bActionFound = true ;
}
if (!m_tKeyTransferMap.count(_strKeyMap))
{
std::cerr << "void CKeyMapBuild::GenerateKeyMap() -- " << _strKeyMap << " doesn`t in key map." << std::endl;
}
else
{
iKey = m_tKeyTransferMap[_strKeyMap];
bKeyFound = true ;
}
if ((bActionFound)&&(bKeyFound))
{
// Insert results to result key map
m_pGameData->GetKeyMap()->InsertKeyMap(eAction, iKey);
}
}
Funkce vyhledá klíč z mapy m_tActionTransferMap , hodnotu z mapy m_tKeyTransferMap . Klíč a hodnotu přidá do výsledné key mapy m_tKeyMap .
/// \brief Inser action key and SDL index key to the key map
void InsertKeyMap(EKeyMapAction _eAction, int _iSDLKey)
{
m_tKeyMap.insert(pair<EKeyMapAction, int >(_eAction, _iSDLKey));
}
Použití keymapy.
Funkce UpdateCamera()
void CCamera::UpdateCamera()
{
// Set descent camera moving
SetDescent( true );
// Get global timer
CTimer *pTimer = m_pGameData->GetTimer();
// Synchronize camera speed
m_fSpeed = m_speedAccelerator;
pTimer->SynchronizeSpeed(m_fSpeed);
// Get global keyboard map pointer
CKeyMap *pKeyMap = m_pGameData->GetKeyMap();
if (pKeyMap->IsKeyPressed(K_GO_FORWARD))
{
GoForward();
}
if (pKeyMap->IsKeyPressed(K_GO_BACKWARD))
{
GoBackward();
}
if (pKeyMap->IsKeyPressed(K_TURN_LEFT))
{
TurnLeft();
}
if (pKeyMap->IsKeyPressed(K_TURN_RIGHT))
{
TurnRight();
}
if (pKeyMap->IsKeyPressed(K_STRAFE_RIGHT))
{
StrafeRight();
}
if (pKeyMap->IsKeyPressed(K_STRAFE_LEFT))
{
StrafeLeft();
}
if (pKeyMap->IsKeyPressed(K_GO_UP))
{
GoUp();
}
if (pKeyMap->IsKeyPressed(K_GO_DOWN))
{
GoDown();
}
if (pKeyMap->IsKeyPressed(K_LURCH_LEFT))
{
LurchLeft();
}
if (pKeyMap->IsKeyPressed(K_LURCH_RIGHT))
{
LurchRight();
}
if (pKeyMap->IsKeyPressed(K_TURN_UP))
{
TurnUp();
}
if (pKeyMap->IsKeyPressed(K_TURN_DOWN))
{
TurnDown();
}
ChangeMatrix();
}
volá funkci IsKeyPressed(EKeyMapAction _eKey) s parametrem akce.
/// \brief Test if is key pressed
bool CKeyMap::IsKeyPressed(EKeyMapAction _eKey)
{
return IsSdlKeyPressed(m_tKeyMap[_eKey]);
}
/// \brief Check if key pressed
/// \retval bool True if key pressed
bool IsSdlKeyPressed( const int _iSDLKey)
{
if (m_puiKeys[_iSDLKey] == SDL_PRESSED)
{
return true ;
}
else
{
return false ;
}
}
Pokud funkce vrací true , klávesa je stisknuta, akce GoForward(), GoBackward(), TurnLeft(), TurnRight() ... se provede.
Instalace a spouštění ukázkového příkladu.
1. Rozbalíme K3dEngine-0-0-4-5.zip .
2. V adresáři K3dEngine/usr/ spustíme v root módu script
./go
3. Program se spustí z adresáře K3dEngine/bin/ příkazem
./K3dApp
Závislosti.
K3dEngine používá následující knihonvy:
lua-devel
http://www.lua.org/
SDL
verze 1.2.10 nebo vyšší
http://www.libsdl.org/index.php
SDL-devel
http://www.libsdl.org/index.php
SDL_image
http://www.libsdl.org/projects/SDL_image/
home
/
opengl game