Enemy waypoint blues

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
jack4000
Prole
Posts: 2
Joined: Sat Nov 22, 2014 10:59 am

Enemy waypoint blues

Post by jack4000 »

Hello Ladies and Gents, I'm having an issue with moving my enemies between waypoints.

I have a working function that moves the enemy to whatever x and y you enter, and I have a table of waypoints like so:

Code: Select all

wps = {{100,100}, {200, 200}, {100,200}}
Currently when the map loads the enemy starts at the first wp, so the second wp is where they need to head to. Then the third, then back to the first, and onwards... I'm having trouble with returning the initial destination wp and when they reach it, cycling on to the next in the wps table.

I've tried comparing enemy.x == wps[1][1], etc, and I've tried working out distances between points but end up tying myself in knots. I'm fairly new to love2d and Lua and I feel like I'm missing something obvious. I haven't posted my attempts at doing this as they don't work and probably wouldn't be helpful, but I can if you think it'd be useful.

If anyone has any advice or working examples it'd be a great help!

Cheers,
Jack.
User avatar
undef
Party member
Posts: 438
Joined: Mon Jun 10, 2013 3:09 pm
Location: Berlin
Contact:

Re: Enemy waypoint blues

Post by undef »

Hey there Jack, and welcome to the community!

What you will have to look up is linear interpolation.

https://en.wikipedia.org/wiki/Interpolation

This is a very basic skill, which enables you to perform a transition between values.
This is something you will use all the time, when programming.

Linear interpolation (often called lerp) looks like this in lua:

Code: Select all

-- a is the initial value, b is the destination value, t is a value between 0 and 1 indicating the progress of the "path" between a and b.
function lerp( a, b, t )
    return a + (b - a)*t -- for t==0 you get a, for t==1 you get b, for t==0.5 you get the middle of the two and so on...
end
So this function can be applied on any numerical values. It doesn't matter if it's coodinates, rgb values or whatever.
Play around with this and you will get the hang of it!
twitter | steam | indieDB

Check out quadrant on Steam!
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Enemy waypoint blues

Post by ivan »

Good answer from undef. Linear interpolation will work for animations but for "autonomously moving agents" a better approach might be "steering".
Take a look at the bottom of:
http://2dengine.com/doc_1_3_10/gs_vector.html

Code: Select all

-- move the agent to target point, return true when we arrive
agent.moveto = function(agent, target, dt)
  -- find the agent's "step" distance for this frame
  local step = agent.speed * dt

  -- find the distance to target
  local distx, disty = target.x - agent.x, target.y - agent.y
  local dist = math.sqrt(distx*distx + disty*disty)

  if dist <= step then
    -- we have arrived
    agent.x = target.x
    agent.y = target.y
    return true
  end

  -- get the normalized vector between the target and agent
  local nx, ny = distx/dist, disty/dist

  -- find the movement vector for this frame
  local dx, dy = nx * step, ny * step

  -- keep moving
  agent.x = agent.x + dx
  agent.y = agent.y + dy
  return false
end
Ideally, you want to modify the "velocity" of the agent not his position.
Currently when the map loads the enemy starts at the first wp, so the second wp is where they need to head to. Then the third, then back to the first, and onwards... I'm having trouble with returning the initial destination wp and when they reach it, cycling on to the next in the wps table.
Depends on your implementation. You can try something like:

Code: Select all

agent.wps = {{x=100,y=100}, {x=200, y=200}, {x=100,y=200}}
agent.nextwp = 1
agent.x, agent.y = 100, 100 -- agent's "current" position
agent.speed = 100 -- in pixels per second

agent.movetowp = function(agent, dt)
  -- no waypoint set?
  if agent.nextwp == nil then
    return
  end
  -- move
  local target = agent.wps[agent.nextwp]
  if agent:moveto(target) then
    -- we have arrived!
    agent.nextwp = agent.nextwp + 1
    -- loop?
    if agent.nextwp > #agent.wps then
      agent.nextwp = 1
    end
  end
end

agent.update = function(agent, dt)
  agent:movetowp(dt)
end
If you set .nextwp to "nil" the agent will stop moving, otherwise it will cycle through all the waypoints.
jack4000
Prole
Posts: 2
Joined: Sat Nov 22, 2014 10:59 am

Re: Enemy waypoint blues

Post by jack4000 »

undef, ivan, thank you both very much, and thanks for the welcome.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 214 guests