How can I set gravity using this code?

前端 未结 1 1439
感情败类
感情败类 2021-01-06 16:32

I am trying to make a game and am stuck on gravity..... In the following code a rectangle stands for a player and when I press up key it moves in y-axis but when I activate

相关标签:
1条回答
  • 2021-01-06 16:49

    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;
    }
    
    0 讨论(0)
提交回复
热议问题