Object AI problems.

Hello,

I am working on an app that involves objects (enemies) following another object (the player) around a level. I have walls setup around each level also that work off of a collision detection code not using physics.

I have the object’s working so they chase the player and so they do not run through the walls. The problem I’m having right now is that once the enemy runs into a wall that the player is on the other side of, it just keeps running into the wall and bouncing off of it instead of finding a way around the wall.

I have tried to code this on my own but have not been able to get it to successfully work so I have decided to once again come to the Corona Community for assistance.

Here is an example of my current code for creating two enemies and having them move and detect collisions with the walls.

 local Npc = {}  
  
Npc[1] = display.newImageRect( "Sprite.png", 25, 35 )  
Npc[1].x = 568  
Npc[1].y = -18  
 Npc[1].dir = 1   
 localGroup:insert(Npc[1])  
  
Npc[2] = display.newImageRect( "Sprite.png", 25, 35 )  
Npc[2].x = 480  
Npc[2].y = 219  
 Npc[2].dir = 1   
 localGroup:insert(Npc[2])  
  
 local function hasCollided(obj1, obj2)  
 if obj1 == nil then  
 return false  
 end  
 if obj2 == nil then  
 return false  
 end  
   
 local left = obj1.contentBounds.xMin \<= obj2.contentBounds.xMin and obj1.contentBounds.xMax \>= obj2.contentBounds.xMin  
 local right = obj1.contentBounds.xMin \>= obj2.contentBounds.xMin and obj1.contentBounds.xMin \<= obj2.contentBounds.xMax  
 local up = obj1.contentBounds.yMin \<= obj2.contentBounds.yMin and obj1.contentBounds.yMax \>= obj2.contentBounds.yMin  
 local down = obj1.contentBounds.yMin \>= obj2.contentBounds.yMin and obj1.contentBounds.yMin \<= obj2.contentBounds.yMax  
 return (left or right) and (up or down)  
 end  
  
 local function NpcMovement ( event )  
 if (gameState == "Play") then  
 local randomDir = math.random(1,2)  
  
 for i = 1, #Npc do  
 if ( ( myPlayer.x \> Npc[i].x ) and ( myPlayer.y \< Npc[i].y ) ) then -- To the right and up  
 if ( randomDir == 1 ) then  
 if ( Npc[i].blocked == 3 ) then  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].dir = 1   
 else  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].dir = 3  
 end  
 else  
 if ( Npc[i].blocked == 1 ) then  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].dir = 3  
 else  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].dir = 1  
 end  
 end  
 elseif ( ( myPlayer.x \< Npc[i].x ) and ( myPlayer.y \< Npc[i].y ) ) then -- To the left and up  
 if ( randomDir == 1 ) then  
 if ( Npc[i].blocked == 4 ) then  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].dir = 1   
 else  
 Npc[i].x = Npc[i].x - 5  
 Npc[i].dir = 4  
 end  
 else  
 if ( Npc[i].blocked == 1 ) then  
 Npc[i].x = Npc[i].x - 5  
 Npc[i].dir = 4  
 else  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].dir = 1  
 end  
 end   
 elseif ( ( myPlayer.x \> Npc[i].x ) and ( myPlayer.y \> Npc[i].y ) ) then -- To the right and down  
 if ( randomDir == 1 ) then  
 if ( Npc[i].blocked == 3 ) then  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].dir = 2   
 else  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].dir = 3   
 end  
 else  
 if ( Npc[i].blocked == 2 ) then  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].dir = 3   
 else  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].dir = 2  
 end  
 end   
 elseif ( ( myPlayer.x \< Npc[i].x ) and ( myPlayer.y \> Npc[i].y ) ) then -- To the left and down  
 if ( randomDir == 1 ) then  
 if ( Npc[i].blocked == 4 ) then  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].dir = 2   
 else  
 Npc[i].x = Npc[i].x - 5  
 Npc[i].dir = 4   
 end  
 else  
 if ( Npc[i].blocked == 2 ) then  
 Npc[i].x = Npc[i].x - 5  
 Npc[i].dir = 4   
 else  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].dir = 2   
 end  
 end  
 elseif ( ( myPlayer.x == Npc[i].x ) and ( myPlayer.y \< Npc[i].y ) ) then -- Same X and up  
 if ( Npc[i].blocked == 2 ) then  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].dir = 2   
 else  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].dir = 1  
 end  
 elseif ( ( myPlayer.x == Npc[i].x ) and ( myPlayer.y \> Npc[i].y ) ) then -- Same X and down  
 if ( Npc[i].blocked == 1 ) then  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].dir = 1  
 else  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].dir = 2   
 end  
  
 elseif ( ( myPlayer.x \> Npc[i].x ) and ( myPlayer.y == Npc[i].y ) ) then -- Same Y and right  
 if ( Npc[i].blocked == 4 ) then  
 Npc[i].x = Npc[i].x - 5  
 Npc[i].dir = 4   
 else  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].dir = 3  
 end  
 elseif ( ( myPlayer.x \< Npc[i].x ) and ( myPlayer.y == Npc[i].y ) ) then -- Same Y and left  
 if ( Npc[i].blocked == 3 ) then  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].dir = 3  
 else   
 Npc[i].x = Npc[i].x - 5  
 Npc[i].dir = 4  
 end   
 end  
  
 for n = 1, #wall do   
 if hasCollided(Npc[i], wall[n]) == false then  
 else  
 if ( Npc[i].dir == 1 ) then  
 Npc[i].y = Npc[i].y + 5  
 Npc[i].blocked = 2  
 elseif ( Npc[i].dir == 2 ) then  
 Npc[i].y = Npc[i].y - 5  
 Npc[i].blocked = 1  
 elseif ( Npc[i].dir == 3 ) then  
 Npc[i].x = Npc[i].x - 5  
 Npc[i].blocked = 4  
 elseif ( Npc[i].dir == 4 ) then  
 Npc[i].x = Npc[i].x + 5  
 Npc[i].blocked = 3  
 end   
 end   
 end  
  
 if ( Npc[i].x \< 15 ) then  
 Npc[i].x = 15  
 end  
 if ( Npc[i].x \> 780 ) then  
 Npc[i].x = 780  
 end  
 if ( Npc[i].y \< 15 ) then  
 Npc[i].y = 15  
 end   
 if ( Npc[i].y \> 820 ) then  
 Npc[i].y = 820  
 end   
 end  
  
 end  
 end  
  
 for i = 1, #Npc do  
 timer.performWithDelay(600, NpcMovement, 0 )  
 end  

I appreciate any help I can get with this because right now I am stuck on it.

Thanks,

  • Ertzel [import]uid: 69700 topic_id: 15939 reply_id: 315939[/import]

I’m still having problems with this system if anyone can help. [import]uid: 69700 topic_id: 15939 reply_id: 60704[/import]

Hi.

Just a few ideas for you.

  1. Tell the enemy if he is colliding with a wall to walk up or down (depending on) like so he is still walking against the wall but moves down or up it also until it is free of the obstacle.

  2. Do some distance checking between the player and the wall, or the player and the enemy. If the player is further away than the enemy and the enemy collides with the wall then you know the wall is the obstacle and tell the enemy to walk up or down until it is no longer colliding with the wall.

[import]uid: 84637 topic_id: 15939 reply_id: 60721[/import]