Page 1 of 1
Finding the closest position
Posted: Sat Sep 27, 2014 12:21 am
by BruceTheGoose
Code: Select all
allies = {}
enemies = {}
for _,v in ipairs(allies) do
if v.target == 0 then
for i = 1, #enemies do
v.currentBest = getMagnitude(v.x,enemies[i].x + enemy:getWidth()/2,v.y,enemies[i].y + enemy:getHeight()/2)
if getMagnitude(v.x,enemies[i].x + enemy:getWidth()/2,v.y,enemies[i].y + enemy:getHeight()/2) >= v.currentBest then
v.target = enemies[i]
v.angle = math.atan2((enemies[i].y-v.y),(enemies[i].x - v.x))
end
end
end
end
So I'm having trouble finding the appropriate way to find the nearest position of all the enemies and setting the target to the closest enemy.
The above code works but it does not look for the closest enemy. Instead, the allies go to the newest enemy spawned. If you can help me I would really appreciate it.
Re: Finding the closest position
Posted: Sat Sep 27, 2014 12:44 am
by kikito
Funny, I was re-reading this blogpost in which I wrote code to do the very thing that you ask. See if this helps you:
http://kiki.to/blog/2012/03/16/small-fu ... -universe/
Re: Finding the closest position
Posted: Sat Sep 27, 2014 12:47 am
by BruceTheGoose
Coincidence? Thank you so much I'll look into it
Re: Finding the closest position
Posted: Sat Sep 27, 2014 1:05 am
by BruceTheGoose
If you use lots of functions like this one, your code tends to become unmanageable, especially if you return to it after not touching it for several months. It’s a code that you understand while you are writing, and certainly the machine understands it, but it doesn’t have “signposts” for future visitors. They have to “explore” it to know it.
I'm gonna rewrite all my code now
Re: Finding the closest position
Posted: Sat Sep 27, 2014 2:14 am
by BruceTheGoose
So I re-wrote my bullets and I'm getting a stupid error. I suspect the reason for the error is that I haven't created a new bullet and I'm calling its update function. Here is the code.
Code: Select all
Bullet = {}
function Bullet:New(x,y,x1,y1,rot,type,damage,speed)
local startX = x
local startY = y
local angle = math.atan2((y1+troop:getHeight()/2-startY),(x1+troop:getWidth()/2-startX))
self.x = x
self.y = y
self.rot = rot
self.type = type
self.damage = damage
self.speed = speed
self.y1 = y1
self.x1 = x1
self.dx = self.speed * math.cos(angle)
self.dy = self.speed * math.sin(angle)
self.timer = 0
end
function Bullet:update(dt)
-- self:collide()
self.x = self.x + (self.dx * dt)
self.y = self.y + (self.dy * dt)
self.timer = self.timer + dt
if self.timer >= 2 then
--self:remove()
end
end
function Bullet:draw()
if self.type == "elixir" then
love.graphics.draw(elx,self.x,self.y,self.rot,1,1,elx:getWidth()/2,elx:getHeight()/2)
end
end
function Bullet:collide()
end
function Bullet:remove()
self = nil
end
The error is: bullet.lua:28: attempt to perform arithmetic on field 'dx' (a nil value)
Also how would I remove a bullet? Would
work?
Re: Finding the closest position
Posted: Sat Sep 27, 2014 8:57 am
by Robin
Please upload a .love. I suspect you're calling
Bullet:update(dt) somewhere and that'll never work.
Also,
Bullet:New is... not what you want it to do.
So instead:
Code: Select all
Bullet.__index = Bullet
function Bullet.New(x,y,x1,y1,rot,type,damage,speed)
local startX = x
local startY = y
local angle = math.atan2((y1+troop:getHeight()/2-startY),(x1+troop:getWidth()/2-startX))
local self = {} -- kind of misleading name, but I'm too lazy to change all the other variables
self.x = x
self.y = y
self.rot = rot
self.type = type
self.damage = damage
self.speed = speed
self.y1 = y1
self.x1 = x1
self.dx = self.speed * math.cos(angle)
self.dy = self.speed * math.sin(angle)
self.timer = 0
return setmetatable(self, Bullet)
end
Something like that.
Recommended reading:
Chapter 13 of PIL.
BruceTheGoose wrote:Also how would I remove a bullet? Would
work?
No. You need to keep a list of bullets and remove them from that list.
Re: Finding the closest position
Posted: Sat Sep 27, 2014 3:49 pm
by BruceTheGoose
Here
Re: Finding the closest position
Posted: Sun Sep 28, 2014 9:16 am
by Robin
Okay, so you do a lot of things like:
Code: Select all
for _,v in ipairs(Bullet) do Bullet.update(dt)end
That doesn't work! That function needs a "self" argument. Either do:
Code: Select all
for _,v in ipairs(Bullet) do Bullet.update(v, dt)end
or:
Code: Select all
for _,v in ipairs(Bullet) do v:update(dt)end
(This is possible because of the __index and setmetatable I suggested.)
The same goes for Tower and Troop. So what's left to do?
When creating new objects, do something like this:
Code: Select all
Tower[#Tower + 1] = Tower.new(...)
Insert this at the end of love.update:
Code: Select all
for i = #Bullet, 1, -1 do if Bullet[i].remove then table.remove(Bullet, i) end end
Then you can do for remove:
Code: Select all
function Bullet.remove(self)
self.remove = true
end
Re: Finding the closest position
Posted: Sun Sep 28, 2014 5:57 pm
by BruceTheGoose
Thank you so much!