Topic: Make Lua Classes and Libraries(Tutorial)

Did you know that you can use more than one script at the same time using the dofile() function?
http://wiki.maratis3d.org/index.php?title=Dofile

Did you know also that you can fake Object Oriented Programming in Lua?
http://forum.maratis3d.com/viewtopic.php?id=839

In this post, I will be documenting how I will use these two things to create a class library that you can import into any game:

The first thing I do is figure out what will be the names of my classes. I also comment on what the classes are used for.

CLASSES
function newAnimation()
function newCutScene()
function newCharacter()
function newProp()
function newMenu()
function newLevel()
function newSound()
function newLight()
function newMotion()
function newCloth()
function newSense()
function newCamera()

The next thing I do is make some psuedo-code to show how it can be used.

IMPLEMENTATION
cut_scene = newCutScene()
cut_scene:Commence()
cut_scene:Conclude()

level1 = newLevel()
level1:Launch()
level1:Finish()

prop1 = newProp()
prop1:Build(couch)
prop1:Destroy()

menu1 = newMenu()
menu1:Start()
menu1:End()

light1 = newLight()
light1:On()
light1:Off()

sound1 = newSound()
sound1:Play()
sound1:Stop()

animation1 = newAnimation()
animation1:Begin()
animation1:End()

character1 = newCharacter()
character1:Live()
character1:Die()

camera1 = newCamera()
camera1:Roll()
camera1:Cut()

Notice how I used SYNONYMS and ANTONYMS to distinguish the class functions from one another. This is my Class Template:

TEMPLATE
--[[Class Template
    function Person(name,age)
            local object = {}
            
            object.name = name
            object.age = age
            
            function object:sayName()
                print (object.name)
            end    
                
            return object
        end

--Create Joe
local joe = Person("Joe",24)

--Create Bill
local bill = Person("Bill",25)

--Print Joe's name
print (joe.name)

--Make Bill say his name
bill:sayName()]]

I am going to use this template to turn these classes into actual classes. But first, I am going to dig through the Maratis API to see what Maratis functions I can use to make these classes work like their title implies:
API

--CUTSCENE API
--changeCurrentCamera(object)
--getCurrentCamera()
--getCameraClearColor(object)
--getCameraFov(object)
--getCameraNear(object)
--getCameraFar(object)
--getCameraFogDistance(object)
--isCameraOrtho(object)
--isCameraFogEnabled(object)
--setCameraClearColor(object, {r, g, b})
--setCameraFov(object, fov)
--setCameraNear(object, near)
--setCameraFar(object, far)
--setCameraFogDistance(object, fogDistance)
--enableCameraOrtho(object, ortho)
--enableCameraFog(object, fog)
--enableCameraLayer(object, scene)
--disableCameraLayer(object)
--enableRenderToTexture(object, "textureName", renderWith, renderHeight)
--disableRenderToTexture(object)
--***getProjectedPoint(object, point)
--***getUnProjectedPoint(object, point)
--getScene("sceneName")
--getScenesNumber()

--ANIMATION API
--changeAnimation(object, animationId)
--setAnimationSpeed(object,speed)

--PROP API
--vec3(x, y, z)
--getObject(« objectName »)
--getParent(object)
--getChilds(object)
--getClone(object)
--setParent(object, parent)
--getName(object)
--activate(object)
--deactivate(object)
--isVisible(object)
--isActive(object)
--rotate(object, {x, y, z}, angle, "local")
--translate(object, {x, y, z}, "local")
--getPosition(object)
--getRotation(object)
--getScale(object)
--setPosition(object, {x, y, z})
--setRotation(object, {x, y, z})
--setScale(object, {x, y, z})

--MENU API
--setText(object , "text")
--getText(object)
--getTextColor(object)
--setTextColor(object, {r, g, b, a})
--getScene("sceneName")
--changeScene(scene)
--getCurrentSceneId()
--getScenesNumber()

--LEVEL API
--loadLevel("levels/myLevel.level")

--CHARACTER API (SubClass of Animation class?)
--vec3(x, y, z)
--getObject(« objectName »)
--changeAnimation(object, animationId)
--activate(object)
--deactivate(object)
--isVisible(object)
--isActive(object)

--LIGHT API
--getLightColor(object)
--getLightRadius(object)
--getLightIntensity(object)
--getLightShadowQuality(object)
--getLightShadowBias(object)
--getLightShadowBlur(object)
--getLightSpotExponent(object)
--setLightColor(object, {r, g, b})
--setLightRadius(object, radius)
--setLightIntensity(object, intensity)
--setLightShadowQuality(object, quality)
--setLightShadowBias(object, bias)
--setLightShadowBlur(object, blur)
--setLightSpotAngle(object, spotAngle)
--setLightSpotExponent(object, exponent)

--CAMERA API
--changeCurrentCamera(object)
--getCurrentCamera()
--getCameraClearColor(object)
--getCameraFov(object)
--getCameraNear(object)
--getCameraFar(object)
--getCameraFogDistance(object)
--isCameraOrtho(object)
--isCameraFogEnabled(object)
--setCameraClearColor(object, {r, g, b})
--setCameraFov(object, fov)
--setCameraNear(object, near)
--setCameraFar(object, far)
--setCameraFogDistance(object, fogDistance)
--enableCameraOrtho(object, ortho)
--enableCameraFog(object, fog)
--enableCameraLayer(object, scene)
--disableCameraLayer(object)
--enableRenderToTexture(object, "textureName", renderWith, renderHeight)
--disableRenderToTexture(object)
--getProjectedPoint(object, point)
--getUnProjectedPoint(object, point)

Now I am going to do one class at a time. I will do the most useful one first (refer to the template and API list) and fill it in with the neccessary API functions:

CREATE A CLASS
--Prop Class
    function newProp(x)
        local object = {}
        
        --Variables:
        prop = getClone(x)
        object.name = getName(prop)
        object.location = getPosition(prop)
        scale = 1
        object.scale = scale
        
        
        
        --Methods:
        function object:Build()
            activate(prop)
        end
        
        function object:Destroy()
            deactivate(prop)
        end
        
        function object:Scale(scale)
            setScale(prop, {scale, scale, scale})
        end
        
        return object
    end
chair = getObject("Chair")

chair1 = newProp(chair)
chair1.Build()
chair1.Destroy()
chair1.Scale(2)

Now I need to test this class out on an object...

--Prop Class
    function newProp(x)
        local object = {}
        
        --Variables:
        prop = getClone(x)
        object.name = getName(prop)
        object.location = getPosition(prop)
        scale = 1
        object.scale = scale
        
        
        
        --Methods:
        function object:Build()
            activate(prop)
        end
        
        function object:Destroy()
            deactivate(prop)
        end
        
        function object:Scale(scale)
            setScale(prop, {scale, scale, scale})
        end
        
        return object
    end
    
monkey = getObject("Monkey")
deactivate(monkey)

monkey1 = newProp(monkey)
monkey1:Build()
--monkey1:Destroy()
monkey1:Scale(2)
IT WORKS!

I named this file PropsClass.lua and put it in my scripts folder.
I created another empty file called Game.lua and put it in the same scripts folder.

If I want to use the class I wrote in the PropClass.lua file I just do it this way:

 dofile("PropClass.lua")

Then I can use it in the Game.lua file like this:

 
 dofile("PropClass.lua")

monkey = getObject("Monkey")
deactivate(monkey)

monkey1 = newProp(monkey)
monkey1:Build()
monkey1:Destroy()
monkey1:Scale(1)

Last edited by Tutorial Doctor (2014-03-08 18:22:13)