# walking enemy - better algorithm sfml c++

This topic is 2570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello everyone

ok so I really don't know if you can call this an algorithm or not. please do let me know if this is an algorithm.
anyways I have been working for the past hour on a way to make an enemy (just an image ) to move in a square way, and its working fine but i feel that its not as clean as it can be and i think there is a better way to do it but i don't know any better way to do this.

so what this algorithm or code will do is the following:-

1- make the image move 50 pixel on the x axis (move right). coordinates are (50,0)
2- when the image rech 50 pixel on the x axis it stops and then move 50 pixel on the y axis ( move down). coordinates are (50,50)
3- when the image rech 50 pixel on y axis it stops and then move -50 pixel on x axis (move left). coordinates are (0,50)
4- when the image rech 0 pixel on x it stops and move -50 pixel on the y axis (move up). coordinates are (0,0)
5- do the same in a loop.

so guys is there a better and cleaner way to do this?

 #include "move.h" move::move() { dirtimage.LoadFromFile("dirt.png"); dirtsprite.SetPosition(0,0); Stop1=false; Stop2=false; Stop3=false; } void move::drawmap(sf::RenderWindow &window) { float ElapsedTime = window.GetFrameTime(); dirstprite.SetImage(dirtimage); int posX = dirtsprite.GetPosition().x; int posY = dirtsprite.GetPosition().y; int Speed = 10; int Up = -10; int Down = 10; int Right = 10; int Left = -10; if(posX <= 50 && Stop1==false) dirtsprite.Move(Right * ElapsedTime * Speed, 0); // go right if(posX >=50) { dirtsprite.Move(-(Right * ElapsedTime * Speed), 0); // stop going right dirtsprite.Move( 0, Down * ElapsedTime * Speed); //go down } if(posY >=50) { dirtsprite.Move( 0, -(Down * ElapsedTime * Speed)); // stop going down Stop1=true; } if(Stop1 == true) dirtsprite.Move( Left * ElapsedTime * Speed, 0); //go left if(posX == 0 && Stop1 == true) { dirtsprite.Move( -(Left * ElapsedTime * Speed), 0); //stop go left Stop2 = true; } if(posX == 0 && Stop2==true) dirtstprite.Move( 0, Up * ElapsedTime * Speed); // go Up if(posX == 0 && posY == 0 ) { dirtsprite.Move( 0, -(Up * ElapsedTime * Speed)); // stop go Up Stop1 = false; } window.Draw(dirstsprite); } 

##### Share on other sites
There's nothing really "wrong" with what you have, but a large constraint to your enemy's AI is that it's entirely hardcoded in its logic. A better algorithm that would be more flexible would be to create a node based path that the enemy will take and repeat. The enemy would move toward the next node regardless of its current position, then continue to the next one once it reaches its destination.

The nodes in your case would be the four points (X,Y) of the square. Store the nodes in a dynamic container and you gain the flexibility to add or remove nodes on the fly. If the enemy ever gets off its path such as it chased the player, it could resume back on its path when instructed to since it's not hardcoded (and assuming there isn't anything obstructing its path).

Another important benefit to using something more flexible is that the system you write that moves the enemy could be reused for other enemies or new levels.

##### Share on other sites

There's nothing really "wrong" with what you have, but a large constraint to your enemy's AI is that it's entirely hardcoded in its logic. A better algorithm that would be more flexible would be to create a node based path that the enemy will take and repeat. The enemy would move toward the next node regardless of its current position, then continue to the next one once it reaches its destination.

The nodes in your case would be the four points (X,Y) of the square. Store the nodes in a dynamic container and you gain the flexibility to add or remove nodes on the fly. If the enemy ever gets off its path such as it chased the player, it could resume back on its path when instructed to since it's not hardcoded (and assuming there isn't anything obstructing its path).

Another important benefit to using something more flexible is that the system you write that moves the enemy could be reused for other enemies or new levels.

i tried to do this but really don't know how to do it. i found a tutorial that does exactly what i want it to do but its in Flash.

http://www.emanueleferonato.com/2007/10/06/make-a-flash-game-like-flash-element-tower-defense-part-1/

he does it like this
 waypoint_x = new Array(40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420); waypoint_y = new Array(140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20);

