Finding the closest position

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

Finding the closest position

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

Re: Finding the closest position

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

Re: Finding the closest position

Post by BruceTheGoose »

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

Re: Finding the closest position

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

Re: Finding the closest position

Post 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

Code: Select all

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

Re: Finding the closest position

Post 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

Code: Select all

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

Re: Finding the closest position

Post by BruceTheGoose »

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

Re: Finding the closest position

Post 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
Help us help you: attach a .love.
User avatar
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Finding the closest position

Post by BruceTheGoose »

Thank you so much!
"I don't know."
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 24 guests