声明:本文章经由作者本人同意转载到此,如果您有任何问题或意见需要向作者请教,请您到文章的源出处http://blog.sina.com.cn/u/4b7f61c90100076a交流您的意见,谢谢!
开始吧,首先从网上下载Lua(我是5.1.1),Luabind(我是0.7),Hge(我是1.6)和Boost库。由于我用的是VC8,但原来的库是VC6或7编译的,所以需要将这些库的源代码重新编译,得到lib和dll文件。然后按着教程写些代码,链上库,保证能够顺利执行。这里注意几点:
1.luabind似乎应该分别用debug和release模式编译,我得到的是luabindd.lib和luabindr.lib,使用时若是debug模式就链luabindd.lib,release就luabindr.lib
2.VC8取消了单线程模式和以往会不兼容,所以你的工程及依赖的库应该保证编译链接的一致性,就是用同一个编译链接选项。
3.Lua5.1和之前版本有很多不同,具体自己去网上搜。
4.也许还会遇到其他问题,我当时就差点放弃,坚持下来,多试试,遇到不懂的先google再问人。
确认这3个库可以正常工作后就可以开始写游戏了,你还需要做的是找一些参考资料(lua,luabind,hge的官方手册及其他文档)和加入几个相关的技术群,这里推荐"中国HGE"(QQ:14159676)。
建一个Win32工程,把该载的头文件载进去。
// Windows 头文件: #include <windows.h> // C 运行时头文件 #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <tchar.h> //hge头文件 #include <hge.h> #include <hgecolor.h> #include <hgesprite.h> #include <hgedistort.h> #include <hgefont.h> //stl头文件 //lua头文件 extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } //luabind头文件 #include <luabind/luabind.hpp> #include <luabind/object.hpp> #include <luabind/class.hpp> |
由于我的方案是用luabind将hge类及相关函数映射到lua中,所以你需要按照luabind的方法进行包装,要注意的是由于hge类是个虚基类,所以你还得另外写个类对其进行包装。映射函数时注意参数或返回值为指针的情况,还有不定参数,都是不行的。
Bind.h
namespace tg { namespace Bind { //绑定hge void Bind_HgeSys(lua_State* L); //绑定hgeFont void Bind_HgeFont(lua_State* L); //绑定hgeSprite void Bind_HgeSprite(lua_State* L); } } |
Bind.cpp
//绑定hge void Bind::Bind_HgeSys(lua_State* L) { module(L) [ class_<HgeSys>("HgeSys") .def(constructor<>()) .scope [ def("System_Start",&HgeSys::System_Start), def("System_SetStateBool", &HgeSys::System_SetStateBool), def("System_SetStateInt", &HgeSys::System_SetStateInt), def("System_SetStateString", &HgeSys::System_SetStateString), //def("Resource_Load",&HgeSys::Resource_Load), //这两个有问题 //def("Resource_Free",&HgeSys::Resource_Free), def("Resource_AttachPack",&HgeSys::Resource_AttachPack), ...... ] ]; } //绑定hgeFont void Bind::Bind_HgeFont(lua_State* L) { module(L) [ class_<hgeFont>("HgeFont") .def(constructor<const char*>()) .def(constructor<const hgeFont&>()) .def("Render",&hgeFont::Render) ...... ]; } //绑定hgeSprite void Bind::Bind_HgeSprite(lua_State* L) { module(L) [ class_<hgeSprite>("HgeSprite") .def(constructor<HTEXTURE,float, float, float, float>()) .def(constructor<const hgeSprite&>()) .def("Render",&hgeSprite::Render) ...... ]; } |
注意,这里我绑定的是HgeSys而非Hge类,因为Hge是个虚基类,不能直接用luabind,所以在其上包装了一层。
HgeSys.h
namespace tg { class HgeSys { public: HgeSys(); ~HgeSys(); static void System_Start(); //启动hge循环 //设置hge状态 static void System_SetStateBool(hgeBoolState state, bool value); static void System_SetStateInt(hgeIntState state, int value); static void System_SetStateString(hgeStringState state, const char* value); //其他函数 //HGE interface static HGE* hge; }; } |
还得建一个脚本引擎类来负责lua脚本的打开,初始化,执行等。
//ScriptEngine.h namespace tg { class ScriptEngine { public: ScriptEngine(); ~ScriptEngine(); void Init(); //初始化 void Release(); //结束 bool Render(); //图像绘制 bool Update(); //消息处理和逻辑更新 private: lua_State* L; }; } //---------------ScriptEngine.cpp里--------------------- //构造函数 ScriptEngine::ScriptEngine() { L = luaL_newstate(); lua_cpcall(L, luaopen_base, 0); lua_cpcall(L, luaopen_io, 0); lua_cpcall(L, luaopen_string, 0); lua_cpcall(L, luaopen_table, 0); lua_cpcall(L, luaopen_math, 0); lua_cpcall(L, luaopen_debug, 0); lua_cpcall(L, luaopen_os, 0); open(L); //邦定C++到Lua Bind::Bind_HgeSys(L); Bind::Bind_HgeFont(L); Bind::Bind_HgeSprite(L); Bind::Bind_DebugConsole(L); int s = luaL_loadfile(L, "Script//GameInit.lua"); if ( s==0 ) { s = lua_pcall(L, 0, LUA_MULTRET, 0); //启动lua初始文件 } } //析构函数 ScriptEngine::~ScriptEngine() { lua_close(L); } //初始化 void ScriptEngine::Init() { luabind::call_function<void>(L,"EngineInit"); //脚本引擎初始化 } //结束 void ScriptEngine::Release() { luabind::call_function<void>(L,"EngineRelease"); //脚本引擎结束 } //图像绘制 bool ScriptEngine::Render() { return luabind::call_function<bool>(L,"EngineRender"); } //消息处理和逻辑更新 bool ScriptEngine::Update() { return luabind::call_function<bool>(L,"EngineUpdate"); } |
C++部分还剩下的就是main函数了,这里建立了HgeSys,ScriptEngine的对象,绑定RenderFunc和FrameFunc函数到Hge,然后启动Hge,执行相关函数。。
#include "stdafx.h" #include "HgeSys.h" #include "ScriptEngine.h" #include "DebugConsole.h" using namespace tg; DebugConsole debugConsole; //这个是开console窗口调试用的 tg::HgeSys hgeSys; //封装Hge接口的类 tg::ScriptEngine scriptEngine; //脚本引擎 / bool FrameFunc() { return scriptEngine.Update(); } bool RenderFunc() { // Render scene HgeSys::hge->Gfx_BeginScene(); scriptEngine.Render(); HgeSys::hge->Gfx_EndScene(); return false; } //Main int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { HgeSys::hge->System_SetState(HGE_FRAMEFUNC, FrameFunc); HgeSys::hge->System_SetState(HGE_RENDERFUNC, RenderFunc); if(HgeSys::hge->System_Initiate()) { scriptEngine.Init(); //脚本引擎初始化 HgeSys::hge->System_Start(); //hge执行,进入游戏引擎循环 scriptEngine.Release(); //脚本引擎结束 } return 0; } |
最后说下Lua部分,我的是GameInit.lua进行初始化工作,GameEngine.lua是游戏6引擎部分,也有Init,Render,Update,Release等方法。
------------GameInit.lua--------------------- ---------------------初始化hge状态--------------------------------- HgeSys.System_SetStateString(16, "GameEngine.log") --HGE_LOGFILE HgeSys.System_SetStateString(7, "GameEngine") --HGE_TITLE HgeSys.System_SetStateBool(18, false) --HGE_USESOUND HgeSys.System_SetStateBool(11, true) --HGE_WINDOWED HgeSys.System_SetStateBool(25, false) --HGE_HIDEMOUSE HgeSys.System_SetStateInt(8, 800) --HGE_SCREENWIDTH HgeSys.System_SetStateInt(9, 600) --HGE_SCREENHEIGHT HgeSys.System_SetStateInt(10, 32) --HGE_SCREENBPP ---------------------游戏引擎------------------------------------- dofile("Script//GameEngine.lua") gameEngine = GameEngine() --全局游戏引擎对象 ---------------------Globa function--------------------------------游戏引擎初始化,由C++调用 function EngineInit() gameEngine:Init() end --绘制图像 function EngineRender() return gameEngine:Render() end --消息处理和逻辑更新 function EngineUpdate() return gameEngine:Update() end --资源释放 function EngineRelease() gameEngine:Release() end |
----------GameEngine.lua游戏引擎,由Hge调用------------------- class 'GameEngine' --这种语法是需要luabind才能写的! function GameEngine:__init() end function GameEngine:Init() --初始化 end function GameEngine:Render() --图像绘制 return false end function GameEngine:Update() --消息处理 & 逻辑更新 return false end function GameEngine:Release() --资源释放 end |
本来还有很多,但一一贴出来太杂,还不如去直接看源代码,可以到我E盘上下载:
http://free.ys168.com/?sftk 程序还很粗糙,还望见谅,需要交流的话可加我QQ