如何使用此代码设置重力?

时间:2014-01-01 09:42:13

标签: c++ sfml

我正在尝试制作一个游戏并且在重力上停留.....在下面的代码中,一个矩形代表一个玩家,当我按下键时它会在y轴上移动但是当我激活重力时(即重置其先前的位置)它没有动画(即它没有跳跃)而是只停留在它的位置。我正在使用C ++的SFML库,这是一个游戏开发工具。请帮助!

#include <SFML/Graphics.hpp>

int main(){
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Gravity");


sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(100, 100));
rectangle.setFillColor(sf::Color::Black);
rectangle.setPosition(sf::Vector2f(10, 350));

while(window.isOpen())
{
    sf::Event Event;
    while(window.pollEvent(Event))
    {
        if(Event.type == sf::Event::Closed)
        {
            window.close();
        }
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
        rectangle.move(0, -1);
    }
    if(rectangle.getPosition().y >= 350-1)
    {
        rectangle.setPosition(0, 350);
    }
    window.display();
    window.clear(sf::Color::Cyan);
    window.draw(rectangle);
}
}

1 个答案:

答案 0 :(得分:3)

理论上你的代码可以工作,但是有一个重要的问题:

  • 您的初始职位是350。

  • 现在你的“跳跃代码”(允许玩家无限期飞行!)触发,你的位置改为349。

  • 但是,保持播放器不会从屏幕上掉落的代码(y >= 350-1)基本上会解析为y >= 349,这将是真的,因此您的位置会永久重置为350。

要解决此问题,只需删除-1或将>=运算符替换为>


虽然您的方法应该有效(一旦应用上述修复),您应该重新考虑您的策略并存储除位置之外的速度。我最近编写了以下示例代码。它远非完美,但它应该教你一些跳跃和跑步游戏的基础知识(不一定是做这些事情的唯一方法):

  • 允许玩家跳跃。
  • 施加重力。
  • 允许玩家根据他按下一个键的时间来确定跳跃高度。
#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;
}