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



我正试图制作一款游戏,却被地心引力卡住了。。。。。在下面的代码中,一个矩形代表一个玩家,当我按下向上键时,它在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);
}
}

重力是加速度:即位移的二重导数。因此,你不能直接设置位移(就像你目前正在做的那样)来获得一个很好的重力表示。

一种方法是创建自己的entity类,添加速度、加速度的成员;伴随着sf::RectangleShape的内部位移;然后让成员函数对初始化/每帧进行操作-快速&肮脏的例子(未经测试):

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,我将假设这是您的"地平面"。要实现这一点,您只需要检查实体是否在地平面下,如果在地平面上,则在实体的"Step"功能中或直接在主循环中重置实体的位置。从长远来看,你最好使用实体管理器/第三方物理引擎来做这类事情(例如,一个la box2D)

您可以这样做:

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

相关内容

  • 没有找到相关文章

最新更新