SFML community forums

Help => General => Topic started by: Czarniecki on January 01, 2022, 05:25:24 pm

Title: Enemy patrolling
Post by: Czarniecki on January 01, 2022, 05:25:24 pm
I'm currently making a game, and trying to create an enemy class, that is patrolling within a certain range from it's origin. My code:
huh = body.getPosition().x
body.move(-(sf::Vector2f(body.getPosition().x, -velocity.y) - sf::Vector2f(huh,body.getPosition().y))* deltaTime);
 

The code above is moving in one direction, and it does the job just fine, but as the object moves, it continuously slows down, until it stops completely, and i'd rather have it walk all the way with the same speed. Any tips on how to do this?
Title: Re: Enemy patrolling
Post by: kojack on January 03, 2022, 04:26:58 am
In your code, the amount of vertical movement each frame is based on the difference between the velocity and the position. But these have different meanings.
As the position gets closer to the velocity, the difference gets less, resulting in the movement being less too (slowing down).

If you already have a velocity, you could replace the move line with:
body.move(velocity*deltaTime);

Although what I'd do is have a target position. Have a Vector2f target that contains the position of where the enemy is moving to. Each update find the vector between the enemy position and the target (target - body.getPosition()), normalise the vector (so the distance remaining doesn't affect speed) and move by this new normalised vector scaled by a speed and deltaTime.
sf::Vector2f dir = target - body.getPosition(); // Get the difference between target and enemy.
float length = sqrt(dir.x * dir.x + dir.y * dir.y); // Get the length of the difference.
// Normalising a vector is done by dividing the vector by its length.
if(length>0) // We don't want to divide by zero, bad things will happen.
        dir /= length;
body.move(dir * speed * deltaT); // Speed is a float that represents pixels per second.
 
That will make the sprite move towards its target at a fixed speed.
You can then add in a proximity check. Put this before the body.move:
if(length<proximity)
{
        // We got close enough to the target, do something.
}
where proximity is a float containing how close (in pixels) to a target the enemy needs to be to consider the target reached. In there you could do things like pick a new target, change the ai behavior, etc.
We use a proximity value instead of directly testing if the enemy position equals the target position because floating point error will mean the enemy almost never exactly hits the target, it will always be a tiny fraction off (like a target of (100,200) but a body position of (100.000001, 199.999999). So we give it a "near enough is good enough" check.