Tuto tiny-ecs demo Part 9 Player Shoots Enemies Die
In this chapter we will make the player1 able to "shoot" and "hurt" enemies.
This will be done in two parts: first enabling the player1 "shoot" action, then hurting the enemies with some fx and make them "die".
Player1 can Shoot
We implement player1 can shoot in the SDynamicBodies system.
Please go to the "sDynamicBodies.lua" file to add some code.
SDynamicBodies = Core.class()
function SDynamicBodies:init(xtiny, xnmes) -- 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.nmes = xnmes -- a list of nmes we can hurt
end
-- ...
In the init function we add the list of enemies to the function signature and we make that list available to the other functions.
Then in the process function, we check if the player presses the action1 button (the spacebar) and we set a random enemy in the nmes list to be hurt.
function SDynamicBodies:process(ent, dt) -- tiny function
-- ...
-- actions (player1)
if ent.isplayer1 and ent.isaction1 then
ent.isaction1 = false
if #self.nmes > 0 then -- check nmes list is not empty
self.nmes[math.random(#self.nmes)].isdirty = true
else -- nmes list is empty
print("you killed everybody!")
end
end
-- move
ent.x += ent.body.vx * dt
ent.sprite:setPosition(ent.x, ent.y)
end
I set the hurt behavior as being the flag isdirty (some of my Box2D leftovers).
So every time the player presses the spacebar, a random enemy from the nmes list will get hurt.
Enemies can die
In order to hurt an enemy we need to add a new System. The system will decrease an enemy health which will eventually "die".
In the systems folder "_S", create a file called "sNme1.lua" for example, and copy the following code:
SNme1 = Core.class()
function SNme1:init(xtiny, xnmes) -- 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.nmes = xnmes
end
function SNme1:filter(ent) -- tiny function
return ent.isnme
end
function SNme1:onAdd(ent) -- tiny function
end
function SNme1:onRemove(ent) -- tiny function
print("SNme1:onRemove")
end
function SNme1:process(ent, dt) -- tiny function
for i = #self.nmes, 1, -1 do -- scan in reverse
if self.nmes[i].isdirty then -- hit
self.nmes[i].health -= 1
self.nmes[i].washurt = 5 -- timer for a flash effect
self.nmes[i].sprite:setColorTransform(2, 0, 0, 3) -- the flash effect (a bright red color)
self.nmes[i].isdirty = false
if self.nmes[i].health <= 0 then -- dead :-(
self.tiny.world:removeEntity(self.nmes[i]) -- sprite removed from sprite layer in SDrawable
self.nmes[i] = nil -- remove from table
table.remove(self.nmes, i) -- remove from table
end
end
end
end
In this system, when an entity is dirty (hurt), we decrease its health, set a timer for a flashing effect and if it dies, we remove it from tiny-ecs world and the nmes list.
Please note the sprite is removed from the sprite layer in the SDrawable system:
function SDrawable:onRemove(ent) -- tiny function
ent.spritelayer:removeChild(ent.sprite)
end
Let's add the flashing effect to the SDynamicBodies system like so:
function SDynamicBodies:process(ent, dt) -- tiny function
-- hurt fx
if ent.washurt and ent.washurt > 0 then
ent.washurt -= 1
if ent.washurt <= 0 then
ent.sprite:setColorTransform(1, 1, 1, 1)
end
end
-- movement
if ent.isleft and not ent.isright then -- LEFT
ent.body.vx = -ent.body.speed
elseif ent.isright and not ent.isleft then -- RIGHT
ent.body.vx = ent.body.speed
-- ...
If an entity counter washurt is greater than 0, we decrease it. When the counter reaches zero we set the entity sprite color back to normal.
Action
To see the result of our work, we need to add the SNme1 system to tiny-ecs world.
In the "levelX.lua" file add the SNme1 system:
-- ...
-- add systems to tiny-ecs
self.tiny.world:add(
SDrawable.new(self.tiny),
SDynamicBodies.new(self.tiny, nmes), -- add the nmes list here too!
SPlayer1Control.new(self.tiny),
SAI.new(self.tiny),
SNme1.new(self.tiny, nmes)
)
-- ...
Remember we changed the SDynamicBodies init function signature, so you need to add the new parameter to the System here too!
That's it!
You can run the demo and press the spacebar. A random enemy should get hit and eventually die.
Next?
In the next part, we ...
Prev.: Tuto tiny-ecs demo Part 8 Enemies
Next: xxx