How can I set gravity using this code?

喜你入骨 提交于 2019-12-01 11:35:21

Theoretically your code would work, but there's one significant problem:

  • Your initial position is 350.

  • Now your "jumping code" (which will allow the player to fly indefinitely!) triggers and your position is changed to 349.

  • However, your code keeping the player from dropping off the screen (y >= 350-1) essentially resolves to the check y >= 349, which will be true, so your position is permanently reset to 350.

To solve this, just remove the -1 or replace the >= operator with >.


While your approach should be working (once the fix above is applied), you should rethink your strategy and store a velocity in addition to a position. I've recently written the following example code. It's far from being perfect, but it should teach you a few basics for a jump and run game (not necessarily the only way to do such things):

  • Allow the player to jump.
  • Apply gravity.
  • Allow the player to determine jump height based on how long he holds down a key.
#include <SFML/Graphics.hpp>

int main(int argc, char **argv) {
    sf::RenderWindow window;
    sf::Event event;

    sf::RectangleShape box(sf::Vector2f(32, 32));
    box.setFillColor(sf::Color::White);
    box.setOrigin(16, 32);

    box.setPosition(320, 240);

    window.create(sf::VideoMode(640, 480), "Jumping Box [cursor keys + space]");
    window.setFramerateLimit(60);
    window.setVerticalSyncEnabled(false);

    // player position
    sf::Vector2f pos(320, 240);

    // player velocity (per frame)
    sf::Vector2f vel(0, 0);

    // gravity (per frame)
    sf::Vector2f gravity(0, .5f);

    // max fall velocity
    const float maxfall = 5;

    // run acceleration
    const float runacc = .25f;

    // max run velocity
    const float maxrun = 2.5f;

    // jump acceleration
    const float jumpacc = -1;

    // number of frames to accelerate in
    const unsigned char jumpframes = 10;

    // counts the number of frames where you can still accelerate
    unsigned char jumpcounter = 0;

    // inputs
    bool left = false;
    bool right = false;
    bool jump = false;

    while (window.isOpen()) {
        while (window.pollEvent(event)) {
            switch(event.type) {
            case sf::Event::KeyPressed:
            case sf::Event::KeyReleased:
                switch (event.key.code) {
                case sf::Keyboard::Escape:
                    window.close();
                    break;
                case sf::Keyboard::Left:
                    left = event.type == sf::Event::KeyPressed;
                    break;
                case sf::Keyboard::Right:
                    right = event.type == sf::Event::KeyPressed;
                    break;
                case sf::Keyboard::Space:
                    jump = event.type == sf::Event::KeyPressed;
                    break;
                }
                break;
            case sf::Event::Closed:
                window.close();
                break;
            }
        }

        // logic update start

        // first, apply velocities
        pos += vel;

        // determine whether the player is on the ground
        const bool onground = pos.y >= 480;

        // now update the velocity by...
        // ...updating gravity
        vel += gravity;

        // ...capping gravity
        if (vel.y > maxfall)
            vel.y = maxfall;

        if (left) { // running to the left
            vel.x -= runacc;
        }
        else if (right) { // running to the right
            vel.x += runacc;
        }
        else { // not running anymore; slowing down each frame
            vel.x *= 0.9;
        }

        // jumping
        if (jump) {
            if (onground) { // on the ground
                vel.y += jumpacc * 2;
                jumpcounter = jumpframes;
            }
            else if (jumpcounter > 0) { // first few frames in the air
                vel.y += jumpacc;
                jumpcounter--;
            }
        }
        else { // jump key released, stop acceleration
            jumpcounter = 0;
        }

        // check for collision with the ground
        if (pos.y > 480) {
            vel.y = 0;
            pos.y = 480;
        }

        // check for collision with the left border
        if (pos.x < 16) {
            vel.x = 0;
            pos.x = 16;
        }
        else if (pos.x > 624) {
            vel.x = 0;
            pos.x = 624;
        }


        // logic update end

        // update the position
        box.setPosition(pos);

        window.clear();
        window.draw(box);
        window.display();
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!