我正在尝试制作一个游戏并且在重力上停留.....在下面的代码中,一个矩形代表一个玩家,当我按下键时它会在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);
}
}
答案 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);
}