2
\$\begingroup\$

How could I made a character jump with SFML in C++, a simple example could be very helpful.

Thanks in advance.

This is the code I currently have; how can I make the sprite jump?

#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;

int main(){
    sf::RenderWindow ventana(sf::VideoMode(800,600),"mi ventana");
    ventana.setFramerateLimit(60);
    sf::Texture Image;
    Image.loadFromFile("tortuga.png");
    sf::Sprite sprite(Image);
    sprite.setPosition(-230,100);
    bool isPlay=true;
    bool presionarW(false);
    bool presionarA(false);
    bool presionarS(false);
    bool presionarD(false);
    //Controlar cualquier evento
    int x=30;
    int y=3;
    sf::Event miEvento;
    sf::CircleShape figura(10);
    while (isPlay)

    {
        //Eventos

        while(ventana.pollEvent(miEvento)){
            if (miEvento.type==sf::Event::Closed){
                isPlay=false;
            }
            if (miEvento.type==sf::Event::KeyPressed && miEvento.key.code==sf::Keyboard::W){
                presionarW=true;
            }
            if (miEvento.type==sf::Event::KeyPressed && miEvento.key.code==sf::Keyboard::A){
                presionarA=true;
            }
            if (miEvento.type==sf::Event::KeyPressed && miEvento.key.code==sf::Keyboard::S){
                presionarS=true;
            }
            if (miEvento.type==sf::Event::KeyPressed && miEvento.key.code==sf::Keyboard::D){
                presionarD=true;
            }

        }

        //Logica del juego
        if(presionarW){
            sprite.move(10,-20);
            presionarW=false;
        }
        if(presionarA){
            sprite.move(-20,5);
            presionarA=false;
        }
        if(presionarS){
            sprite.move(0,25);
            presionarS=false;
        }
        if(presionarD){
            sprite.move(25,0);
            presionarD=false;
        }

        //Renderizado
        ventana.clear();
        ventana.draw(sprite);
        ventana.display();
    }
    ventana.close();
}
\$\endgroup\$
0

2 Answers 2

7
\$\begingroup\$

I do not know how familiar you are with movement physics, but for this instance, you ideally want to work with Velocity and Acceleration.

Basically, Acceleration impacts Velocity which impacts Position.

float x = 0;
float y = 0;
float velocityX = 0;
float velocityY = 0;
float accelerationX = 0;
float accelerationY = 0;

void updateMovement() {

    velocityX += accelerationX;
    velocityY += accelerationY;

    x += velocityX;
    y += velocityY;

}

By working like this, you don't move a character by modifying its position, instead you modify its Velocity.

Now, gravity works like acceleration, meaning it should eventually cancel out a velocity. As a higher Y-coordinate means downwards, the gravity in this case is positive.

float gravity = 5;

void updateMovement() {
    
    velocityY += gravity;
    velocityX += accelerationX;
    velocityY += accelerationY;

    x += velocityX;
    y += velocityY;
}

However, we only want to apply gravity while we are in the air, so we need to check that first.

float gravity = 2;

void updateMovement() {
    
    if(y < 500)                  //If you are above ground
        velocityY += gravity;    //Add gravity
    else if(y > 500)             //If you are below ground
        y = 500;                 //That's not supposed to happen, put him back up

    velocityX += accelerationX;
    velocityY += accelerationY;

    x += velocityX;
    y += velocityY;
}

Now we can finally do the fun stuff! The actual jump will now be very easy to perform.

if (miEvento.type==sf::Event::KeyPressed && miEvento.key.code==sf::Keyboard::Space){
    velocityY = -10;
}

Basically, we tell the character to start lifting off. The character will then be affected by gravity, and the actual jump will become weaker and weaker, until the velocity becomes positive, pushing the character back to the ground.

That should cover all of it.

If you have any questions, feel free to comment and I'll do my best to answer.

EDIT: Something like this.

#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;

float x = 0;
float y = 0;
float velocityX = 0;
float velocityY = 0;
float accelerationX = 0;
float accelerationY = 0;

float gravity = 2;

void updateMovement() {

    if(y < 500)                  //If you are above ground
        velocityY += gravity;    //Add gravity
    else if(y > 500)             //If you are below ground
        y = 500;                 //That's not supposed to happen, put him back up

    velocityX += accelerationX;
    velocityY += accelerationY;

    x += velocityX;
    y += velocityY;
}

int main(){
    RenderWindow ventana(VideoMode(800,600),"mi ventana");
    ventana.setFramerateLimit(60);
    Texture Image;
    Image.loadFromFile("tortuga.png");
    Sprite sprite(Image);
    sprite.setPosition(-230,100);
    
    CircleShape figura(10);

    while (ventana.isOpen())
    {
        //Eventos

        while(ventana.pollEvent(miEvento)){
            if (miEvento.type==Event::Closed){
                ventana.close();
            }
            else if(miEvento.type==Event::KeyPressed && miEvento.key.code==Keyboard::Space){
                velocityY = -10;
            }
        }

        if(Keyboard::isKeyPressed(Keyboard::Left))
            velocityX = -5;
        else if(Keyboard::isKeyPressed(Keyboard::Right))
            velocityX = 5;
            
        updateMovement();
        sprite.setPosition(x, y);
            
        //Renderizado
        ventana.clear();
        ventana.draw(sprite);
        ventana.display();
    }

    return 0;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Perfect, thanks, but could you put it in my code? to guide me , i would like see the code complete to understand it, thanks¡ \$\endgroup\$ Commented May 9, 2017 at 18:48
  • 1
    \$\begingroup\$ @Davisonarcnoldswaden did everything work out for you? \$\endgroup\$
    – qwarten
    Commented May 15, 2017 at 1:10
1
\$\begingroup\$
float x = 0;
float y = 0;
float velocityX = 0;
float velocityY = 0;
float accelerationX = 0;
float accelerationY = 0;

float gravity = 2;

void updateMovement() {

    if(y < 500)                  //If you are above ground
        velocityY += gravity;    //Add gravity
    else if(y > 500)             //If you are below ground
        y = 500;                 //That's not supposed to happen, put him back up

    velocityX += accelerationX;
    velocityY += accelerationY;

    x += velocityX;
    y += velocityY;
}

int main(){
    

    sf::RenderWindow ventana(sf::VideoMode(800,69),"mi ventana");

    ventana.setFramerateLimit(69);
    sf::Texture Image;
    Image.loadFromFile("tortuga.png");
    sf::Sprite sprite(Image);
    

    sprite.setPosition(-2319,100);

    sf::CircleShape figura(10);

    while (ventana.isOpen())
    {
        //Eventos

        while(ventana.pollEvent(miEvento)){
            if (miEvento.type==sf::Event::Closed){
                ventana.close();
            }
            else if(miEvento.type==sf::Event::KeyPressed && miEvento.key.code==sf::Keyboard::Space){
                velocityY = -10;
            }
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
            velocityX = -5;
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
            velocityX = 5;

        updateMovement();
        sprite.setPosition(x, y);

        //Renderizado
        ventana.clear();
        ventana.draw(sprite);
        ventana.display();
    }

    return 0;
}
\$\endgroup\$
1
  • 2
    \$\begingroup\$ To explain what's going on and the train of thoughts that went on to create the code, we generally like to add some text at the beginning of the post before adding the code,. \$\endgroup\$
    – Vaillancourt
    Commented Sep 4, 2017 at 11:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .