[solved] I need help with spawning entities.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
eqnox
Prole
Posts: 44
Joined: Fri Jul 31, 2015 2:36 pm

[solved] I need help with spawning entities.

Post by eqnox »

I am making a game and need an enemy spawned every 15 seconds and I want to use the same code for the enemy everytime I do it.

Code: Select all

enemy = {}

--this is where we set atributes of the enemy
function enemy.load()
	enemy.x = x
	enemy.y = y
	enemy.width = 10
	enemy.height = 10
	enemy.xvel = 0
	enemy.yvel = 0
	enemy.friction = 1
	enemy.speed = 500
end

--this is where the enemy is drawn from
function enemy.draw()
	love.graphics.setColor(255,0,0)
	love.graphics.rectangle("fill",enemy.x,enemy.y,enemy.width,enemy.height)

end

--this is where the phusics are handled
function enemy.physics(dt)
	enemy.x = enemy.x + enemy.xvel * dt
	enemy.y = enemy.y + enemy.yvel * dt
	enemy.xvel = enemy.xvel * (1 - math.min(dt*enemy.friction, 1))
	enemy.yvel = enemy.yvel * (1 - math.min(dt*enemy.friction, 1))
end

--this is where the movement is handled
function enemy.move(dt)
	if player.x > enemy.x and
	enemy.xvel < enemy.speed then
		enemy.xvel = enemy.xvel + enemy.speed * dt
	end

	if player.x < enemy.x and
	enemy.xvel > -enemy.speed then
		enemy.xvel = enemy.xvel - enemy.speed * dt
	end

	if player.y > enemy.y and
	enemy.yvel < enemy.speed then
		enemy.yvel = enemy.yvel + enemy.speed * dt
	end

	if player.y < enemy.y and
	enemy.yvel > -enemy.speed then
		enemy.yvel = enemy.yvel - enemy.speed * dt
	end
end

function enemy.wallCollision(dt)
	if enemy.x < 0 then
		enemy.x = 0
		enemy.xvel = 0
	end

	if enemy.y < 0 then
		enemy.y = 0
		enemy.yvel = 0
	end

	if enemy.x + enemy.width > love.graphics.getWidth() then
		enemy.x = love.graphics.getWidth() - enemy.width
		enemy.xvel = 0
	end

	if enemy.y + enemy.height > love.graphics.getHeight() then
		enemy.y = love.graphics.getHeight() - enemy.height
		enemy.yvel = 0
	end
end 


--functions are put here to be easily managaed in the main file
function enemy.LOAD()
	enemy.load()
end

function enemy.UPDATE(dt)
	enemy.physics(dt)
	enemy.move(dt)
	enemy.wallCollision(dt)
end

function enemy.DRAW()
	enemy.draw()
end
this is the code I already have.
how would I make several enemy s out of this without overwriting the first one I made.
Last edited by eqnox on Tue Aug 18, 2015 10:58 pm, edited 1 time in total.
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: I need help with spawning entities.

Post by Ranguna259 »

There are lots of ways to do this, here's the method I use.
First create an enemy table that will store all your enemy entities ( I'm gonna do all of this in a seperate file, let's call it enemy.lua):

Code: Select all

--enemy.lua
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it
The enemy table will hold all enemy instances and the enemyClass table will hold all the enemy related functions.
Now lets code a function to create enemies:

Code: Select all

--enemy.lua
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it

local newEnemy = function(x,y)
   local enmy = {} --temporary table to hold all the play atributes
   enmy.x = x
   enmy.y = y
   enmy.width = 10
   enmy.height = 10
   enmy.xvel = 0
   enmy.yvel = 0
   enmy.friction = 1
   enmy.speed = 500
   setmetatable(enmy, enemyClass) --this will link all the enemyClass functions to the newly created enemy.
   table.insert(enemy, enmy) --this will store the newly created enemy in the enemy table.
   return enmy
end

return newEnemy
To create an enemy all you need to do is to run newEnemy, like so:

Code: Select all

--main.lua
newEnemy = require('enemy.lua')
function love.load()
   badGuy = newEnemy(100,100)
end
There you have it but we still need to draw it, to do this simply add the drawing function to the enemyClass:

Code: Select all

--enemy.lua
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it

function enemyClass:draw()
   love.graphics.setColor(255,0,0)
   love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
end

local newEnemy = function(x,y)
   local enmy = {} --temporary table to hold all the play atributes
   enmy.x = x
   enmy.y = y
   enmy.width = 10
   enmy.height = 10
   enmy.xvel = 0
   enmy.yvel = 0
   enmy.friction = 1
   enmy.speed = 500
   setmetatable(enmy, enemyClass) --this will link all the enemyClass functions to the newly created enemy.
   table.insert(enemy, enmy) --this will store the newly created enemy in the enemy table.
   return enmy
