Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm creating a game where the enemies spawn randomly on a map then move towards the player every frame at a random speed. The map has no obstacles so the enemies should always move in a straight line. I wrote the movement function a few times but no matter what the enemies always hit 0, 45, 90, 135, 180, 225, 270, 315 angles but never a straight line. Here is an example of the code:

    base_speed = random();

    diff_x = abs(enemy_y_pos - player_x_pos);
    diff_y = abs(enemy_x_pos - player_y_pos);
     if (diff_x > diff_y) {
      y_speed = base_speed;
     } else if (diff_y > diff_x) {
      x_speed = base_speed;
     }

     if (enemy_x_pos < player_x_pos) {
      velocity.x = x_speed;
     } else if (enemy_x_pos > player_x_pos) {
      velocity.x = -x_speed;
     } else {
      velocity.x = 0;
     }

     if (enemy_y_pos < player_y_pos) {
      velocity.y = y_speed;
     } else if (enemy_y_pos > player_y_pos) {
      velocity.y = -y_speed;
     } else {
            velocity.y = 0;
    }

    enemy_x_pos = enemy_x_pos + velocity.x;
    enemy_y_pos = enemy_y_pos + velocity.y;

This is my first attempt at game programming. I guessing it's should use algorithm like Bresenham’s Line( http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm) but my attempts to implement have the same issue. How do I make enemies move in a straight line?

share|improve this question
add comment

2 Answers

up vote 17 down vote accepted

Bresenham's line algorithm was developed for fast drawing lines without using floating point operations (integer operations are faster). It is very interesting historicaly but not very good solution for a game (especialy because you cannot specify speed).

When doing a 2D movement use always vectors. This will do all the stuff for you. Sometimes is algebra just wonderful.

Vec2d playerPos;
Vec2d direction; // always normalized
float velocity;

update()
{
   direction = normalize(playerPos - enemyPos);
   playerPos = playerPos + direction * velocity;
}

There will be some vector2D class for your target language for sure.

share|improve this answer
    
That worked perfectly. Normalize was the function I needed. Thanks. –  user4761 Jan 21 '11 at 0:24
add comment

Are you calculating every frame? Your code sets either x_speed or y_speed to a random number and the other to zero (or the default). Let's say the enemy is at 0, 0 and player is at 20, 10. This looks like it will set x_speed to some random number each frame and move the enemy to the right until he is at 10, 0. Then the enemy will move either x or y each frame so it will seem he moves in a 45 degree angle up to 10, 10.

Notabene's vector explanation is right but here's how it works. The Vec2d will have an x and y component. In the example above, playerPos - enemyPos will give you a vector of (20, 10). normalize() changes the vector so that the length is 1. Currently the length is sqrt(20 * 20 + 10 * 10). That is about 22.36068. normalize divides both X and Y by this number, giving you about (0.89443, 0.44721) for the direction, which is a vector pointing from the enemy to the player with a length of 1. Multiplying this by your random speed does what you want.

However I would not calculate a new random speed each frame. You probably just want to set the random speed once, or have an initial speed and a target speed that you get closer to each frame. It doesn't make sense for your enemy to go 100 mph initially, then 50 mph for one frame and 200 mph for the next.

float targetSpeed = random(); // do this only rarely, or each frame if you don't mind slowing down and speeding up constantly

float acceleration = max(abs(targetSpeed - speed), 0.5) * sgn(targetSpeed - speed); // cap accel/decel at 0.5 per frame
speed = speed + acceleration;
share|improve this answer
    
Nice explanations and additions Jason, thanks. I like yours acceleration function –  Notabene Jan 20 '11 at 15:25
    
random() in that scope was a typo. Your explanation and code with what notabene wrote help me get the game working. Thanks. –  user4761 Jan 21 '11 at 0:27
    
Thanks a lot for the explanation. –  Brendan Long Feb 1 '11 at 5:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.