A.I Programming

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
ruthven
Prole
Posts: 2
Joined: Wed Nov 27, 2013 11:20 pm

A.I Programming

Post by ruthven »

Hello everyone! :awesome: , so, I've learning just for couple of days Love and Lua, great indeed, reading and stuff, so I did this little code trying to emulete some AI or something, just a guy walking forever in square, so I did everything with IF's statements and counters, obviously must be a better way to do the same using other stuff, so that's the question to the experts, What's the proper way to do this kind of events in Love and of course using Lua? ^^

Waiting for suggestions.. thanks

here's the code and the .love:

Code: Select all

if veces == 1  then
          player2.x = player2.x + player2.speed * dt
          
      elseif veces == 2 then
          player2.x = player2.x - player2.speed * dt
      elseif veces == 3 then
          player2.y = player2.y - player2.speed * dt
      elseif veces == 4 then
          player2.y = player2.y + player2.speed * dt
      end    
       if player2.x >= 600 and veces == 1 then 
             veces = 2
             semaforo.tiempo = semaforo. tiempo + 1 --veces que llega a punto
             player2.animation = player2.animations.left
      
      elseif player2.x <= 400 and veces == 2 then
             veces = 1
             semaforo.tiempo = semaforo. tiempo + 1  --veces llega
             player2.animation = player2.animations.right
      end
      --hero square walking
      if semaforo.tiempo == 3 then
          veces = 3
          player2.animation = player2.animations.up
      elseif semaforo.tiempo == 6 then
             veces = 2
             player2.animation = player2.animations.left
            -- semaforo.tiempo = 0 --reset time
      elseif semaforo.tiempo == 9 then
             veces = 4
             player2.animation = player2.animations.down
       --      semaforo.tiempo = 2
      elseif semaforo.tiempo == 12 then
             veces = 1
             player2.animation = player2.animations.right
             semaforo.tiempo = 0             
      end
      if player2.y <= 100 and veces == 3 then
        veces = 4
        semaforo.tiempo = semaforo. tiempo + 1 --veces que llega a punto
        player2.animation = player2.animations.down
      elseif player2.y >= 410 and veces == 4 then
             veces = 3
             semaforo.tiempo = semaforo. tiempo + 1 --veces que llega a punto
             player2.animation = player2.animations.up
end
Attachments
walking.love
love file
(321.72 KiB) Downloaded 110 times
User avatar
iPoisonxL
Party member
Posts: 227
Joined: Wed Feb 06, 2013 3:53 am
Location: Australia
Contact:

Re: A.I Programming

Post by iPoisonxL »

That's the way I would do it. I'm not sure if there's a better way at all.

Code: Select all

      L
    L Ö
    Ö V
L Ö V E
Ö B E
V E
E Y
Website
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: A.I Programming

Post by kikito »

If you put the coordinates of the square in a table, you can have a smaller algorithm, which will be also more maintainable and easier to extend.

This could be the path:

Code: Select all

local path = { {x=0,y=0}, {x=600,y=0}, {x=600,y=400}, {x=0,y=400} }
You will also need some variables to know where you want to go next. Depending on your implementation, you will need to put them in local variables or inside your player/monster, as attributes. I would have two: one for the index, and one for the goal itself.

Code: Select all

local current_goal_index = 1
local current_goal = path[current_goal_index]
Now you need to move your player up/down or left/right depending on whether he's up/down of current_goal.y, and left/right of current_goal.y.

Once he's very near current_goal, you can assume he's reached it. Don't try to test for equality, because dt makes it very difficult to 'land' on exactly one number. If the sum of the abs differences is < 1, then you are near enough.

Code: Select all

local dx, dy = math.abs(player.x - current_goal.x), math.abs(player.y - current_goal.y)
if dx + dy < 1 then -- the player is on the goal, proceed to the next
To proceed to the next goal you have to increase current_goal_index by 1, but if it's greater than #path you have to make it one. That can be done with a little math with the % operator:

Code: Select all

if dx + dy < 1 then -- the player is on the goal, proceed to the next
  current_goal_index = (current_goal_index + 1) % #path
end
That's the gist of it. I hope it is enough for you to fill the blanks.

This method has the advantage of not only accepting rectangles of any kind; you can give your player any polygon of any arbitrary size. It might not look great if the player only moves up/down and left/right. You might need some trigonometry in order to make it move just the right amount in the right direction instead. It's also more maintainable since there are no "magic numbers" laying around in your code - if you want to change the square width to 500, you have to make changes only in path. Also, if you make path a member of player, you could have different players following different paths.
When I write def I mean function.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: A.I Programming

Post by ivan »

kikito's answer is on the right path.
To make your agent steer smoothly, you have to look into "path following" which Buckland discusses in his book based on the work of Craig Reynolds.
More generally speaking, your AI system could use one of several approaches.

1) Finite state machines are one of the easier design solutions where you could have a "followPath" state that is initialized using a table of positions.

2) Behavior trees are a little more complicated where behaviors are decomposed into "atomic goals" so you would write AI scripts that (more or less) look like:

Code: Select all

follow = sequence()
follow [1] = move_to(200, 200)
follow [2] = move_to(0, 0)
follow [3] = move_to(100, 100)
follow [4] = move_to(200, 200)
ai.set_goal ( agent, follow )
ruthven
Prole
Posts: 2
Joined: Wed Nov 27, 2013 11:20 pm

Re: A.I Programming

Post by ruthven »

Thank you so much guys, indeed is a great improvement your method kikito :ultrahappy: and more elegant, I've changed it, ivan, I'll get the book, thanks, ,
Edit: I was wrong,,, :? I thought I have it but there's something I'm missing, my hero does the square but sometimes he loops, must be something bad in my ifs to reach the current_goal, I can't figure out what, some help will be great.. :awesome:
Attachments
hero2.love
failed test
(321.77 KiB) Downloaded 94 times
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Yahoo [Bot] and 4 guests