end

return newEnemy
Notice the ':' instead of '.' in the draw function between enemyClass and draw ?
That allows us to use self inside the function, it gives us more flexibility.
To actualy draw the enemy all you need to do is this:

Code: Select all

--main.lua
newEnemy = require('enemy.lua')
function love.load()
   badGuy = newEnemy(100,100)
end

function love.draw()
   badGuy:draw()
end
Notice the ':' again, that is necessay, or else self will not work.

Now add all your other functions to the enemyClass table, don't forget to use ':' instead of '.' between enemyClass and the name of your function, always use self inside the function too. self will store the enemy entity that is currently being called.

But imagine that you have a load of enemies and you want do draw them all with a single function. Here's how you do it:

Code: Select all

--enemy.lua
local enemyTBL = {} --this will store all the functions that operate on all the enemy entities
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it

function enemyClass:draw()
   love.graphics.setColor(255,0,0)
   love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
end

enemyTBL.newEnemy = function(x,y) -- now the newEnemy function will be stored inside the enemyTBL table
   local enmy = {} --temporary table to hold all the play atributes
   enmy.x = x
   enmy.y = y
   enmy.width = 10
   enmy.height = 10
   enmy.xvel = 0
   enmy.yvel = 0
   enmy.friction = 1
   enmy.speed = 500
   setmetatable(enmy, enemyClass) --this will link all the enemyClass functions to the newly created enemy.
   table.insert(enemy, enmy) --this will store the newly created enemy in the enemy table.
   return enmy
end


-- enemyTBL functions, these will operate on all the enemy entites with a single call
function enemyTBL.draw()
   for i,v in ipairs(enemy) do
      v:draw()
   end
end

--return enemyTBL instead of the old newEnemy
return enemyTBL 
The enemyTBL will store all the functions that operate on all the enemies at once.
Notice that now I'm using '.' again instead of ':' on all enemyTBL functions, thats because enemyTBL is not a class, it's a simple table.
Now in main.lua:

Code: Select all

--main.lua
enemy= require('enemy.lua')
function love.load()
   for i=1,100 do
      enemy.newEnemy(100 + 11*(i-1),100) --this will create a row of enemies form the point (100,100) to (9990,100), creating a total of 100 enemies
   end
end

function love.draw()
   enemy.draw() --this function will draw all the 100 enemies, yey
end
That's all, if you don't understand something then feel free to ask :)

TL;DR:
Read everything, this will improve your programming skills ;)
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
User avatar
eqnox
Prole
Posts: 44
Joined: Fri Jul 31, 2015 2:36 pm

Re: I need help with spawning entities.

Post by eqnox »

Ranguna259 wrote:There are lots of ways to do this, here's the method I use.
First create an enemy table that will store all your enemy entities ( I'm gonna do all of this in a seperate file, let's call it enemy.lua):

Code: Select all

--enemy.lua
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it
The enemy table will hold all enemy instances and the enemyClass table will hold all the enemy related functions.
Now lets code a function to create enemies:

Code: Select all

--enemy.lua
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it

local newEnemy = function(x,y)
   local enmy = {} --temporary table to hold all the play atributes
   enmy.x = x
   enmy.y = y
   enmy.width = 10
   enmy.height = 10
   enmy.xvel = 0
   enmy.yvel = 0
   enmy.friction = 1
   enmy.speed = 500
   setmetatable(enmy, enemyClass) --this will link all the enemyClass functions to the newly created enemy.
   table.insert(enemy, enmy) --this will store the newly created enemy in the enemy table.
   return enmy
end

return newEnemy
To create an enemy all you need to do is to run newEnemy, like so:

Code: Select all

--main.lua
newEnemy = require('enemy.lua')
function love.load()
   badGuy = newEnemy(100,100)
end
There you have it but we still need to draw it, to do this simply add the drawing function to the enemyClass:

Code: Select all

--enemy.lua
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it

function enemyClass:draw()
   love.graphics.setColor(255,0,0)
   love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
end

local newEnemy = function(x,y)
   local enmy = {} --temporary table to hold all the play atributes
   enmy.x = x
   enmy.y = y
   enmy.width = 10
   enmy.height = 10
   enmy.xvel = 0
   enmy.yvel = 0
   enmy.friction = 1
   enmy.speed = 500
   setmetatable(enmy, enemyClass) --this will link all the enemyClass functions to the newly created enemy.
   table.insert(enemy, enmy) --this will store the newly created enemy in the enemy table.
   return enmy
end

return newEnemy
Notice the ':' instead of '.' in the draw function between enemyClass and draw ?
That allows us to use self inside the function, it gives us more flexibility.
To actualy draw the enemy all you need to do is this:

