Enemy Movement strategy

Hi guys, I’ve created Random movement for my enemies on a tilemap.
Now I want that some enemies can “see” the player and therefore follow it.

For this reason I make a straight line from my enemy to my player.
The line can
hits obstacles (blocked tiles) so enemy can’t see the player and implement random movement
don’t hits obstacles so enemy can see the player and follow it.

to trace the straight line I’ve thought this code:



float startX, startY, endX, endY
float p, xp, yp;

startX = enemy.getX();
startY = enemy.getY();
endX = player.getX();
endY = player.getY();

p = ((float) endY - startY) / (endX - startX);

        for (x=startX; x<=endX; x++)
        {
            xp = x;
            yp = startY + (x - startX) * p;
            map.canMove(xp / map.TILE_SIZE, yp / map.TILE_SIZE);
        }

this code can trace only lines where x is positive.

you can suggest me any other solution??

I think there can be something better!

nobody has implemented this technique??

perhaps another algorithm can be “bresenham algorithm”… but, it’s a right implementation for this problem?

I think Bresenham is the right idea. However your game is organized. If you operate on tiles which are passable or not passable, you need to get each tile along the way. If you are organized in lines, i would suppose to make things easier. Get the starting point and the x offset per pixel and the y offset per pixel. Then get the x or y position of a line and see if your line of vision is on the obstacle line or not.

For example you look from 100,50 to 200,100. You have an offset of 2 pixels x for each pixel along y. Now take a horizontal line, it has a fixed y value and two endpoints with x values. Lets say the line is between 120,70 and 150,70. Calculate the x of your line of vision for an y of 70, its 140,70. So it hits the line.

No matter how you do it, you must make a difference in cases. You have 4 cases, depending on if x and y increment or decrement along the line. You cant handle it in one piece of code, you need code for every case. As fas as I know.

-JAW

Ok, so: this is my chasePlayer method where I implement bresenham Algorithm


public boolean chasePlayer(Map map, float startX, float startY, float endX, float endY)
    { 
        p1 = new Point((int)startX, (int)startY);
        p2 = new Point((int)endX, (int)endY);
        
        boolean steep = (Math.abs(p2.y - p1.y) > Math.abs(p2.x - p1.x));
        
        if (steep)
        {
            p1 = new Point((int)startY, (int)startX);
            p2 = new Point((int)endY, (int)endX);
        }
     
        if (p1.x > p2.x)
        { 
            Point temp = p1;
            p1 = p2;
            p2 = temp;
            temp = null;               
        }
        
        int deltax = p2.x - p1.x;
        int deltay = Math.abs(p2.y - p1.y);
        int error = 0;
        int ystep;
        int y = p1.y;
     
        if (p1.y < p2.y) 
            ystep = 1;     
        else 
            ystep = -1;
        
        for (int x = p1.x; x <= p2.x; x++)
        {
            if (steep)
            {
                if(map.cantMove(y / map.TILE_SIZE,x / map.TILE_SIZE))
                    return false;
            }
            else
            {
                if(map.cantMove(x / map.TILE_SIZE,y / map.TILE_SIZE))
                    return false;
            }                
            error = error + deltay;
            if (2*error >= deltax)
            {
                 y = y + ystep;
                 error = error - deltax;
            }
        }
        
        return true;
    }

the method return false if there is a blocked tile betwen player and enemy.

The chasePlayer is located in the “movement” class (that contain also randomMovement method).
The enemy class call chasePlayer;
if the value is false, then it call randomMovement, otherwise I verify
the x,y coordinate of enemy and player to determine the direction

Any suggestion or comment are appreciated!