English

OpenGL game

Volání fukcí herního enginu z Lua skriptu.

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

20.11.2006

Vytvoříme Lua skript funkci
int K3d_GetSphere(const char* _strName)
která bude volat fukci herního enginu
int K3dSphereBuild::FindSphereId(const char* _strName)
Funkce vrátí index koule podle jména
_strName

1. Načteme mapovací soubor

numvertices=0
numfaces=0
numblocks=0
num2dimages=0
numspheres=1
numlines=0
numplanes=0
numcameras=1
activecameraid=0

--Spheres
sphere0=
{
	name="BoundSphere",
	pos_x=0.0,
	pos_y=200.0,
	pos_z=300.0,
	radius=64,
	r=0,
	g=255,
	b=0,
	num_slices=20,
	num_stacks=20
}

--Cameras
camera0=
{
	name="MainCamera",
	pos_x=0.0,
	pos_y=0.0,
	pos_z=1024.0,
	rot_x=0.0,
	rot_y=0.0,
	rot_z=0.0,
	mousemove=false,
	descent=false,
	firstperson=false,
	spectate=true,
	speed=600.0
}



Tutorial, jak načíst mapovací soubor najdete zde.

2. Vytvoříme (virtual machine) třídu

class K3dVM
{
	static K3dLua *ms_pLua;
	static K3dGameData *ms_pGameData;	///< Global game data, data centered game system
	static K3dScene *ms_pScene;
	static K3dSphereBuild *ms_pSphereBuild;	///< Pointer to sphere build object for find sphere index from sphere name
	static void *ms_pObject;	///< Pointer to some void
	
	static int K3d_GetSphere(lua_State *_pState);
	int GetSphere(const char* _strName);	

	public:
		K3dVM(K3dGameData *_pGameData, K3dScene *_pScene);
		K3dVM(){}
		~K3dVM();
		
		void RegisterFunctions();
		void LoadScript(K3dString _strFilename);
		void LF_Init();
		void LF_Update();
		void LF_Delete();
};


3. V konstruktoru této třídy

K3dVM::K3dVM(K3dGameData *_pGameData, K3dScene *_pScene)
{
	ms_pGameData = _pGameData;
	ms_pScene = _pScene;
	ms_pLua = new K3dLua();
	ms_pSphereBuild = new K3dSphereBuild(_pGameData);
	RegisterFunctions();
}


3.1 Připojíme Lua skriptovací jazyk
ms_pLua = new K3dLua();
(volá se konstruktor třídy
K3dLua)

K3dLua::K3dLua()
{
	// Open Lua
	m_pLua = lua_open();
	luaopen_base(m_pLua);
	luaopen_table(m_pLua);
	luaopen_io(m_pLua);
	luaopen_string(m_pLua);
	luaopen_math(m_pLua);
}



3.2 Voláme funkci
RegisterFunctions();
ve které zaregistrujeme naší funkci
K3d_GetSphere

///\brief Register script functions
void K3dVM::RegisterFunctions()
{
	std::cout << "void K3dVM::RegisterFunctions()" << endl;
	ms_pLua->LuaRegister("K3d_GetSphere", K3d_GetSphere);
}


///\brief Sets the C function _f as the new value of global _strName
///\param _strName Function name
///\param _f Global function
void K3dLua::LuaRegister( const char *_strName, lua_CFunction _f)
{
	lua_register(m_pLua, _strName, _f);
}


4. Napíšeme jednoduchý Lua skript, který volá naší funkci
K3d_GetSphere

g_iSphere = -1
g_iSphere = K3d_GetSphere("BoundSphere")
print("g_iSphere =", g_iSphere)
if g_iSphere == -1 then
	print("BoundSphere doesn`t exists.")
end


4.1 Jednoduchý Lua skript uložíme jako soubor
test_script.lua

5. Pokud je naše funkce zaregistrovaná, bude se automaticky volat stejná statická funkce VM (virtual machine) třídy

