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)
2


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


[Please log in to post a comment]