Log In  

Hi,

here is example how to write lua code more as OOP using metatable and user defined callbacks for update and draw per actor.

Note: Plane sprite is created as sprite 2x1 on sprite id 1 and 2.

--   Actors+Actor CLASSes
-- andygfx - cubesteam - 2016

-- Define TActors container class ---------------------------------------------

TActors = {}

-- TActors CONSTRUCTOR 

function TActors:New() 

    o = { 
            list={}
        } 

    setmetatable(o, self) 
    self.__index = self 

    return o 

end 

-- TActors methods ------------------------------------------------------------

-- add actor to Actors list
function TActors:Add(actor)
    add(self.list,actor)
end

-- delete actor from Actors list
function TActors:Del(actor)
    del(self.list,actor)
end

-- return count of actors in list
function TActors:Count()
    return #self.list
end

-- call user defined update method on all actors in list
function TActors:Update()
    for a in all(self.list) do 
        if a.enable then
            a:update()
        end
    end
end

-- call user defined draw method on all actors in list
function TActors:Draw()
    for a in all(self.list) do 
        if a.enable then
            a:draw()
        end
    end
end

-- Define TActor class --------------------------------------------------------

TActor = {} 

-- TActor CONSTRUCTOR ---------------------------------------------------------

function TActor:New() 

    o = { 
            name="actor",
            enable=true,
            visible=true,
            x = 0, y = 0,
            _x = 0, _y = 0,
            sprite = 0,
            sx = 1, sy = 1,
            dx = 0, dy = 0,
            update = function() end,
            draw = function() end 
        } 

    setmetatable(o, self) 
    self.__index = self 

    return o 

end 

-- METHODS 

-- set actor fields
function TActor:Set(name,sprID,x,y,w,h,dx,dy)
    self.name=name
    self.sprite=sprID
    self.x=x
    self.y=y
    self._x=x
    self._y=y
    self.sx=w
    self.sy=h
    self.dx=dx
    self.dy=dy
end

-- set actor update and draw callback
function TActor:SetCallback(fncUpdate,fncDraw)
    self.update = fncUpdate
    self.draw = fncDraw
end

-- respawn acgtor to start position
function TActor:Respawn()
    self.x=self._x
    self.y=self._y
end

-- pico8 callbacks ------------------------------------------------------------ 

function _init()
end

function _update()
  Actors:Update()
end

function _draw()
  cls()
  Actors:Draw()
end

-- TEST ACTORS ----------------------------------------------------------------

-- create Actors container
Actors=TActors:New()

-- user defined UPDATE callback for actor
function UpdatePlane(self)
    self.x+=self.dx
    self.y+=self.dy

    if self.x>128 then self:Respawn() end

end

-- user defined DRAW callback fro actor
function DrawPlane(self)
    spr(self.sprite,self.x,self.y,self.sx,self.sy)
end

-- create actor#1
plane1 = TActor:New()
plane1:Set("plane1",1,10,20,2,1,1,0)
plane1:SetCallback(UpdatePlane,DrawPlane)

Actors:Add(plane1)

-- create actor#2
plane2 = TActor:New()
plane2:Set("plane2",1,10,35,2,1,2,0)
plane2:SetCallback(UpdatePlane,DrawPlane)

Actors:Add(plane2)

-- create actor#3
plane3 = TActor:New()
plane3:Set("plane3",1,10,50,2,1,3,0)
plane3:SetCallback(UpdatePlane,DrawPlane)

Actors:Add(plane3)
P#25419 2016-07-16 12:20 ( Edited 2016-07-17 03:06)

I notice people don't seem to be aware of this, so I thought I should mention it. setmetatable() returns its first argument. That greatly simplifies the common implementation of new() functions. You can turn this:

function TActors:New() 

    o = { 
            list={}
        } 

    setmetatable(o, self) 
    self.__index = self 

    return o 

end

Into this:

function TActors:New() 

    self.__index = self 
    return setmetatable({ 
            list={}
        }, self) 

end
P#25440 2016-07-16 23:06 ( Edited 2016-07-17 03:06)

[Please log in to post a comment]