• Create Account

# G4MR

Member Since 06 Jan 2013
Offline Last Active Jan 11 2013 12:46 PM

### In Topic: SFML sprite movement (think super meat boy's rocket levels)

07 January 2013 - 12:11 PM

Another version someone posted on /r/gamedev:

```while(game_is_running) {

handle_input_and_move_player();

//get vector
vx = player.x - zombie.x;
vy = player.y - zombie.y;

//get length of vector (distance from zombie to player)
length = sqrt(vx*vx + vy*vy);

//check length is above the hit distance from player to zombie here
//if it's below the distance then the zombie has eaten the player
//length must be above zero or the normalisation will error (divide by zero)

//normalise
vx = vx/length;
vy = vy/length;

zombie.x += vx*zombie.speed*frame_time;
zombie.y += vy*zombie.speed*frame_time;

//draw everything
draw_everything();
}```

Which also works.

### In Topic: SFML sprite movement (think super meat boy's rocket levels)

07 January 2013 - 11:26 AM

While I also suggest you use a vector difference like Jutaris suggested (though sf::Vector2 doesn't have ANY functions to normalize),

I think your original code's error is quite simple.

You're converting the result of your atan2 into degrees, but sin and cos are designed to accept radians. Remove the * 180 / M_PI which converts your angle to degrees.

Storing your angle should only look like this:

`angle = atan2(rany - player1.sprite.getPosition().y, ranx - player1.sprite.getPosition().x);`

I'm not sure how accurate BeerNutts analysis is - I thought all of that works as you indended, but the human controlled player is player2, and the zombie is player1.

Best 'o luck to ya though.

This worked

### In Topic: SFML sprite movement (think super meat boy's rocket levels)

07 January 2013 - 03:59 AM

So I attempted to do what you said and I had to make the speed the same for the player and the zombie.

Problem/Question 1: It seems I can't make both units on the screen different velocities (eg.: player1 = zombie with a speed of 2 and player2 = player with a speed of 3 [slightly faster]), if I do this and I go in a diagonal direction my player1 sprite will go in weird circular patterns unless I stop moving.

Problem/Question 2: It seems that if I allow diagonal movement (holding W and D or A & S, etc...) it will do this small curl up until I stop moving.  What's the best way to approach this problem?

Problem/Question 3: There's also the issue when holding just down or right (S or D) and the sprite will just sit on the X or Y axis until I stop moving the unit on the screen and then proceed to move towards my unit.  How do I sort this?

Example:

Source:

```#include "GameApp.h"

void GameApp::Setup() {

//setup the game window
window.create(VideoMode(width, height), "Zoms");

//set framerate
window.setFramerateLimit(60);

player1.setSize(10, 20);
player1.setPos(10, 10);

player2.setSize(10,10);

//lets say theg ames running now
running 	= true;
}

void GameApp::Run() {

//Setup game
Setup();

//used to get the current angle of the line between the two points
//then we can properly move the sprite to the player
double angle, x, y, newx, newy;

//sprite speed
int speed 	= 2;

//are the wasd buttons pressed?
bool mw = false;
bool ma = false;
bool ms = false;
bool md = false;

//setup the player2 location
int ranx 	= 300;
int rany 	= 300;

player2.setPos(ranx, rany);

float timeprev, timecurr;

while(window.isOpen()) {

//loop through the active events (keyboard, mouse, etc...)
while(window.pollEvent(event)) {

if(event.type == Event::Closed) {
window.close();
}

if(event.type == Event::KeyPressed) {
switch(event.key.code) {
case Keyboard::W:
mw = true;
break;
case Keyboard::A:
ma = true;
break;
case Keyboard::S:
ms = true;
break;
case Keyboard::D:
md = true;
break;
}
}

if(event.type == Event::KeyReleased) {
switch(event.key.code) {
case Keyboard::W:
mw = false;
break;
case Keyboard::A:
ma = false;
break;
case Keyboard::S:
ms = false;
break;
case Keyboard::D:
md = false;
break;
}
}
}

//did we move the player?
if(mw) {
rany -= speed;
}

if(ma) {
ranx -= speed;
}

if(ms) {
rany += speed;
}

if(md) {
ranx += speed;
}

//get the angle of the line between both player locations (zombie/player)
angle 	= (atan2(rany - player1.sprite.getPosition().y, ranx - player1.sprite.getPosition().x) * 180) / M_PI;

//steps between movement
x 		= cos(angle) * speed;
y 		= sin(angle) * speed;

newx = player1.sprite.getPosition().x + x;
newy = player1.sprite.getPosition().y + y;

//move the sprites on the screen
player1.sprite.setPosition(Vector2f(newx, newy));
player2.sprite.setPosition(Vector2f(ranx, rany));

window.clear();
window.draw(player1.sprite);
window.draw(player2.sprite);

//update the screen
window.display();
}

}```

### In Topic: SFML sprite movement (think super meat boy's rocket levels)

07 January 2013 - 02:57 AM

You should be multiplying the cos() and sin() by a velocity, and adding it to the x and y location every loop, like this:

```
// Let's assume we've set float zombie.velocity = 5, which it seem is defined as pixels per frame

<pre>
angle = (atan2(player.y - zombie.y, player.x - zombie.x) * 180) / M_PI;
zombie.x += cos(angle)*zombie.velocity;
zombie.y += sin(angle)*zombie.velocity;</pre>```

Eventually you should define the velocity to be in some units/second (like pixels/second), so it will move better with other machine speeds.

Thank you, I will try this

PARTNERS