我用C ++和SFML编写了一个简单的程序。我的问题是,当我移动我的精灵时,它非常不稳定。我的精灵会移动一点然后加速到一个平稳的运动,直到我按下另一个键然后它会再次停止然后继续。我希望这是有道理的,但简而言之,我只是希望我的精灵运动更顺畅。我的代码:
#include <SFML/Graphics.hpp>
#include <math.h>
#include <iostream>
int main()
{
float x = 0;
float y = 0;
sf::Vector2f position;
sf::Vector2f velocity;
float maxspeed = 3.0f;
float accel = 1.0f;
float decel = 0.02f;
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
sf::Texture tplayer;
if (!tplayer.loadFromFile("character.png"))
{
// error...
}
sf::Sprite splayer;
splayer.setTexture(tplayer);
splayer.setOrigin(sf::Vector2f(0, 0));
splayer.setTextureRect(sf::IntRect(0, 0, 16, 38));
sf::Vector2f pos = splayer.getPosition();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
velocity.x -= accel;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
velocity.x += accel;
else
velocity.x *= decel;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
velocity.y -= accel;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
velocity.y += accel;
else
velocity.y *= decel;
if (velocity.x < -maxspeed) velocity.x = -maxspeed;
if (velocity.x > maxspeed) velocity.x = maxspeed;
if (velocity.y < -maxspeed) velocity.y = -maxspeed;
if (velocity.y > maxspeed) velocity.y = maxspeed;
position += velocity;
splayer.setPosition(position);
}
}
window.clear();
window.draw(splayer);
window.display();
window.setFramerateLimit(60);
}
return 0;
}
答案 0 :(得分:2)
Google frame independent movement
//Before main loopp
sf::Clock clock;
// Start main loop
//Somewhere in the main loop
sf::Time deltaTime = clock.restart().asSeconds();
velocity.x *= deltaTime.asSeconds();
velocity.y *= deltaTime.asSeconds();
//move is just a setPosition but it adds given argument to actual position so it's basically splayer.setPosition(sf:Vector2f(position.x + velocity.x,position.y + velocity.y));
splayer.move(velocity);
答案 1 :(得分:0)
不要在民意调查事件循环中使用sf::Keyboard::isKeyPressed
- 方法!此方法提供了一种在程序中的任何位置请求键状态的方法。如果您之前检查过当前轮询事件是您的想法,则只在您的轮询事件循环中写入代码。你就像你已经发现的那样if(event.type == sf::Event::Closed)
。
因此,只需将所有代码(窗口关闭事件除外)移出poll事件循环。
我觉得你不明白事件循环究竟是什么,所以我会向你解释:
在前一帧中出现的每个事件(例如鼠标事件,按下键,窗口大小调整......)都会排队,并且轮询事件循环会遍历每个排队事件。例如,首先是鼠标移动事件,然后是按键事件。并且您只想在一个特定事件发生后执行操作,因此如果当前事件与搜索到的事件匹配,则必须询问此if块。做某事。一次。
顺便说一下:您可以在窗口打开之前致电window.setFramerateLimit(60);
,这样您就不会在每帧设置限制时浪费资源。