Difference between revisions of "Tuto tiny-ecs beatemup Part 9 Systems"

From GiderosMobile
(wip)
 
(wip)
 
Line 1: Line 1:
 
__TOC__
 
__TOC__
  
== The last ones ==
+
== The Systems ==
We have two entities left to make. Some breakable objects entities which will spawn collectible entities.
+
We have our entities, we have our components, now the systems. What is an ECS '''System'''?
  
As I have mentioned before components are shared amongst entities and this is exactly the case here too. The breakable objects and the collectibles share the same components as our previous actors and the structure is almost the same as well.
+
A System is a wrapper around function callbacks for manipulating Entities. Systems are implemented as tables that contain at least one method; an update function that takes parameters like so:
 +
 +
'''function system:update(dt)'''
 +
 +
There are also a few other optional callbacks:
 +
*'''function system:filter(entity)''' Returns true if this System should include this Entity, otherwise should return false. If this isn't specified, no Entities are included in the System.
 +
*'''function system:onAdd(entity)''' Called when an Entity is added to the System.
 +
*function system:onRemove(entity)''' Called when an Entity is removed from the System.
 +
*'''function system:onModify(dt)''' Called when the System is modified by adding or removing Entities from the System.
 +
*'''function system:onAddToWorld(world)''' Called when the System is added to the World, before any entities are added to the system.
 +
*'''function system:onRemoveFromWorld(world)''' Called when the System is removed from the world, after all Entities are removed from the System.
 +
*'''function system:preWrap(dt)''' Called on each system before update is called on any system.
 +
*'''function system:postWrap(dt)''' Called on each system in reverse order after update is called on each system.
 +
 +
'''Please see [[Tiny-ecs#System_functions]] for more information'''
  
== eDestructibleObject.lua ==
+
That looks scary but worry not we won't use all the callback functions :-)
'''Excuse my english, I am not an english native speaker. I called the breakable objects destructibles!'''
 
  
Please create a file "'''eDestructibleObject.lua'''" in the '''"_E"''' folder and the code:
+
To put it simple a '''System''' manipulates entities. Let's see our first '''System'''.
 +
 
 +
== sDrawable.lua ==
 +
Please create a file "'''sDrawable.lua'''" in the '''"_S"''' folder and the code:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
EDestructibleObject = Core.class()
+
SDrawable = Core.class()
 +
 
 +
function SDrawable:init(xtiny) -- tiny function
 +
xtiny.system(self) -- called only once on init (no update)
 +
end
 +
 
 +
function SDrawable:filter(ent) -- tiny function
 +
return ent.spritelayer and ent.sprite
 +
end
 +
 
 +
function SDrawable:onAdd(ent) -- tiny function
 +
-- print("SDrawable:onAdd(ent)")
 +
ent.spritelayer:addChild(ent.sprite)
 +
end
  
function EDestructibleObject:init(xspritelayer, xpos)
+
function SDrawable:onRemove(ent) -- tiny function
-- ids
+
-- print("SDrawable:onRemove(ent)")
self.isdestructibleobject = true
+
ent.spritelayer:removeChild(ent.sprite)
-- sprite layer
+
-- cleaning?
self.spritelayer = xspritelayer
+
ent.sprite = nil
-- params
+
ent = nil
self.pos = xpos
 
self.positionystart = self.pos.y -- for sprite sorting
 
self.sx = 1
 
self.sy = self.sx
 
self.flip = math.random(100)
 
if self.flip > 50 then self.flip = 1
 
else self.flip = -1
 
end
 
self.totallives = 1
 
self.totalhealth = 2
 
if g_difficulty == 0 then -- easy
 
self.totalhealth *= 0.5
 
end
 
self.currlives = self.totallives
 
self.currhealth = self.totalhealth
 
-- recovery
 
self.washurt = 0
 
self.wasbadlyhurt = 0
 
self.recovertimer = 10
 
self.hitfx = Bitmap.new(Texture.new("gfx/fx/1.png"))
 
self.hitfx:setAnchorPoint(0.5, 0.5)
 
-- COMPONENTS
 
-- ANIMATION: CAnimation:init(xspritesheetpath, xcols, xrows, xanimspeed, xoffx, xoffy, sx, sy)
 
local texpath = "gfx/breakable/Barrel_02_0012.png"
 
local framerate = 1
 
self.animation = CAnimation.new(texpath, 1, 1, framerate, 0, 0, self.sx, self.sy)
 
self.sprite = self.animation.sprite
 
self.sprite:setScale(self.sx*self.flip, self.sy) -- for the flip
 
self.animation.sprite = nil -- free some memory
 
self.w, self.h = self.sprite:getWidth(), self.sprite:getHeight()
 
-- create animations: CAnimation:createAnim(xanimname, xstart, xfinish)
 
self.animation:createAnim(g_ANIM_DEFAULT, 1, 1)
 
self.animation:createAnim(g_ANIM_IDLE_R, 1, 1)
 
-- clean up
 
self.animation.myanimsimgs = nil
 
-- BODY: CBody:init(xspeed, xjumpspeed)
 
self.body = CBody.new(0, 0) -- xspeed, xjumpspeed
 
self.body.defaultmass = 1
 
self.body.currmass = self.body.defaultmass
 
-- COLLISION BOX: CCollisionBox:init(xcollwidth, xcollheight)
 
local collw, collh = self.w*1, 8*self.sy
 
self.collbox = CCollisionBox.new(collw, collh)
 
-- hurt box
 
local hhbw, hhbh = self.w, 1*self.h/2
 
self.headhurtbox = {
 
isactive=false,
 
x=0*self.sx,
 
y=-self.h+hhbh*0.5+self.collbox.h/2,
 
w=hhbw,
 
h=hhbh,
 
}
 
local shbw, shbh = self.w, 3*self.h/4
 
self.spinehurtbox = {
 
isactive=false,
 
x=0*self.sx,
 
y=self.collbox.h/2-shbh/2,
 
w=shbw,
 
h=shbh,
 
}
 
-- SHADOW: CShadow:init(xparentw, xshadowsx, xshadowsy)
 
self.shadow = CShadow.new(self.w*1.1)
 
 
end
 
end
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The main differences:
+
XXX
* it is a single frame animation
 
* no attacks
 
* no AI
 
 
 
Once a breakable object is destroyed by the player, it spawns a collectible.
 
  
 
== eCollectible.lua ==
 
== eCollectible.lua ==
 
"'''eCollectible.lua'''" in the '''"_E"''' folder. The code:
 
"'''eCollectible.lua'''" in the '''"_E"''' folder. The code:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
ECollectible = Core.class()
 
 
function ECollectible:init(xspritelayer, xpos)
 
-- ids
 
self.iscollectible = true
 
-- sprite layer
 
self.spritelayer = xspritelayer
 
-- params
 
self.pos = xpos
 
self.positionystart = self.pos.y -- for sprite sorting
 
self.sx = 1
 
self.sy = self.sx
 
self.flip = math.random(100)
 
if self.flip > 80 then self.flip = 1
 
else self.flip = -1
 
end
 
self.totallives = 1
 
self.currlives = self.totallives
 
-- COMPONENTS
 
-- ANIMATION: CAnimation:init(xspritesheetpath, xcols, xrows, xanimspeed, xoffx, xoffy, sx, sy)
 
local texpath = "gfx/collectible/Dragon Eggs 1.png"
 
local framerate = 1
 
self.animation = CAnimation.new(texpath, 1, 1, framerate, 0, 0, self.sx, self.sy)
 
self.sprite = self.animation.sprite
 
self.sprite:setScale(self.sx*self.flip, self.sy)
 
self.animation.sprite = nil -- free some memory
 
self.w, self.h = self.sprite:getWidth(), self.sprite:getHeight()
 
-- create animations: CAnimation:createAnim(xanimname, xstart, xfinish)
 
self.animation:createAnim(g_ANIM_DEFAULT, 1, 1)
 
self.animation:createAnim(g_ANIM_IDLE_R, 1, 1)
 
-- clean up
 
self.animation.myanimsimgs = nil
 
-- BODY: CBody:init(xspeed, xjumpspeed)
 
self.body = CBody.new(0, 0) -- xspeed, xjumpspeed
 
self.body.defaultmass = 1
 
self.body.currmass = self.body.defaultmass
 
-- COLLISION BOX: CCollisionBox:init(xcollwidth, xcollheight)
 
local collw, collh = self.w*0.6, self.h*0.6
 
self.collbox = CCollisionBox.new(collw, collh)
 
-- SHADOW: CShadow:init(xparentw, xshadowsx, xshadowsy)
 
self.shadow = CShadow.new(self.w*0.75)
 
-- IDEA: CREATE AN OSCILLATION COMPONENT using body xspeed, xjumpspeed!
 
end
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Latest revision as of 00:22, 21 November 2024

The Systems

We have our entities, we have our components, now the systems. What is an ECS System?

A System is a wrapper around function callbacks for manipulating Entities. Systems are implemented as tables that contain at least one method; an update function that takes parameters like so:

function system:update(dt)

There are also a few other optional callbacks:
*function system:filter(entity) Returns true if this System should include this Entity, otherwise should return false. If this isn't specified, no Entities are included in the System.
*function system:onAdd(entity) Called when an Entity is added to the System.
*function system:onRemove(entity) Called when an Entity is removed from the System.
*function system:onModify(dt) Called when the System is modified by adding or removing Entities from the System.
*function system:onAddToWorld(world) Called when the System is added to the World, before any entities are added to the system.
*function system:onRemoveFromWorld(world) Called when the System is removed from the world, after all Entities are removed from the System.
*function system:preWrap(dt) Called on each system before update is called on any system.
*function system:postWrap(dt) Called on each system in reverse order after update is called on each system.

Please see Tiny-ecs#System_functions for more information

That looks scary but worry not we won't use all the callback functions :-)

To put it simple a System manipulates entities. Let's see our first System.

sDrawable.lua

Please create a file "sDrawable.lua" in the "_S" folder and the code:

SDrawable = Core.class()

function SDrawable:init(xtiny) -- tiny function
	xtiny.system(self) -- called only once on init (no update)
end

function SDrawable:filter(ent) -- tiny function
	return ent.spritelayer and ent.sprite
end

function SDrawable:onAdd(ent) -- tiny function
--	print("SDrawable:onAdd(ent)")
	ent.spritelayer:addChild(ent.sprite)
end

function SDrawable:onRemove(ent) -- tiny function
--	print("SDrawable:onRemove(ent)")
	ent.spritelayer:removeChild(ent.sprite)
	-- cleaning?
	ent.sprite = nil
	ent = nil
end

XXX

eCollectible.lua

"eCollectible.lua" in the "_E" folder. The code:

You get the idea ;-)

We are done making all our entities!!!

Next?

The time has come to tackle the systems. I will try to make it easy :-)


Prev.: Tuto tiny-ecs beatemup Part 8 Breakables
Next: Tuto tiny-ecs beatemup Part 10 XXX


Tutorial - tiny-ecs beatemup