i tried to do it in c++ but i just couldn't. if you could help me that would be amazing.
thank you.

##### Share on other sites

http://www.emanuelef...defense-part-1/

he does it like this
 waypoint_x = new Array(40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420); waypoint_y = new Array(140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20);

i tried to do it in c++ but i just couldn't. if you could help me that would be amazing.
thank you.

in C++ you'd use something along the lines of:
 const size_t kPathPoints = 11; //helps keep x & y pairs matched const int waypoint_x[kPathPoints] = {40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420}; const int waypoint_y[kPathPoints] = {140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20}; 

##### Share on other sites

[quote name='FantasyVI' timestamp='1320091936' post='4878985']
http://www.emanuelef...defense-part-1/

he does it like this
 waypoint_x = new Array(40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420); waypoint_y = new Array(140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20);

i tried to do it in c++ but i just couldn't. if you could help me that would be amazing.
thank you.

in C++ you'd use something along the lines of:
 const size_t kPathPoints = 11; //helps keep x & y pairs matched const int waypoint_x[kPathPoints] = {40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420}; const int waypoint_y[kPathPoints] = {140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20}; 

[/quote]

thank for the replay.

but yes doing this is easy
 const int waypoint_x[kPathPoints] = {40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420}; const int waypoint_y[kPathPoints] = {140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20}; 

but what i meant is how can i make it move to these points. If i use sprite.setposition(40,140) the image postion will change to that place but not move there(or walk you know).
however if i use  sprite.move(40,140) this will only offset it position and make it keep moving by offeset of (40,140).

my question is how can i make to move to that position and stop there?
and yes i know that my code already does that but there should be some kind of clean way to do it like using this array.

 const int waypoint_x[kPathPoints] = {40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420}; const int waypoint_y[kPathPoints] = {140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20}; 

##### Share on other sites
The waypoint list gives the list of points to walk to. At any given point in time, the entity will have an array index variable indicating the current waypoint to walk to, call it waypointIndex or somesuch. When the entity needs to take a step it can do so by:

 wpX = waypoint_x[waypointIndex]; wpY = waypoint_y[waypointIndex]; // Calculate direction vector float vx = (float)wpX - (float)self->X; float vy = (float)wpY - (float)self->Y; // Normalize direction vector to unit length float len = sqrt(vx*vx + vy*vy); vx /= len; vy /= len; // Apply movement vector to move self->X += vx * self->Speed * elapsedTime; self->Y += vy * self->Speed * elapsedTime; 

