Difference between revisions of "Tuto tiny-ecs beatemup Part 11 Systems 3"
(wip) |
|||
(3 intermediate revisions by the same user not shown) | |||
Line 189: | Line 189: | ||
'''There are quite a bit of commented code you can delete as this Entity is immediately removed''' | '''There are quite a bit of commented code you can delete as this Entity is immediately removed''' | ||
− | == sSpritesSorting | + | == sSpritesSorting.lua == |
− | "'''sSpritesSorting | + | "'''sSpritesSorting.lua'''" in the '''"_S"''' folder. The code: |
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
SSpritesSorting = Core.class() | SSpritesSorting = Core.class() | ||
Line 250: | Line 250: | ||
It would be difficult to accurately position the hit and hurt boxes, the collision boxes, ... without visual cues. | It would be difficult to accurately position the hit and hurt boxes, the collision boxes, ... without visual cues. | ||
− | Debug systems help us with | + | Debug systems help us with the above. Fortunately they are small and quite simple. |
=== sDebugCollision.lua === | === sDebugCollision.lua === | ||
Line 503: | Line 503: | ||
function SDebugHurtBoxNme:onRemove(ent) -- tiny function | function SDebugHurtBoxNme:onRemove(ent) -- tiny function | ||
− | ent.spritelayer:removeChild(ent.debugheadhurtbox) | + | if not ent.isdestructibleobject then -- isdestructibleobject is somehow already removed! |
− | + | ent.spritelayer:removeChild(ent.debugheadhurtbox) | |
+ | ent.spritelayer:removeChild(ent.debugspinehurtbox) | ||
+ | end | ||
end | end | ||
function SDebugHurtBoxNme:process(ent, dt) -- tiny function | function SDebugHurtBoxNme:process(ent, dt) -- tiny function | ||
− | ent.debugheadhurtbox:setPosition(ent.pos+vector(ent.collbox.w/2+(ent.headhurtbox.x*ent.flip), ent.headhurtbox.y)) | + | local function fun() |
− | + | ent.debugheadhurtbox:setPosition(ent.pos+vector(ent.collbox.w/2+(ent.headhurtbox.x*ent.flip), ent.headhurtbox.y)) | |
+ | ent.debugspinehurtbox:setPosition(ent.pos+vector(ent.collbox.w/2+(ent.spinehurtbox.x*ent.flip), ent.spinehurtbox.y)) | ||
+ | Core.yield(1) | ||
+ | end | ||
+ | Core.asyncCall(fun) | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | This System displays the enemies hurt boxes. | + | This System displays the enemies and breakable objects hurt boxes. |
=== sDebugHurtBoxPlayer.lua === | === sDebugHurtBoxPlayer.lua === | ||
Line 592: | Line 598: | ||
== Next? == | == Next? == | ||
− | + | '''Congratulations'''! We have finished our game. | |
− | |||
− | + | Let's add the final scene: '''YOU WIN'''! | |
Prev.: [[Tuto tiny-ecs beatemup Part 10 Systems 2]]</br> | Prev.: [[Tuto tiny-ecs beatemup Part 10 Systems 2]]</br> | ||
− | '''Next: [[Tuto tiny-ecs beatemup Part 12 | + | '''Next: [[Tuto tiny-ecs beatemup Part 12 You Win]]''' |
'''[[Tutorial - tiny-ecs beatemup]]''' | '''[[Tutorial - tiny-ecs beatemup]]''' | ||
{{GIDEROS IMPORTANT LINKS}} | {{GIDEROS IMPORTANT LINKS}} |
Latest revision as of 02:32, 25 November 2024
The Systems 3
A couple more systems to add and we are done. We also add the Debug Systems to help us visualize all the boxes (hitbox, hurtbox, collsion box, ...).
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)
There are quite a bit of commented code you can delete as this Entity is immediately removed
sSpritesSorting.lua
"sSpritesSorting.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
DEBUG SYSTEMS
It would be difficult to accurately position the hit and hurt boxes, the collision boxes, ... without visual cues.
Debug systems help us with the above. Fortunately they are small and quite simple.
sDebugCollision.lua
"sDebugCollision.lua" in the "_S" folder. The code:
SDebugCollision = Core.class()
function SDebugCollision:init(xtiny) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
end
function SDebugCollision:filter(ent) -- tiny function
return ent.collbox
end
function SDebugCollision:onAdd(ent) -- tiny function
local debugcolor = 0xff00ff
if ent.isplayer1 then debugcolor = 0x00ffff end
ent.debug = Pixel.new(debugcolor, 0.25, ent.collbox.w, ent.collbox.h)
ent.spritelayer:addChild(ent.debug)
end
function SDebugCollision:onRemove(ent) -- tiny function
ent.spritelayer:removeChild(ent.debug)
end
function SDebugCollision:process(ent, dt) -- tiny function
-- ent.debug:setPosition(ent.x, ent.y)
ent.debug:setPosition(ent.pos)
end
This System displays the actors collision box.
sDebugHitBoxNme.lua
"sDebugHitBoxNme.lua" in the "_S" folder. The code:
SDebugHitBoxNme = Core.class()
function SDebugHitBoxNme:init(xtiny, xshowbox) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
self.showbox = xshowbox
end
function SDebugHitBoxNme:filter(ent) -- tiny function
return (ent.headhitboxattack1 or ent.headhitboxattack2 or ent.spinehitboxattack1 or ent.spinehitboxattack2 or
ent.headhitboxjattack1 or ent.spinehitboxjattack1) and not ent.isplayer1
end
function SDebugHitBoxNme:onAdd(ent) -- tiny function
-- debugheadhitboxp1
if ent.headhitboxattack1 then
ent.debugheadhitboxp1 = Pixel.new(0xaa0000, 0.5, ent.headhitboxattack1.w, ent.headhitboxattack1.h)
ent.debugheadhitboxp1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhitboxp1)
ent.debugheadhitboxp1:setVisible(self.showbox[1]) -- granular debugging
end
-- debugheadhitboxp2
if ent.headhitboxattack2 then
ent.debugheadhitboxp2 = Pixel.new(0xaa5500, 0.5, ent.headhitboxattack2.w, ent.headhitboxattack2.h)
ent.debugheadhitboxp2:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhitboxp2)
ent.debugheadhitboxp2:setVisible(self.showbox[2]) -- granular debugging
end
-- debugspinehitboxk1
if ent.spinehitboxattack1 then
ent.debugspinehitboxk1 = Pixel.new(0x005500, 0.5, ent.spinehitboxattack1.w, ent.spinehitboxattack1.h)
ent.debugspinehitboxk1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehitboxk1)
ent.debugspinehitboxk1:setVisible(self.showbox[3]) -- granular debugging
end
-- debugspinehitboxk2
if ent.spinehitboxattack2 then
ent.debugspinehitboxk2 = Pixel.new(0x00aa00, 0.5, ent.spinehitboxattack2.w, ent.spinehitboxattack2.h)
ent.debugspinehitboxk2:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehitboxk2)
ent.debugspinehitboxk2:setVisible(self.showbox[4]) -- granular debugging
end
-- debugheadhitboxjp1
if ent.headhitboxjattack1 then
ent.debugheadhitboxjp1 = Pixel.new(0xaaaa00, 0.5, ent.headhitboxjattack1.w, ent.headhitboxjattack1.h)
ent.debugheadhitboxjp1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhitboxjp1)
ent.debugheadhitboxjp1:setVisible(self.showbox[5]) -- granular debugging
end
-- debugspinehitboxjk1
if ent.spinehitboxjattack1 then
ent.debugspinehitboxjk1 = Pixel.new(0x00ff00, 0.5, ent.spinehitboxjattack1.w, ent.spinehitboxjattack1.h)
ent.debugspinehitboxjk1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehitboxjk1)
ent.debugspinehitboxjk1:setVisible(self.showbox[6]) -- granular debugging
end
end
function SDebugHitBoxNme:onRemove(ent) -- tiny function
if ent.headhitboxattack1 then ent.spritelayer:removeChild(ent.debugheadhitboxp1) end
if ent.headhitboxattack2 then ent.spritelayer:removeChild(ent.debugheadhitboxp2) end
if ent.spinehitboxattack1 then ent.spritelayer:removeChild(ent.debugspinehitboxk1) end
if ent.spinehitboxattack2 then ent.spritelayer:removeChild(ent.debugspinehitboxk2) end
if ent.headhitboxjattack1 then ent.spritelayer:removeChild(ent.debugheadhitboxjp1) end
if ent.spinehitboxjattack1 then ent.spritelayer:removeChild(ent.debugspinehitboxjk1) end
end
function SDebugHitBoxNme:process(ent, dt) -- tiny function
local function fun()
if ent.headhitboxattack1 then
ent.debugheadhitboxp1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhitboxattack1.x*ent.flip), ent.headhitboxattack1.y))
end
if ent.headhitboxattack2 then
ent.debugheadhitboxp2:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhitboxattack2.x*ent.flip), ent.headhitboxattack2.y))
end
if ent.spinehitboxattack1 then
ent.debugspinehitboxk1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehitboxattack1.x*ent.flip), ent.spinehitboxattack1.y))
end
if ent.spinehitboxattack2 then
ent.debugspinehitboxk2:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehitboxattack2.x*ent.flip), ent.spinehitboxattack2.y))
end
if ent.headhitboxjattack1 then
ent.debugheadhitboxjp1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhitboxjattack1.x*ent.flip), ent.headhitboxjattack1.y))
end
if ent.spinehitboxjattack1 then
ent.debugspinehitboxjk1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehitboxjattack1.x*ent.flip), ent.spinehitboxjattack1.y))
end
Core.yield(1)
end
Core.asyncCall(fun)
end
This System displays the enemies hit boxes when available.
sDebugHitBoxPlayer.lua
"sDebugHitBoxPlayer.lua" in the "_S" folder. The code:
SDebugHitBoxPlayer = Core.class()
function SDebugHitBoxPlayer:init(xtiny, xshowbox) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
self.showbox = xshowbox
end
function SDebugHitBoxPlayer:filter(ent) -- tiny function
return (ent.headhitboxattack1 or ent.headhitboxattack2 or ent.spinehitboxattack1 or ent.spinehitboxattack2 or
ent.headhitboxjattack1 or ent.spinehitboxjattack1) and not ent.isnme
end
function SDebugHitBoxPlayer:onAdd(ent) -- tiny function
-- debugheadhitboxp1
if ent.headhitboxattack1 then
ent.debugheadhitboxp1 = Pixel.new(0xaa0000, 0.5, ent.headhitboxattack1.w, ent.headhitboxattack1.h)
ent.debugheadhitboxp1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhitboxp1)
ent.debugheadhitboxp1:setVisible(self.showbox[1]) -- granular debugging
end
-- debugheadhitboxp2
if ent.headhitboxattack2 then
ent.debugheadhitboxp2 = Pixel.new(0xaa5500, 0.5, ent.headhitboxattack2.w, ent.headhitboxattack2.h)
ent.debugheadhitboxp2:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhitboxp2)
ent.debugheadhitboxp2:setVisible(self.showbox[2]) -- granular debugging
end
-- debugspinehitboxk1
if ent.spinehitboxattack1 then
ent.debugspinehitboxk1 = Pixel.new(0x005500, 0.5, ent.spinehitboxattack1.w, ent.spinehitboxattack1.h)
ent.debugspinehitboxk1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehitboxk1)
ent.debugspinehitboxk1:setVisible(self.showbox[3]) -- granular debugging
end
-- debugspinehitboxk2
if ent.spinehitboxattack2 then
ent.debugspinehitboxk2 = Pixel.new(0x00aa00, 0.5, ent.spinehitboxattack2.w, ent.spinehitboxattack2.h)
ent.debugspinehitboxk2:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehitboxk2)
ent.debugspinehitboxk2:setVisible(self.showbox[4]) -- granular debugging
end
-- debugheadhitboxjp1
if ent.headhitboxjattack1 then
ent.debugheadhitboxjp1 = Pixel.new(0xaaaa00, 0.5, ent.headhitboxjattack1.w, ent.headhitboxjattack1.h)
ent.debugheadhitboxjp1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhitboxjp1)
ent.debugheadhitboxjp1:setVisible(self.showbox[5]) -- granular debugging
end
-- debugspinehitboxjk1
if ent.spinehitboxjattack1 then
ent.debugspinehitboxjk1 = Pixel.new(0x00ff00, 0.5, ent.spinehitboxjattack1.w, ent.spinehitboxjattack1.h)
ent.debugspinehitboxjk1:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehitboxjk1)
ent.debugspinehitboxjk1:setVisible(self.showbox[6]) -- granular debugging
end
end
function SDebugHitBoxPlayer:onRemove(ent) -- tiny function
if ent.headhitboxattack1 then ent.spritelayer:removeChild(ent.debugheadhitboxp1) end
if ent.headhitboxattack2 then ent.spritelayer:removeChild(ent.debugheadhitboxp2) end
if ent.spinehitboxattack1 then ent.spritelayer:removeChild(ent.debugspinehitboxk1) end
if ent.spinehitboxattack2 then ent.spritelayer:removeChild(ent.debugspinehitboxk2) end
if ent.headhitboxjattack1 then ent.spritelayer:removeChild(ent.debugheadhitboxjp1) end
if ent.spinehitboxjattack1 then ent.spritelayer:removeChild(ent.debugspinehitboxjk1) end
end
function SDebugHitBoxPlayer:process(ent, dt) -- tiny function
local function fun()
if ent.headhitboxattack1 then
ent.debugheadhitboxp1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhitboxattack1.x*ent.flip), ent.headhitboxattack1.y))
end
if ent.headhitboxattack2 then
ent.debugheadhitboxp2:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhitboxattack2.x*ent.flip), ent.headhitboxattack2.y))
end
if ent.spinehitboxattack1 then
ent.debugspinehitboxk1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehitboxattack1.x*ent.flip), ent.spinehitboxattack1.y))
end
if ent.spinehitboxattack2 then
ent.debugspinehitboxk2:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehitboxattack2.x*ent.flip), ent.spinehitboxattack2.y))
end
if ent.headhitboxjattack1 then
ent.debugheadhitboxjp1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhitboxjattack1.x*ent.flip), ent.headhitboxjattack1.y))
end
if ent.spinehitboxjattack1 then
ent.debugspinehitboxjk1:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehitboxjattack1.x*ent.flip), ent.spinehitboxjattack1.y))
end
Core.yield(1)
end
Core.asyncCall(fun)
end
This System displays the player hit boxes when available.
sDebugHurtBoxNme.lua
"sDebugHurtBoxNme.lua" in the "_S" folder. The code:
SDebugHurtBoxNme = Core.class()
function SDebugHurtBoxNme:init(xtiny) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
end
function SDebugHurtBoxNme:filter(ent) -- tiny function
return (ent.headhurtbox or ent.spinehurtbox) and not ent.isplayer1
end
function SDebugHurtBoxNme:onAdd(ent) -- tiny function
-- debugheadhurtbox
ent.debugheadhurtbox = Pixel.new(0x5500ff, 0.5, ent.headhurtbox.w, ent.headhurtbox.h)
ent.debugheadhurtbox:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhurtbox)
-- debugspinehurtbox
ent.debugspinehurtbox = Pixel.new(0xff00ff, 0.5, ent.spinehurtbox.w, ent.spinehurtbox.h)
ent.debugspinehurtbox:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehurtbox)
end
function SDebugHurtBoxNme:onRemove(ent) -- tiny function
if not ent.isdestructibleobject then -- isdestructibleobject is somehow already removed!
ent.spritelayer:removeChild(ent.debugheadhurtbox)
ent.spritelayer:removeChild(ent.debugspinehurtbox)
end
end
function SDebugHurtBoxNme:process(ent, dt) -- tiny function
local function fun()
ent.debugheadhurtbox:setPosition(ent.pos+vector(ent.collbox.w/2+(ent.headhurtbox.x*ent.flip), ent.headhurtbox.y))
ent.debugspinehurtbox:setPosition(ent.pos+vector(ent.collbox.w/2+(ent.spinehurtbox.x*ent.flip), ent.spinehurtbox.y))
Core.yield(1)
end
Core.asyncCall(fun)
end
This System displays the enemies and breakable objects hurt boxes.
sDebugHurtBoxPlayer.lua
"sDebugHurtBoxPlayer.lua" in the "_S" folder. The code:
SDebugHurtBoxPlayer = Core.class()
function SDebugHurtBoxPlayer:init(xtiny) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
end
function SDebugHurtBoxPlayer:filter(ent) -- tiny function
return (ent.headhurtbox or ent.spinehurtbox) and not ent.isnme
end
function SDebugHurtBoxPlayer:onAdd(ent) -- tiny function
-- debugheadhurtbox
ent.debugheadhurtbox = Pixel.new(0x5500ff, 0.5, ent.headhurtbox.w, ent.headhurtbox.h)
ent.debugheadhurtbox:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugheadhurtbox)
-- debugspinehurtbox
ent.debugspinehurtbox = Pixel.new(0xff00ff, 0.5, ent.spinehurtbox.w, ent.spinehurtbox.h)
ent.debugspinehurtbox:setAnchorPoint(0.5, 0.5)
ent.spritelayer:addChild(ent.debugspinehurtbox)
end
function SDebugHurtBoxPlayer:onRemove(ent) -- tiny function
ent.spritelayer:removeChild(ent.debugheadhurtbox)
ent.spritelayer:removeChild(ent.debugspinehurtbox)
end
function SDebugHurtBoxPlayer:process(ent, dt) -- tiny function
ent.debugheadhurtbox:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.headhurtbox.x*ent.flip), ent.headhurtbox.y))
ent.debugspinehurtbox:setPosition(ent.pos + vector(ent.collbox.w/2+(ent.spinehurtbox.x*ent.flip), ent.spinehurtbox.y))
end
This System displays the player hurt boxes.
sDebugSpriteSorting.lua
"sDebugSpriteSorting.lua" in the "_S" folder. The code:
SDebugSpriteSorting = Core.class()
function SDebugSpriteSorting:init(xtiny) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
end
function SDebugSpriteSorting:filter(ent) -- tiny function
return ent.sprite
end
function SDebugSpriteSorting:onAdd(ent) -- tiny function
-- debugposition
ent.debugposition = Pixel.new(0xaa5500, 1, 16, 16)
ent.debugposition:setAnchorPoint(0.5, 0.5)
if ent.isplayer1 then ent.debugposition:setColor(0xaa5500, 1) end
ent.spritelayer:addChild(ent.debugposition)
-- debugstartyposition
ent.debugstartyposition = Pixel.new(0xaa557f, 1, 16, 16)
ent.debugstartyposition:setAnchorPoint(0.5, 0.5)
if ent.isplayer1 then ent.debugstartyposition:setColor(0xaa557f, 1) end
ent.spritelayer:addChild(ent.debugstartyposition)
end
function SDebugSpriteSorting:onRemove(ent) -- tiny function
ent.spritelayer:removeChild(ent.debugposition)
ent.spritelayer:removeChild(ent.debugstartyposition)
end
function SDebugSpriteSorting:process(ent, dt) -- tiny function
ent.debugposition:setPosition(ent.pos)
ent.debugstartyposition:setPosition(ent.pos.x, ent.positionystart)
end
This System displays the actors y position.
Next?
Congratulations! We have finished our game.
Let's add the final scene: YOU WIN!
Prev.: Tuto tiny-ecs beatemup Part 10 Systems 2
Next: Tuto tiny-ecs beatemup Part 12 You Win