Finding the closest position

General discussion about LÖVE, Lua, game development, puns, and unicorns.
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Finding the closest position

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.
"I don't know."
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

Re: Finding the closest position

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/
When I write def I mean function.
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Finding the closest position

Coincidence? Thank you so much I'll look into it
"I don't know."
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Finding the closest position

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
"I don't know."
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Finding the closest position

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

Code: Select all

self = nil
work?
"I don't know."
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Finding the closest position

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.

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

Code: Select all

self = nil
work?
No. You need to keep a list of bullets and remove them from that list.
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Finding the closest position

Here
"I don't know."
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Finding the closest position

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