如何使用此代码设置重力? SFML / C ++

时间:2014-01-02 04:45:20

标签: c++ sfml platform gravity game-development

我正在尝试制作一个游戏并且在重力上停留.....在下面的代码中,一个矩形代表一个玩家,当我按下键时它会在y轴上移动但是当我激活重力时(即重置它的先前位置)它没有动画(即它没有跳跃)而是只停留在它的位置。我知道它为什么会发生。因为它只是保持其位置,因为当我按下向上键时它会执行代码rectangle.setPosition(0, 350)。是的,我希望它能做到这一点,但我也希望看到我的运动员在运动。我正在使用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);
    }
}

2 个答案:

答案 0 :(得分:3)

重力是加速度:即位移的双重导数。所以你不能直接设置位移(正如你现在所做的那样)以获得很好的重力表示。

一种方法是创建自己的entity类,添加速度,加速度的成员;与sf::RectangleShape的内部位移一起;然后让成员函数在初始化/每帧上运行 - 快速&amp;脏例子(未经测试):

class SomeEntity {
public:
    SomeEntity( float x_pos, float y_pos ) : position(x_pos, y_pos) {
        m_shape.setSize(sf::Vector2f(100, 100));
        m_shape.setFillColor(sf::Color::Black);
        m_shape.setPosition(sf::Vector2f(x, y));

        // Constants at the moment (initial velocity up, then gravity pulls down)
        velocity = sf::Vector2f(0, -30);
        acceleration = sf::Vector2f(0, 9.81); //Earth's acceleration
    }

    void Step() { // TODO: use delta time
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
            velocity.y -= 1;
        }

        velocity.x += acceleration.x;
        velocity.y += acceleration.y;
        x += velocity.x;
        y += velocity.y;

        m_shape.setPosition(x, y);
    }

    void Draw(sf::RenderWindow &window) {
        window.draw(m_shape);
    }

private:
    sf::RectangleShape m_shape;
    sf::Vector2f position, velocity, acceleration;
}

这也意味着你可以重写你的应用程序,因为它更清洁:

SomeEntity ent(360, 0);

while(window.isOpen()) {

    sf::Event Event;
    while(window.pollEvent(Event)) {
        if(Event.type == sf::Event::Closed) {
            window.close();
        }
    }

    ent.Step();

    window.display();
    window.clear(sf::Color::Cyan);
    ent.Draw();
}

当你反复将rectangle设置为x = 0, y = 350时,我会假设那是你的'地平面'。要实现这一点,您只需检查实体是否在地平面下,并将其位置重置为地平面(如果是) - 在实体的“步骤”功能中或直接在主循环中。从长远来看,你可能最好使用实体管理器/第三方物理引擎来做这类事情(例如la box2D)

答案 1 :(得分:0)

你可以这样做:

if(rectangle.getPosition().y > 350)
{
    rectangle.move(0, 0.01);
}