///\brief Script function calling GetSphere function
int K3dVM::K3d_GetSphere(lua_State *_pState)
{
	// Cast the void pointer
	K3dVM *pSomeClass = (K3dVM*)ms_pObject;
	// Get function parameter
	const char* strParam = (const char*) lua_tostring(_pState, 1); 
	// Try call non static function
	int iResult = pSomeClass->GetSphere(strParam);
	 // Push result into script function
	lua_pushnumber(_pState, iResult);
	// Return number of results
	return 1;
}


5.1 Protože je funkce statická a budeme volat nestatickou funkci, přetypujeme ukazatel void na třídu K3dVM

	K3dVM *pSomeClass = (K3dVM*)ms_pObject;



5.2 Získáme první parametr skriptovací funkce, což je název koule

	const char* strParam = (const char*) lua_tostring(_pState, 1); 



5.3 Voláme nestatickou funkci GetSphere přetypované třídy K3dVM s parametrem názvu koule.

	int iResult = pSomeClass->GetSphere(strParam);



5.3.1 Funkce GetSphere najde a vrací index koule podle názvu koule. Pokud název nesouhlasí funkce vrací index -1

///\brief Get sphere index from game data
///\param _strName Sphere name
///\retval int Sphere index. If return -1, then doesn`t exist current sphere
int K3dVM::GetSphere(const char* _strName)
{
	// Find sphere index by sphere name
	int iId = ms_pSphereBuild->FindSphereId(_strName);
	return iId;
}



///\brief Find sphere index in global sphere data by sphere name
int K3dSphereBuild::FindSphereId(const char* _strName)
{
	K3dString strName(_strName);
	for(int i=0; i<m_pGameData->GetNumSpheres(); i++)
	{
		K3dSphereObj *pSphere = m_pGameData->GetSphere(i);
		if(strName == pSphere->GetName())
		{
			return i;
		}
	}
	return -1;
}


6. Spustíme skript voláním VM funkce
LoadScript
s parametrem
test_script.lua

///\brief Global virtual machine
K3dVM *g_pVM;

///\brief Init engine
bool Init()
{
	...
	...
	// Create virtual machine
	g_pVM = new K3dVM(g_pGameData, g_pScene);
	g_pVM->LoadScript("test_script.lua");
	...
	...
	return true;
}


///\brief Load script 
void K3dVM::LoadScript(K3dString _strFilename)
{
	std::cout << "void K3dVM::LoadScript()" << endl;
	std::cout << "_strFilename = " << _strFilename.GetString( ) << endl;
	// Test calling my function from Lua
	int error = ms_pLua->LuaLoadFile( _strFilename.GetString().c_str());
	if (!error) 
	{
		error = ms_pLua->LuaPCall(0, 0, 0);
	}
	if (error) 
	{
		const char *message = lua_tostring(ms_pLua->GetLuaState(), -1);
		ms_pLua->LuaError(message);
	}
}


6.1 Funkce zkusí otevřít soubor
test_script.lua

	int error = ms_pLua->LuaLoadFile( _strFilename.GetString().c_str());


///\brief Load lua script file
///\param _strFilename Filename string
///\retval int Positive value, if file correctly loaded 
int K3dLua::LuaLoadFile(const char *_strFilename)
{
	return luaL_loadfile(m_pLua, _strFilename);
}


6.2 Pokud se soubor podaří otevřít, spustíme skript voláním funkce LuaPCall s nulovými parametry

	error = ms_pLua->LuaPCall(0, 0, 0);


///\brief Call lua script
///\param _iNumArgs Number of arguments
///\param _iNumResults Number of results
///\param _iErrFunc Error function index
int K3dLua::LuaPCall(const int _iNumArgs,const int _iNumResults,const int _iErrFunc)
{
	return lua_pcall(m_pLua, _iNumArgs, _iNumResults, _iErrFunc);
}



home / opengl game


Valid XHTML 1.0 Transitional