The entity can check to see if it has arrived at the waypoint by:

 wpX = waypoint_x[waypointIndex]; wpY = waypoint_y[waypointIndex]; float vx = wpX - self->X; float vy = wpY - self->Y; float len = sqrt(vx*vx + vy*vy); if (len < proximityLimit) { // Close enough, entity has arrived return ENTITY_HAS_ARRIVED; } 

This code checks to see if the entity is within some specified distance (called here proximityLimit) of the destination waypoint. When dealing with floating-point vectors for movement, it is a bad idea to try to test if the entity has arrived by using == comparisons, since it is possible that they will fail due to slight over-stepping, and the entity will either just keep walking or will walk back and forth in a tiny area centered on the waypoint, vainly trying to reach it exactly, depending on if you cache your (vx,vy) vector or recalculate it every time.

This logic also does not include path-finding, which can complicate the process a tiny bit. Rather than just calculate a straight vector to the waypoint, the pathfinding-based solution will feed the entity position and waypoint location to the path-finder to obtain a path to follow. This path to follow may itself be a simple list of locations (mini-waypoints) which could be followed in the exact way described above, by calculating straight-line movement vectors.

##### Share on other sites
@[color=#CB021A]JTippetts

thank you very very much for taking the time to read my post and help me with my code, i really appreciate it.
I'm experiencing a small problem with the new code. i did this

 int i=0; float wpX = waypoint_x; float wpY = waypoint_y; 

because if i try to do this instead

 float wpX = waypoint_x[waypointIndex]; float wpY = waypoint_y[waypointIndex]; 

i get a runtime error saying that i did not initialize waypoint_x and waypoint_y.
the problem i'm having is that ( i ) is starting from 1, not 0 and when it increment it go to 3 instead of 2. so the sprite move 64pixel up and then 64pixel down. what it should do is to move 64pixel to the right then down then left then up.

here is the full code
 #include "Enemy.h" Enemy::Enemy(void) { EnemyImage.LoadFromFile("Images/enemy.png"); EnemyImage.CreateMaskFromColor(sf::Color(255,255,255)); EnemySprite.SetPosition(0,0); Stop1=false; Stop2=false; Stop3=false; i=0; } Enemy::~Enemy(void) { } void Enemy::Movment(sf::RenderWindow &window) { float ElapsedTime = window.GetFrameTime(); EnemySprite.SetImage(EnemyImage); float X = EnemySprite.GetPosition().x; float Y = EnemySprite.GetPosition().y; int Speed = 50; int const waypointIndex=4; const float waypoint_x[waypointIndex] = {64, 0, -64, 0}; const float waypoint_y[waypointIndex] = {0, 64, 0, -64}; // Calculate direction vector float wpX = waypoint_x; float wpY = waypoint_y; // Calculate direction vector float vx = (float)wpX - (float)X; float vy = (float)wpY - (float)Y; // Normalize direction vector to unit length float len = sqrt(vx*vx + vy*vy); vx /= len; vy /= len; // Apply movement vector to move X += vx * Speed * ElapsedTime; Y += vy * Speed * ElapsedTime; EnemySprite.SetPosition(X, Y); // go right checking(); window.Draw(EnemySprite); } void Enemy::checking() { float X = EnemySprite.GetPosition().x; float Y = EnemySprite.GetPosition().y; int const waypointIndex=4; const float waypoint_x[waypointIndex] = {64, 0, -64, 0}; const float waypoint_y[waypointIndex] = {0, 64, 0, -64}; float wpX = waypoint_x; float wpY = waypoint_y[0]; float vx = wpX - X; float vy = wpY - Y; float len = sqrt(vx*vx + vy*vy); float proximityLimit = 60; if (len > proximityLimit) { i++; if(i>=4) i=0; std::cout<<i; } } 

I'm really sorry if i sound like I'm not trying to fix my own errors but i'm, I really am. I spent two hour trying to fix it but i just couldn't.
ironically i want to be a game programer but i'm not really good in physics and math.

i'm really sorry for being such a newbie.

##### Share on other sites
 float wpX = waypoint_x; float wpY = waypoint_y[0]; 

This looks like a bug in your posted code. You index waypoint_x using i, but you only index waypoint_y with 0, so you will always get a value of 0 for wpY.

And of course you'll get an error trying to do wpX = waypoint_x[waypointIndex] because earlier you set waypointIndex equal to 4 for the array initialization, and trying to index an array of length 4 with the index 4 results in an array out of bounds.

##### Share on other sites
Your code would more robust if you had a 2D vector holding your (x,y) coordinates.The way-point system of moving objects around is great, however on its own it suffers from 2 major limitation. Without proper collision checking the object can and will move through walls. Also, even with collision checking if a way point draws a path through a wall, the object will never reach its destination, collision checking will keep it at the wall and it will never reach the next way point. What you need is A* Pathing algorithm to set intermediate way-points for you dynamically. Its a bit too much to explain here so I will link you, You already have half the work done because A*uses a way-point system.

http://www.policyalmanac.org/games/aStarTutorial.htm

gLhf

##### Share on other sites
I thnk a big question here is.. can this enemy ever be knocked off its path? If not, then there's no concern about it needing intelligence to path around walls.

please be sure you define the limits of what this sprite is to do.. Our tendencies around here are to sometimes set you down the path of creating First person shooter enemies capable of hopping small hurdles, work in teams and patha round a graph representation of the game world....

Concise definition of what the character is supposed to do will allow you to implement systems that are useful.

The original post makes me believe it's simply an enemy that walks. like old enemies in Mario that didn't care where Mario went, they just did their pathing and if he hit them, he got hurt.

1. 1
Rutin
39
2. 2
3. 3
4. 4
5. 5

• 12
• 16
• 12
• 14
• 9
• ### Forum Statistics

• Total Topics
633357
• Total Posts
3011504
• ### Who's Online (See full list)

There are no registered users currently online

×