Advertisement

Following enemy CSFML

Started by April 02, 2019 09:25 AM
18 comments, last by polpel 5 years, 8 months ago

Hi,

So basically I'm developing a 2d RPG type game, in the old pokemon style.

One of the parts of the game is an enemy that starts following you once you get in a certain range.

I was able to implement the detection part (quite easy, just basic vector math), now I need to make him move according to a clock (not the hard part), but I don't know how I would make him follow a vector (enemy position to player position).

The code below is a function that returns distance between two points (mouse cursor and sprite position).

Any sort of help would be hugely appreciated.

Cheers


// GETTING DISTANCE BETWEEN TWO POINTS IN 2D
// RESULT IS USED IN A CONDITION ALONGSIDE A CLOCK

int    vector_dist(sfVector2i mouse, sfVector2f pos)
{
    int dist = 0;
    int x = mouse.x - pos.x;
    int y = mouse.y - pos.y;

    dist = sqrt(x * x + y * y);
    return (dist);
}

 

Do you just want the agent to move in a straight line towards the player based on the player's current position? Or do you need something more sophisticated, like pathfinding or intercept behavior?

Also, just out of curiosity, what language are you using? (Google says CSFML is a C binding for SFML, so I'm assuming C, but perhaps you could confirm.)

Advertisement

What you're wanting to research is Boid's, this is a general overview of some of the different things you can do with them: http://www.kfish.org/boids/pseudocode.html

 

 

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Hi Zakwayda,

Yes I'm coding in C, and yeah a straight line would be perfect.

I was able to make the sprite move, just not in the perfect direction:


enemy_t    **set_pos(sfVector2i mouse, enemy_t **enemy)
{
    if (mouse.x < enemy[0]->pos.x) enemy[0]->pos.x--;
    if (mouse.x > enemy[0]->pos.x) enemy[0]->pos.x++;
    if (mouse.y < enemy[0]->pos.y) enemy[0]->pos.y--;
    if (mouse.y > enemy[0]->pos.y) enemy[0]->pos.y++;
    sfSprite_setPosition(enemy[0]->sprite, enemy[0]->pos);
    return (enemy);
}

//ENEMY_T IS A STRUCTURE THAT CONTAINS TEXTURE, SPRITE, POSITION, SCALE
// MOUSE IS THE COORDS OF THE CURSOR POSITION RELATIVE TO THE WINDOW

but it's not the fastest trajectory, basically I need the enemy to follow a perfect line (vector (enemy.pos->mouse)

The simplest way to do what you're wanting might be something like this (pseudocode, and off the top of my head, so there may be errors):


vec2 direction = target_position - enemy_position;

// This assumes the enemy isn't extremely close to the target, numerically
// speaking. If that situation can arise, you may have to add a special case to
// handle it.
direction.normalize();

enemy_position += direction * enemy_speed * delta_time;

You appear to be working with integers here. That may work if the scale of the simulation is large enough and everything is implemented appropriately, but it's more typical to use arbitrary real numbers (e.g. floating point) for this sort of thing.

'Boids'-style algorithms are an option as well, as CrazyCdn suggested, although that would be more involved.

Hey man thanks for everything!

Just what's the special case to add? ...

 

Advertisement

If the enemy position == the target position, obviously no movement is needed and no direction can be computed. Mathematically this manifests as a division by zero in the normalization. Further, with floating point you may encounter numerical problems if the two points are nearly coincident. For these reasons, typically you'd bail on the algorithm if the two positions are very close together.

In practice, at least one of the agents in such a situation often has a non-negligible size or radius. If there's something that maintains a non-negligible distance between the agents (such as a collision detection and response system), then you may not need the special case.

I just implemented what you told me, but there's a problem: the sprite only moves on the x axis or y axis but not both at the same time, as if it would only move if y is null or x is null

 

2 minutes ago, polpel said:

I just implemented what you told me, but there's a problem: the sprite only moves on the x axis or y axis but not both at the same time, as if it would only move if y is null or x is null

I think we'd probably need to see your code to help with that.

What's your code look like now? I've done enemy following in the past exactly how Zakwayda has described it, and it always worked.

This topic is closed to new replies.

Advertisement