现在的位置: 首页 > 综合 > 正文

LUA脚本组件系统(一)

2018年02月06日 ⁄ 综合 ⁄ 共 1422字 ⁄ 字号 评论关闭

LUA脚本组件系统

----让LUA成为C++的子集

零 简介

         我们知道C++是一门静态编译执行的语言,其运行效率较高,并且从语法上支持面向对象,但和所有静态语言一样,当类定义好后在运行时就无法改变了,除此之外,c++的语法较复杂,学习代价比较高。

脚本语言LUA是一门动态语言,虽然在普遍情况下运行效率没有c++高,但其运行时可以动态的调整代码,给流程控制提供了很大的灵活性。拥有自动内存管理等特性也使其学习成本较低,使快速原型开发成为可能。

在游戏开发中,一般会用C++来开发游戏引擎的图形渲染,场景管理和物理碰撞等核心部分,而用LUA脚本来完成复杂的逻辑和流程控制。

本文的目的在于实现一种方案从而使LUA和c++紧密地结合在一起,让lua看起来就像是c++的一个子集一样.

本文分为七个部分,第一部分会通过一个代码实例来简要的了解脚本组件系统设计思想.第二部分介绍脚本组件系统产生的背景、动机与意图。第三部分介绍系统相关的基本理论。第四部分通过一个假想的需求实例来进一步说明脚本组件系统的功能和优点。第五部分描述系统的定义和特性。第六部分给出系统的实现方法和相关代码。最后部分给出一个使用脚本组件系统实现连连看游戏的实例。

 

一 脚本组件系统的轮廓

除了语法细节外,我们希望LUA和C++一样可以用来描述相同的对象,也就是说一个对象的一部分可以用c++来描述而另一部分可以用Lua来描述;更通俗一点讲,一个对象的成员变量和函数可以被任意划分放到C++和LUA中,而在使用上没有任何分别.

以对象”圆”为例子用代码来说明,我们可以这样来描述

一个shape.h描述了圆的形状属性,形状可以被绘制出来

Shap.h

class Shape
{
         public:
                   virtual~Shape(){};
                   voidDraw(){};
                   int id;
};

一个circle.lua描述了对象圆的半径,计算面积的方法和绘制方法

Circle.lua

radius = 0;
local PI = 3.14;
function GetArea()
         return radius *this.radius * PI;
end
 
local function DrawCircle()
         super:Draw();
end
 
function Draw()
         DrawCircle();
end

 

基于以上两种语言的描述,在假设我们已经实现了脚本组件系统的情形下,那么我们可以在test.lua文件中这样使用

Test.lua

local c = Shape:new("circle.lua");
c.radius = 0.5;
local area = c.GetArea();
c.Draw();
local id = c.id;

 

这样的用法看起来很诱人和新奇,首先我们用C++的Shape类和circle.lua文件生成了一个圆对象c.通过对象c可以访问C++成员id也可以访问lua的成员变量radius和成员函数GetArea()。其次在调用c.Draw()的实际是通过多态的机制动态的调用了lua中的Draw(即使Shape的Draw函数不是虚函数).再次在circle.lua中也可以通过关键字super使用宿主对象的成员,看起来好像和承继一样,最后在GetArea函数中,我们可以隐藏this关键字,也可以显示的使用this,看起来好像是c++的成员变量和函数被放到lua文件中!这些花招看起来很诱人,但实现这样的系统的动机和意图是什么呢?欲知后事如何,且听下回分解!

抱歉!评论已关闭.