- 为什么要在游戏中使用脚本语言?
要解释这个问题首先我们先来了解一下脚本语言的特性:
- 学习门槛低,快速上手
- 开发成本低,可维护性强
- 动态语言,灵活性高
相对于C/C++这类高复杂性、高风险的编译型语言来说,Lua脚本做为一种轻量级的动态语言,简单的语言特性,精简的核心和基础库,使得语言的学习门槛大大的降低,即使是没有任何游戏经验的人都能快速上手,开发游戏功能。实际上游戏设计是一种十分繁杂的工作,C/C++虽然给我们带来极大的高效性,但同时也不能忽视其复杂性,极易产生BUG,而且对于开发人员的要求非常高。从语言的的抽象层面来说C/C++的抽象低更加适合于底层逻辑的支持,而Lua脚本抽象层次高,更加适合游戏逻辑的实现。脚本语言运行在虚拟机之上,而虚拟机运行在游戏逻辑之上,作为一种解释型语言,我们可以随时修改并及时体现在游戏之中,快速完成开发。C/C++却做不到,对一个巨大的游戏工程,每次修改都需要重新编译,成本很高。设想一下,如果所有的功能都是使用C/C++实现的话,那么对开发人员来说简直是一场灾难。
- 如何在游戏中使用Lua脚本?
这里就不理论一大堆了,直接手把手教。
- 进入Lua官方网站下载Source源代码
- 在Visual Studio在新建一个解决方案名为Lua2Game
- 在Lua2Game解决方案下新建一个空项目,命名为LuaDll,将从Lua官网下载的源代码src中除luac.c文件之外的源代码拷贝到LuaDll工程,配置项目属性,常规->配置类型为静态库(lib)然后编译LuaDll项目。(luac.c是编译器,lua.c是解释器也就是lua虚拟机)
- 在Lua2Game解决方案下新建一个空项目,命名为Game,配置项目属性,常规->配置类型为应用程序(.exe), 这就是游戏demo。在项目属性中,链接器-> 输入->附加依赖项中加入../Debug/LuaDll.lib
- 在项目Game中实现脚本引擎CLuaScript(实现C/C++与Lua脚本的互相访问)
LuaScript.h
1 #ifndef __LUA_SCRIPT_H__ 2 #define __LUA_SCRIPT_H__ 3 4 #include "GameDef.h" 5 6 class CLuaScript 7 { 8 public: 9 CLuaScript(); 10 ~CLuaScript(); 11 12 public: 13 //实现C/C++对Lua脚本的调用 14 bool LoadScript(const char* szFileName); //实现lua脚本加载和编译 15 //调用Lua函数 16 bool CallFunction(char* cFuncName, int nResults, char* cFormat, va_list vlist); 17 bool CallFunction(const char* cFuncName, int nResults, char* cFormat, ...); 18 19 private: 20 void RegisterLuaLib(); //注册lua各种基础库 21 bool RegisterFunctions(TLua_Funcs Funcs[], int n);//将游戏接口注册到lua脚本 22 23 private: 24 lua_State* m_LuaState; //state 脚本和CC++搞基就靠它了 25 bool m_IsLoadScript; 26 }; 27 28 29 #endif
LuaScript.cpp
1 #include <iostream> 2 #include "LuaScript.h" 3 4 CLuaScript::CLuaScript() 5 { 6 m_LuaState = luaL_newstate(); 7 if (!m_LuaState) 8 { 9 std::cout << "m_LuaState new state failed!" << std::endl; 10 return; 11 } 12 RegisterLuaLib();//注册lua标准库 13 RegisterFunctions(g_GameFunc, g_GetGameFuncSize());//注册cc++脚本接口 14 m_IsLoadScript = false; 15 } 16 17 CLuaScript::~CLuaScript() 18 { 19 if (m_LuaState) 20 { 21 lua_close(m_LuaState); 22 m_LuaState = NULL; 23 } 24 m_IsLoadScript = false; 25 } 26 27 void CLuaScript::RegisterLuaLib() 28 { 29 if (!m_LuaState) 30 { 31 return; 32 } 33 luaL_openlibs(m_LuaState); 34 } 35 36 bool CLuaScript::RegisterFunctions(TLua_Funcs Funcs[], int n) 37 { 38 if (!m_LuaState) 39 { 40 return false; 41 } 42 for (int i = 0; i < n; i++) 43 lua_register(m_LuaState, Funcs[i].name, Funcs[i].func); 44 return true; 45 } 46 47 bool CLuaScript::LoadScript(const char* szFileName) 48 { 49 if (!szFileName || szFileName[0] == '