1
\$\begingroup\$

I'm making AI to tell a minion to chase and attack the player.

I played Magicka, and the minion follows the player in a nice curved manner (left image), rather than what I currently have (right image), where the minion just keeps reacting the the player's changes in X,Y.

enter image description here

The code I have makes the chasing minion appear to move in a blocky way as it keeps trying to have its coordinates == the player's coordinates:

    if (enemy.pos.x <= game.data.playerX) {
        enemy.body.vel.x += enemy.body.accel.x * me.timer.tick;
    }
    else {
        enemy.body.vel.x += -enemy.body.accel.x * me.timer.tick;
    }
    if (enemy.pos.y <= game.data.playerY) {
        enemy.body.vel.y += enemy.body.accel.y * me.timer.tick;
    }
    else {
        enemy.body.vel.y += -enemy.body.accel.y * me.timer.tick;    
    }   

How can I achieve a more smooth transition effect?

\$\endgroup\$
1
  • \$\begingroup\$ Do I understand it right - you need to limit their angular velocity? There was very similar question few days ago. \$\endgroup\$
    – wondra
    Jan 25, 2015 at 0:31

1 Answer 1

1
\$\begingroup\$

You need to keep a enemy heading (direction) variable and only move the enemy along that direction.

Slowly rotate the enemy heading to face where it actually wants to go but only a few degrees per frame.

You move forward according to the dot product of the heading and where you should be heading. This prevents overshooting the target. The enemy will move a bit slower as its turning to reach the target.

enemy.pos += enemy.heading * enemy.max_speed * Max(0, DotProduct(Normalize(player.pos-enemy.pos), enemy.heading))

Max() is there to not walk backward but that is optional. Could also use Clamp(dot, -0.25, 1.0) if the enemy is allowed to walk backward slowly in a somewhat comical fashion.

A different way to go about it would be to only update the enemy's target every seconds or so, or have the enemy target lag behind the wanted target by interpolation or delay queue.

current_target_pos += (real_target_pos - current_target_pos) * 0.25;

There are many variations of these depending on the exact desired effect.

\$\endgroup\$
1
  • 4
    \$\begingroup\$ In short, look up 'steering behavior'. \$\endgroup\$
    – House
    Jan 25, 2015 at 2:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .