Difference between revisions of "Tuto tiny-ecs beatemup Part 11 Systems 3"
(wip) |
(wip) |
||
Line 1: | Line 1: | ||
__TOC__ | __TOC__ | ||
− | == The Systems | + | == The Systems 3 == |
− | + | A couple more systems to add and we are done. Those systems apply on the breakable objects and the collectibles. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | == | + | == sDestructibleObjects.lua == |
− | + | Please create a file "'''sDestructibleObjects.lua'''" in the '''"_S"''' folder and the code: | |
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
− | + | SDestructibleObjects = Core.class() | |
− | function | + | local random, cos, sin = math.random, math.cos, math.sin |
− | xtiny.processingSystem(self) -- called once on init and every | + | local insert = table.insert |
− | self. | + | |
− | self.channel = self. | + | function SDestructibleObjects:init(xtiny, xbworld) -- tiny function |
+ | self.tiny = xtiny -- ref so we can remove entities from tiny system | ||
+ | self.tiny.processingSystem(self) -- called once on init and every update | ||
+ | self.bworld = xbworld | ||
+ | -- sfx | ||
+ | self.snd = Sound.new("audio/sfx/footstep/Forest02.wav") | ||
+ | self.channel = self.snd:play(0, false, true) | ||
end | end | ||
− | function | + | function SDestructibleObjects:filter(ent) -- tiny function |
− | return ent. | + | return ent.isdestructibleobject |
end | end | ||
− | function | + | function SDestructibleObjects:onAdd(ent) -- tiny function |
end | end | ||
− | function | + | function SDestructibleObjects:onRemove(ent) -- tiny function |
− | ent. | + | -- spawn a random collectible: ECollectible:init(xspritelayer, xpos) |
+ | local function fun() | ||
+ | local el = ECollectible.new(ent.spritelayer, ent.pos+vector(ent.collbox.w/4, -1*ent.collbox.h)) | ||
+ | self.tiny.tworld:addEntity(el) | ||
+ | self.bworld:add(el, el.pos.x, el.pos.y, el.collbox.w, el.collbox.h) | ||
+ | Core.yield(1) | ||
+ | end | ||
+ | Core.asyncCall(fun) | ||
+ | self.bworld:remove(ent) -- remove collision box from cbump world here! | ||
end | end | ||
− | + | function SDestructibleObjects:process(ent, dt) -- tiny function | |
− | function | + | local function EffectExplode(s, scale, pos, r, speed, texture) |
− | + | local p = Particles.new() | |
− | + | p:setPosition(pos) | |
− | + | p:setTexture(texture) | |
− | + | p:setScale(scale) | |
− | + | s:addChild(p) | |
− | + | local parts = {} | |
− | + | for i = 1, 6 do -- 8 | |
− | + | local a = random()*6.3 | |
− | + | local dx, dy = cos(a), sin(a) | |
− | + | local sr = random()*r | |
− | + | local px, py = dx*sr, dy*sr | |
− | + | local ss = (random()+0.5) * (speed or 1) | |
− | + | insert(parts, | |
− | + | { | |
− | + | x = px, y = py, | |
− | + | speedX = dx * ss, | |
− | + | speedY = dy * ss, | |
− | + | speedAngular = random()*4 - 2, | |
− | + | decayAlpha = random()*0.04 + 0.95, | |
− | + | ttl = 32, -- 500 | |
− | + | size = random()*10 + 20, | |
− | + | } | |
− | + | ) | |
− | + | end | |
− | + | p:addParticles(parts) | |
− | + | Core.yield(1) | |
− | + | p:removeFromParent() | |
− | + | end | |
− | + | -- hurt fx | |
− | + | if ent.washurt and ent.washurt > 0 then | |
− | + | ent.washurt -= 1 | |
− | + | if ent.washurt < ent.recovertimer/2 then | |
− | + | if ent.hitfx then ent.hitfx:setVisible(false) end | |
− | + | end | |
− | + | if ent.washurt <= 0 then | |
− | + | ent.sprite:setColorTransform(1, 1, 1, 1) | |
− | + | end | |
− | + | end | |
− | + | if ent.isdirty then -- hit | |
− | end | + | self.channel = self.snd:play() |
− | + | if self.channel then self.channel:setVolume(g_sfxvolume*0.01) end | |
− | + | ent.hitfx:setVisible(true) | |
− | + | ent.hitfx:setPosition(ent.pos + vector(ent.headhurtbox.x+4, ent.headhurtbox.y)) | |
− | -- | + | ent.spritelayer:addChild(ent.hitfx) |
− | + | ent.currhealth -= ent.damage | |
− | + | ent.washurt = ent.recovertimer -- timer for a flash effect | |
− | + | ent.sprite:setColorTransform(1, 1, 1, 3) -- a flash effect | |
− | + | ent.isdirty = false | |
− | + | if ent.currhealth <= 0 then | |
− | + | --EffectExplode(s, scale, pos, r, speed, texture) | |
− | + | Core.asyncCall(EffectExplode, ent.spritelayer, 2, | |
− | + | ent.pos+vector(ent.collbox.w/2, -ent.h/2), 4, 2, | |
− | + | Texture.new("gfx/fx/fxBarrel_02_0011.png")) | |
− | ent. | + | ent.spritelayer:removeChild(ent.hitfx) |
− | + | self.tiny.tworld:removeEntity(ent) -- sprite is removed in SDrawable | |
− | + | self.tiny.numberofdestructibleobjects -= 1 | |
− | |||
− | |||
− | |||
− | |||
− | -- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | |||
end | end | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | The System removes a breakable object when destroyed and spawn a collectible in the '''onRemove''' function: | |
* it runs every frame | * it runs every frame | ||
− | * it affects only entities with an '' | + | * it affects only entities with an ''isdestructibleobject'' id |
− | * | + | * on hurt adds an hit fx |
− | + | * on destroyed adds particles | |
− | * | + | * '''onRemove''' spawns a collectible |
− | * | ||
− | |||
− | |||
− | == | + | == sCollectible.lua == |
− | "''' | + | "'''sCollectible.lua'''" in the '''"_S"''' folder. The code: |
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
− | + | SCollectible = Core.class() | |
local random = math.random | local random = math.random | ||
− | function | + | function SCollectible:init(xtiny, xbump, xplayer1) -- tiny function |
− | self.tiny = xtiny -- | + | self.tiny = xtiny -- make a class ref |
self.tiny.processingSystem(self) -- called once on init and every update | self.tiny.processingSystem(self) -- called once on init and every update | ||
− | self. | + | self.bworld = xbump |
+ | self.player1 = xplayer1 | ||
+ | -- sfx | ||
+ | self.snd = Sound.new("audio/sfx/sfx_coin_double1.wav") | ||
+ | self.channel = self.snd:play(0, false, true) | ||
end | end | ||
− | function | + | function SCollectible:filter(ent) -- tiny function |
− | return ent. | + | return ent.iscollectible |
end | end | ||
− | function | + | function SCollectible:onAdd(ent) -- tiny function |
end | end | ||
− | function | + | function SCollectible:onRemove(ent) -- tiny function |
+ | self.bworld:remove(ent) -- remove collision box from cbump world here! | ||
end | end | ||
− | + | function SCollectible:process(ent, dt) -- tiny function | |
− | function | + | if ent.isdirty then -- hit |
− | + | local function map(v, minSrc, maxSrc, minDst, maxDst, clampValue) | |
− | if | + | local newV = (v - minSrc) / (maxSrc - minSrc) * (maxDst - minDst) + minDst |
− | + | return not clampValue and newV or clamp(newV, minDst >< maxDst, minDst <> maxDst) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | + | self.channel = self.snd:play() | |
− | + | if self.channel then self.channel:setVolume(g_sfxvolume*0.01) end | |
− | + | -- ent.hitfx:setVisible(true) | |
− | + | -- ent.hitfx:setPosition(ent.pos.x+ent.headhurtbox.x, ent.y+ent.headhurtbox.y) | |
− | + | -- ent.spritelayer:addChild(ent.hitfx) | |
− | + | -- ent.currhealth -= ent.damage | |
− | + | -- ent.washurt = ent.recovertimer -- timer for a flash effect | |
− | + | if random(100) > 50 then | |
− | + | if self.player1.currjumps < 0 then self.player1.currjumps = 0 end | |
− | + | self.player1.currjumps += 3 | |
− | + | self.tiny.hudcurrjumps:setText("JUMPS: "..self.player1.currjumps) | |
− | + | else | |
− | + | self.player1.currhealth += 1 | |
− | + | -- hud | |
− | + | local hudhealthwidth = map(self.player1.currhealth, 0, self.player1.totalhealth, 0, 100) | |
− | + | self.tiny.hudhealth:setWidth(hudhealthwidth) | |
− | + | if self.player1.currhealth < self.player1.totalhealth/3 then self.tiny.hudhealth:setColor(0xff0000) | |
− | + | elseif self.player1.currhealth < self.player1.totalhealth/2 then self.tiny.hudhealth:setColor(0xff5500) | |
− | + | else self.tiny.hudhealth:setColor(0x00ff00) | |
− | |||
− | |||
− | |||
− | if | ||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
− | + | ent.sprite:setColorTransform(0, 2, 0, 3) -- the flash effect (a bright color) | |
− | + | ent.isdirty = false | |
− | + | --[[ | |
− | + | if ent.currhealth <= 0 then | |
− | + | ent.hitfx:setColorTransform(3, 0, 0, random(1, 3)/10) | |
− | + | ent.hitfx:setY(ent.hitfx:getY()+ent.h/1.1) -- magik XXX | |
− | -- | + | ent.hitfx:setRotation(random(360)) |
− | + | ent.hitfx:setScale(random(5, 10)/10) | |
− | + | ent.bgfxlayer:addChild(ent.hitfx) | |
− | + | self.tiny.tworld:removeEntity(ent) -- sprite is removed in SDrawable | |
− | + | -- self.tiny.numberofnmes -= 1 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | + | ]] | |
− | + | self.tiny.tworld:removeEntity(ent) -- sprite is removed in SDrawable | |
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | This System | + | This System spawns a collectible: |
* runs once on init and '''every game loop''' (''process'') | * runs once on init and '''every game loop''' (''process'') | ||
− | * | + | * there are two kind of collectibles: health and jump attacks (updated in the HUD) |
− | |||
− | |||
− | |||
− | |||
− | == | + | == sSpritesSorting.lua.lua == |
− | "''' | + | "'''sSpritesSorting.lua.lua'''" in the '''"_S"''' folder. The code: |
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
− | + | SSpritesSorting = Core.class() | |
− | function | + | function SSpritesSorting:init(xtiny) -- tiny function |
xtiny.processingSystem(self) -- called once on init and every update | xtiny.processingSystem(self) -- called once on init and every update | ||
self.spriteslist = xtiny.spriteslist | self.spriteslist = xtiny.spriteslist | ||
end | end | ||
− | function | + | function SSpritesSorting:filter(ent) -- tiny function |
− | return ent. | + | return ent.sprite |
end | end | ||
− | function | + | function SSpritesSorting:onAdd(ent) -- tiny function |
+ | -- print("SSpritesSorting added", ent) | ||
+ | self.spriteslist[ent] = true | ||
end | end | ||
− | function | + | function SSpritesSorting:onRemove(ent) -- tiny function |
+ | -- print("SSpritesSorting removed", ent) | ||
+ | self.spriteslist[ent] = nil | ||
end | end | ||
− | function | + | local p1rangetoofar = myappwidth*0.5 -- save some CPU |
− | local function | + | function SSpritesSorting:process(ent, dt) -- tiny function |
− | + | local function fun() | |
− | + | for k, _ in pairs(self.spriteslist) do | |
− | + | if ent.currlives <= 0 or k.currlives <= 0 then -- don't sort if dead | |
− | + | return | |
− | + | end | |
− | + | if k.isplayer1 then -- don't sort out of range actors to save frames | |
− | + | if -(k.pos.x-ent.pos.x)<>(k.pos.x-ent.pos.x) > p1rangetoofar then | |
− | + | return | |
− | |||
− | for k, _ in pairs(self.spriteslist) do | ||
− | |||
− | if | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | if | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
− | + | if not ent.body.isonfloor then | |
− | + | if ent.positionystart < k.positionystart and -- ent is behind | |
− | + | ent.spritelayer:getChildIndex(ent.sprite) > k.spritelayer:getChildIndex(k.sprite) then -- sprite is in front | |
− | + | ent.spritelayer:swapChildren(ent.sprite, k.sprite) | |
− | if | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | if | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ent. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ent. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
else | else | ||
− | if | + | if ent.pos.y < k.pos.y and -- ent is behind |
− | ent. | + | ent.spritelayer:getChildIndex(ent.sprite) > k.spritelayer:getChildIndex(k.sprite) then -- sprite is in front |
− | + | ent.spritelayer:swapChildren(ent.sprite, k.sprite) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
end | end | ||
+ | Core.yield(0.5) | ||
end | end | ||
+ | Core.asyncCall(fun) -- profiler seems to be faster without asyncCall (because of pairs traversing?) | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | Finally this System sorts the actors on the y axis: | |
* runs once on init and '''every game loop''' (''process'') | * runs once on init and '''every game loop''' (''process'') | ||
− | * | + | * there is a distinction between the actor being on floor and jumping |
− | |||
− | |||
− | |||
− | |||
− | == | + | == XXX.lua == |
"'''sCollision.lua'''" in the '''"_S"''' folder. The code: | "'''sCollision.lua'''" in the '''"_S"''' folder. The code: | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 02:46, 24 November 2024
The Systems 3
A couple more systems to add and we are done. Those systems apply on the breakable objects and the collectibles.
sDestructibleObjects.lua
Please create a file "sDestructibleObjects.lua" in the "_S" folder and the code:
SDestructibleObjects = Core.class()
local random, cos, sin = math.random, math.cos, math.sin
local insert = table.insert
function SDestructibleObjects:init(xtiny, xbworld) -- tiny function
self.tiny = xtiny -- ref so we can remove entities from tiny system
self.tiny.processingSystem(self) -- called once on init and every update
self.bworld = xbworld
-- sfx
self.snd = Sound.new("audio/sfx/footstep/Forest02.wav")
self.channel = self.snd:play(0, false, true)
end
function SDestructibleObjects:filter(ent) -- tiny function
return ent.isdestructibleobject
end
function SDestructibleObjects:onAdd(ent) -- tiny function
end
function SDestructibleObjects:onRemove(ent) -- tiny function
-- spawn a random collectible: ECollectible:init(xspritelayer, xpos)
local function fun()
local el = ECollectible.new(ent.spritelayer, ent.pos+vector(ent.collbox.w/4, -1*ent.collbox.h))
self.tiny.tworld:addEntity(el)
self.bworld:add(el, el.pos.x, el.pos.y, el.collbox.w, el.collbox.h)
Core.yield(1)
end
Core.asyncCall(fun)
self.bworld:remove(ent) -- remove collision box from cbump world here!
end
function SDestructibleObjects:process(ent, dt) -- tiny function
local function EffectExplode(s, scale, pos, r, speed, texture)
local p = Particles.new()
p:setPosition(pos)
p:setTexture(texture)
p:setScale(scale)
s:addChild(p)
local parts = {}
for i = 1, 6 do -- 8
local a = random()*6.3
local dx, dy = cos(a), sin(a)
local sr = random()*r
local px, py = dx*sr, dy*sr
local ss = (random()+0.5) * (speed or 1)
insert(parts,
{
x = px, y = py,
speedX = dx * ss,
speedY = dy * ss,
speedAngular = random()*4 - 2,
decayAlpha = random()*0.04 + 0.95,
ttl = 32, -- 500
size = random()*10 + 20,
}
)
end
p:addParticles(parts)
Core.yield(1)
p:removeFromParent()
end
-- hurt fx
if ent.washurt and ent.washurt > 0 then
ent.washurt -= 1
if ent.washurt < ent.recovertimer/2 then
if ent.hitfx then ent.hitfx:setVisible(false) end
end
if ent.washurt <= 0 then
ent.sprite:setColorTransform(1, 1, 1, 1)
end
end
if ent.isdirty then -- hit
self.channel = self.snd:play()
if self.channel then self.channel:setVolume(g_sfxvolume*0.01) end
ent.hitfx:setVisible(true)
ent.hitfx:setPosition(ent.pos + vector(ent.headhurtbox.x+4, ent.headhurtbox.y))
ent.spritelayer:addChild(ent.hitfx)
ent.currhealth -= ent.damage
ent.washurt = ent.recovertimer -- timer for a flash effect
ent.sprite:setColorTransform(1, 1, 1, 3) -- a flash effect
ent.isdirty = false
if ent.currhealth <= 0 then
--EffectExplode(s, scale, pos, r, speed, texture)
Core.asyncCall(EffectExplode, ent.spritelayer, 2,
ent.pos+vector(ent.collbox.w/2, -ent.h/2), 4, 2,
Texture.new("gfx/fx/fxBarrel_02_0011.png"))
ent.spritelayer:removeChild(ent.hitfx)
self.tiny.tworld:removeEntity(ent) -- sprite is removed in SDrawable
self.tiny.numberofdestructibleobjects -= 1
end
end
end
The System removes a breakable object when destroyed and spawn a collectible in the onRemove function:
- it runs every frame
- it affects only entities with an isdestructibleobject id
- on hurt adds an hit fx
- on destroyed adds particles
- onRemove spawns a collectible
sCollectible.lua
"sCollectible.lua" in the "_S" folder. The code:
SCollectible = Core.class()
local random = math.random
function SCollectible:init(xtiny, xbump, xplayer1) -- tiny function
self.tiny = xtiny -- make a class ref
self.tiny.processingSystem(self) -- called once on init and every update
self.bworld = xbump
self.player1 = xplayer1
-- sfx
self.snd = Sound.new("audio/sfx/sfx_coin_double1.wav")
self.channel = self.snd:play(0, false, true)
end
function SCollectible:filter(ent) -- tiny function
return ent.iscollectible
end
function SCollectible:onAdd(ent) -- tiny function
end
function SCollectible:onRemove(ent) -- tiny function
self.bworld:remove(ent) -- remove collision box from cbump world here!
end
function SCollectible:process(ent, dt) -- tiny function
if ent.isdirty then -- hit
local function map(v, minSrc, maxSrc, minDst, maxDst, clampValue)
local newV = (v - minSrc) / (maxSrc - minSrc) * (maxDst - minDst) + minDst
return not clampValue and newV or clamp(newV, minDst >< maxDst, minDst <> maxDst)
end
self.channel = self.snd:play()
if self.channel then self.channel:setVolume(g_sfxvolume*0.01) end
-- ent.hitfx:setVisible(true)
-- ent.hitfx:setPosition(ent.pos.x+ent.headhurtbox.x, ent.y+ent.headhurtbox.y)
-- ent.spritelayer:addChild(ent.hitfx)
-- ent.currhealth -= ent.damage
-- ent.washurt = ent.recovertimer -- timer for a flash effect
if random(100) > 50 then
if self.player1.currjumps < 0 then self.player1.currjumps = 0 end
self.player1.currjumps += 3
self.tiny.hudcurrjumps:setText("JUMPS: "..self.player1.currjumps)
else
self.player1.currhealth += 1
-- hud
local hudhealthwidth = map(self.player1.currhealth, 0, self.player1.totalhealth, 0, 100)
self.tiny.hudhealth:setWidth(hudhealthwidth)
if self.player1.currhealth < self.player1.totalhealth/3 then self.tiny.hudhealth:setColor(0xff0000)
elseif self.player1.currhealth < self.player1.totalhealth/2 then self.tiny.hudhealth:setColor(0xff5500)
else self.tiny.hudhealth:setColor(0x00ff00)
end
end
ent.sprite:setColorTransform(0, 2, 0, 3) -- the flash effect (a bright color)
ent.isdirty = false
--[[
if ent.currhealth <= 0 then
ent.hitfx:setColorTransform(3, 0, 0, random(1, 3)/10)
ent.hitfx:setY(ent.hitfx:getY()+ent.h/1.1) -- magik XXX
ent.hitfx:setRotation(random(360))
ent.hitfx:setScale(random(5, 10)/10)
ent.bgfxlayer:addChild(ent.hitfx)
self.tiny.tworld:removeEntity(ent) -- sprite is removed in SDrawable
-- self.tiny.numberofnmes -= 1
end
]]
self.tiny.tworld:removeEntity(ent) -- sprite is removed in SDrawable
end
end
This System spawns a collectible:
- runs once on init and every game loop (process)
- there are two kind of collectibles: health and jump attacks (updated in the HUD)
sSpritesSorting.lua.lua
"sSpritesSorting.lua.lua" in the "_S" folder. The code:
SSpritesSorting = Core.class()
function SSpritesSorting:init(xtiny) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
self.spriteslist = xtiny.spriteslist
end
function SSpritesSorting:filter(ent) -- tiny function
return ent.sprite
end
function SSpritesSorting:onAdd(ent) -- tiny function
-- print("SSpritesSorting added", ent)
self.spriteslist[ent] = true
end
function SSpritesSorting:onRemove(ent) -- tiny function
-- print("SSpritesSorting removed", ent)
self.spriteslist[ent] = nil
end
local p1rangetoofar = myappwidth*0.5 -- save some CPU
function SSpritesSorting:process(ent, dt) -- tiny function
local function fun()
for k, _ in pairs(self.spriteslist) do
if ent.currlives <= 0 or k.currlives <= 0 then -- don't sort if dead
return
end
if k.isplayer1 then -- don't sort out of range actors to save frames
if -(k.pos.x-ent.pos.x)<>(k.pos.x-ent.pos.x) > p1rangetoofar then
return
end
end
if not ent.body.isonfloor then
if ent.positionystart < k.positionystart and -- ent is behind
ent.spritelayer:getChildIndex(ent.sprite) > k.spritelayer:getChildIndex(k.sprite) then -- sprite is in front
ent.spritelayer:swapChildren(ent.sprite, k.sprite)
end
else
if ent.pos.y < k.pos.y and -- ent is behind
ent.spritelayer:getChildIndex(ent.sprite) > k.spritelayer:getChildIndex(k.sprite) then -- sprite is in front
ent.spritelayer:swapChildren(ent.sprite, k.sprite)
end
end
end
Core.yield(0.5)
end
Core.asyncCall(fun) -- profiler seems to be faster without asyncCall (because of pairs traversing?)
end
Finally this System sorts the actors on the y axis:
- runs once on init and every game loop (process)
- there is a distinction between the actor being on floor and jumping
XXX.lua
"sCollision.lua" in the "_S" folder. The code:
This System uses the Bump plugin to check for collisions between the actors collision boxes:
- runs once on init and every game loop (process)
- in init we pass the Bump world the actors live in
- we define Bump collision filter
- we check if player1 collides with a collectible actor and tag the collectible as dirty
- finally we set the actor position and flip its bitmap in the direction it is going
- I experimented with asyncCall to test if we could gain some frames per second ;-)
Next?
Next we add the systems for the breakable objects and the collectibles and we are almost done with the game!
Prev.: Tuto tiny-ecs beatemup Part 10 Systems 2
Next: Tuto tiny-ecs beatemup Part 12 XXX