Code: Select all

--main.lua
newEnemy = require('enemy.lua')
function love.load()
   badGuy = newEnemy(100,100)
end

function love.draw()
   badGuy:draw()
end
Notice the ':' again, that is necessay, or else self will not work.

Now add all your other functions to the enemyClass table, don't forget to use ':' instead of '.' between enemyClass and the name of your function, always use self inside the function too. self will store the enemy entity that is currently being called.

But imagine that you have a load of enemies and you want do draw them all with a single function. Here's how you do it:

Code: Select all

--enemy.lua
local enemyTBL = {} --this will store all the functions that operate on all the enemy entities
local enemy = {}
local enemyClass = {}
enemyClass.__index = function(t,i) return enemyClass[i] end --I don't know if this is necessary but I always write it

function enemyClass:draw()
   love.graphics.setColor(255,0,0)
   love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
end

enemyTBL.newEnemy = function(x,y) -- now the newEnemy function will be stored inside the enemyTBL table
   local enmy = {} --temporary table to hold all the play atributes
   enmy.x = x
   enmy.y = y
   enmy.width = 10
   enmy.height = 10
   enmy.xvel = 0
   enmy.yvel = 0
   enmy.friction = 1
   enmy.speed = 500
   setmetatable(enmy, enemyClass) --this will link all the enemyClass functions to the newly created enemy.
   table.insert(enemy, enmy) --this will store the newly created enemy in the enemy table.
   return enmy
end


-- enemyTBL functions, these will operate on all the enemy entites with a single call
function enemyTBL.draw()
   for i,v in ipairs(enemy) do
      v:draw()
   end
end

--return enemyTBL instead of the old newEnemy
return enemyTBL 
The enemyTBL will store all the functions that operate on all the enemies at once.
Notice that now I'm using '.' again instead of ':' on all enemyTBL functions, thats because enemyTBL is not a class, it's a simple table.
Now in main.lua:

Code: Select all

--main.lua
enemy= require('enemy.lua')
function love.load()
   for i=1,100 do
      enemy.newEnemy(100 + 11*(i-1),100) --this will create a row of enemies form the point (100,100) to (9990,100), creating a total of 100 enemies
   end
end

function love.draw()
   enemy.draw() --this function will draw all the 100 enemies, yey
end
That's all, if you don't understand something then feel free to ask :)

TL;DR:
Read everything, this will improve your programming skills ;)
You are amazing, thank you!
This helped me understand a lot of things I have seen but not known why people do it.
very helpful.
User avatar
eqnox
Prole
Posts: 44
Joined: Fri Jul 31, 2015 2:36 pm

Re: I need help with spawning entities.

Post by eqnox »

But now where I call my new enemy I get an error saying. attempt to call global "newEnemy". what should I do to fix this.
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: I need help with spawning entities.

Post by Ranguna259 »

Does it say it's a nil value ?
if it says it's a table value then you need to require the enemy file like so:

Code: Select all

enemy = require('enemy')
And run it like this:

Code: Select all

badGuy = enemy.newEnemy(100,100)
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
User avatar
eqnox
Prole
Posts: 44
Joined: Fri Jul 31, 2015 2:36 pm

Re: I need help with spawning entities.

Post by eqnox »

Alright I got that part working, but how would I add back in the stuff that I had before for the enemy movement and such?
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: I need help with spawning entities.

Post by Ranguna259 »

Ranguna259 wrote:Now add all your other functions to the enemyClass table, don't forget to use ':' instead of '.' between enemyClass and the name of your function, always use self inside the function too. self will store the enemy entity that is currently being called.
In your exemple, this:

Code: Select all

function enemy.physics(dt)
   enemy.x = enemy.x + enemy.xvel * dt
   enemy.y = enemy.y + enemy.yvel * dt
   enemy.xvel = enemy.xvel * (1 - math.min(dt*enemy.friction, 1))
   enemy.yvel = enemy.yvel * (1 - math.min(dt*enemy.friction, 1))
end
Would look something like this:

Code: Select all

function enemyClass:physics(dt)
   self.x = self.x + self.xvel * dt
   self.y = self.y + self.yvel * dt
   self.xvel = self.xvel * (1 - math.min(dt*self.friction, 1))
   self.yvel = self.yvel * (1 - math.min(dt*self.friction, 1))
end
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
User avatar
eqnox
Prole
Posts: 44
Joined: Fri Jul 31, 2015 2:36 pm

Re: I need help with spawning entities.

Post by eqnox »

Alright, thanks I guess I missed that part.
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: I need help with spawning entities.

Post by Ranguna259 »

No problem, you are welcome :)
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
Post Reply

Who is online

Users browsing this forum: Google [Bot], KayleMaster and 62 guests