Difference between revisions of "Tuto tiny-ecs demo Part 9 Player Shoots Enemies Die"
(Created page with "__TOC__ In this chapter we will make the player1 able to "shoot" and hurt a enemies. This will be done in two parts: first enabling the player1 "shoot" action, then hurting...") |
|||
Line 1: | Line 1: | ||
__TOC__ | __TOC__ | ||
− | In this chapter we will make the player1 able to "shoot" and hurt | + | 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". | 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 | + | == Player1 can Shoot == |
We implement player1 can shoot in the '''SDynamicBodies''' system. | We implement player1 can shoot in the '''SDynamicBodies''' system. | ||
Line 22: | Line 22: | ||
In the init function we add the list of enemies to the function signature and we make that list available to the other functions. | 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. |
− | + | <syntaxhighlight lang="lua"> | |
+ | -- ... | ||
+ | -- 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) | ||
+ | -- ... | ||
+ | </syntaxhighlight> | ||
− | + | 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: | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
+ | 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 | ||
+ | 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 | ||
+ | self.tiny.world:removeEntity(self.nmes[i]) -- SDrawable removed from cbump world on system remove (=dead) | ||
+ | self.nmes[i] = nil -- remove from table | ||
+ | table.remove(self.nmes, i) -- remove from table | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | 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: | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | function SDrawable:onRemove(ent) -- tiny function | ||
+ | ent.spritelayer:removeChild(ent.sprite) | ||
+ | end | ||
+ | </syntaxhighlight> | ||
'''You can run the demo and you should see ten enemies placed randomly on the x axis'''. | '''You can run the demo and you should see ten enemies placed randomly on the x axis'''. |
Revision as of 04:37, 21 December 2023
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.
-- ...
-- 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)
-- ...
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
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
self.tiny.world:removeEntity(self.nmes[i]) -- SDrawable removed from cbump world on system remove (=dead)
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
You can run the demo and you should see ten enemies placed randomly on the x axis.
Enemy add AI Component
Our enemy1 entities don't do anything yet. Let's equip them with an Artificial Intelligence component.
In the components folder "_C", create a file called "cAI.lua" for example, and copy the following code:
Here, in the init function, we store an entity starting position and a delta x and y to set how far it can travel.
We can now attach this AI component to our enemy1 entity in "eNme1.lua":
You can run the demo and the enemies should move to the right.
Enemy AI System
To make our enemies intelligent we need to create an AI system.
In the systems folder "_S", create a file called "sAI.lua" for example, and copy the following code:
This is a simple AI system, which switches an entity direction when it reaches some limits (delta x, delta y).
Finally we need to add this AI system to tiny-ecs world.
Please go to the "LevelX.lua" file and complete the code as follow:
You can run the demo and the enemies should be less dumb ;-)
Next?
In the next part, we make the player1 "shoots" and the enemies "die" :-(
Prev.: Tuto tiny-ecs demo Part 8 Enemies
Next: xxx