Tuto tiny-ecs demo Part 8 Enemies
We continue with our tiny-ecs demo. It is time to add some "enemies".
Entity enemy1
First we create an entity of type enemy1.
In the entites folder "_E", create a file called "eNme1.lua" for example and copy the following code:
ENme1 = Core.class()
function ENme1:init(xspritelayer, x, y, dx, dy)
-- ids
self.isnme = true
self.isactor = true
-- sprite
self.spritelayer = xspritelayer
self.sprite = Pixel.new(math.random(0xffffff), 1, 32, 64)
-- params
self.x = x
self.y = y
self.health = 10
-- BODY COMPONENT: function CBody:init(xspeed, xjumpspeed)
self.body = CBody.new(4*16, 6*16) -- xspeed, xjumpspeed
self.body.defaultmass = 1
self.body.currmass = self.body.defaultmass
end
We start by adding some ids, a sprite layer and a sprite. The sprite here is a Pixel with a random color.
We add some more parameters like position and health.
Finally we add the body component so the entity can move.
Please note in the init parameters, there are two unused yet variables: dx and dy. They will be used when we add an artificial intelligence (AI) component later.
With ECS it is easy to build your game, you add/remove parameters and components as you need.
World addEntity
We need to add the enemy1 entity to tiny-ecs world. Let's add a couple of them.
Please go to the "LevelX.lua" file and complete the code as follow:
...
-- tiny-ecs
self.tiny = require "classes/tiny-ecs"
self.tiny.world = self.tiny.world()
-- some enemies (xspritelayer, x, y, dx, dy)
local nmes = {}
for i = 1, 10 do -- we create 10 enemies
nmes[i] = ENme1.new(self.camera, math.random(24)*16, 10*16, math.random(12)*16, 0)
self.tiny.world:addEntity(nmes[i])
end
-- the player (xspritelayer, x, y)
self.player1 = EPlayer1.new(self.camera, 12*16, 10*16)
self.tiny.world:addEntity(self.player1)
...
When we add an enemy1 entity to tiny-ecs world, we also add it to an nmes list so we can iterate through them in our game.
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:
CAI = Core.class()
function CAI:init(x, y, dx, dy)
self.startpositionx = x
self.startpositiony = y
self.dx = dx -- delta x
self.dy = dy -- delta y
end
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":
ENme1 = Core.class()
function ENme1:init(xspritelayer, x, y, dx, dy)
-- ...
self.health = 10
-- BODY COMPONENT: function CBody:init(xspeed, xjumpspeed)
self.body = CBody.new(4*16, 6*16) -- xspeed, xjumpspeed
self.body.defaultmass = 1
self.body.currmass = self.body.defaultmass
-- AI COMPONENT: function CAI:init(x, y, dx, dy)
self.ai = CAI.new(self.x, self.y, dx, dy)
if self.ai.dx then self.isright = true end -- start moving our enemy1
if self.ai.dy then self.isdown = true end -- start moving our enemy1
end
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:
SAI = Core.class()
function SAI:init(xtiny) -- tiny function
xtiny.processingSystem(self) -- called once on init and every update
end
function SAI:filter(ent) -- tiny function
return ent.ai
end
function SAI:onAdd(ent) -- tiny function
end
function SAI:onRemove(ent) -- tiny function
end
function SAI:process(ent, dt) -- tiny function
if ent.ai.dx and ent.ai.dy then -- DIAGONAL
if ent.x >= ent.ai.startpositionx + ent.ai.dx then
ent.isleft, ent.isright = true, false
ent.isup, ent.isdown = true, false
elseif ent.x <= ent.ai.startpositionx then
ent.isleft, ent.isright = false, true
ent.isup, ent.isdown = false, true
end
elseif ent.ai.dx then -- HORIZONTAL
if ent.x >= ent.ai.startpositionx + ent.ai.dx then
ent.isleft, ent.isright = true, false
elseif ent.x <= ent.ai.startpositionx then
ent.isleft, ent.isright = false, true
end
elseif ent.ai.dy then -- VERTICAL
if ent.y >= ent.ai.startpositiony + ent.ai.dy then
ent.isup, ent.isdown = true, false
elseif ent.y <= ent.ai.startpositiony then
ent.isup, ent.isdown = false, true
end
end
end
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:
...
-- the player (xspritelayer, x, y)
self.player1 = EPlayer1.new(self.camera, 12*16, 10*16)
self.tiny.world:addEntity(self.player1)
-- add systems to tiny-ecs
self.tiny.world:add(
SDrawable.new(self.tiny),
SDynamicBodies.new(self.tiny),
SPlayer1Control.new(self.tiny),
SAI.new(self.tiny)
)
...
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 7 Systems to move actors
Next: Tuto tiny-ecs demo Part 9 Player Shoots Enemies Die