English

OpenGL Linux game

Mapování kláves.

Zdroják ke stažení (541,5kB)

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


Valid XHTML 1.0 Transitional