【问题标题】:How can I set gravity using this code?如何使用此代码设置重力?
【发布时间】:2014-01-18 23:30:21
【问题描述】:

我正在尝试制作游戏,但被重力困住了.....在以下代码中,一个矩形代表玩家,当我按下向上键时,它会沿 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);
}
}

【问题讨论】:

    标签: c++ sfml


    【解决方案1】:

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

    • 你的初始位置是350。

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

    • 但是,防止玩家从屏幕上掉下来的代码 (y &gt;= 350-1) 基本上解析为检查 y &gt;= 349,这将是正确的,因此您的位置将永久重置为 350。

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


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

    • 允许玩家跳跃。
    • 应用重力。
    • 允许玩家根据按住键的时间来确定跳跃高度。
    #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;
    }
    

    【讨论】:

    • +1 我误解并假设上限是玩家落地时。我需要睡觉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多