遵循SFML教程。此代码应该允许我在屏幕周围移动青色圆圈。在不使用mPlayer.move(移动)的情况下绘制圆形工作正常,但是当这条线在game.update中运行时,形状将从屏幕上消失,永远不会被重绘。我错过了什么?
Game.cpp
Game::Game()
:mWindow(sf::VideoMode(1440, 900, 32),"yeeboi1!!!!!") , mPlayer()
{
mPlayer.setRadius(20.f);
mPlayer.setPosition(100.f, 110.f);
mPlayer.setFillColor(sf::Color::Cyan);
}
Game::~Game()
{
}
void Game::run() {
while (mWindow.isOpen()) {
processEvents();
update();
render();
}
}
void Game::processEvents()
{
sf::Event event;
while (mWindow.pollEvent(event))
{
switch (event.type)
{
case sf::Event::KeyPressed:
HandleInput(event.key.code, true);
break;
case sf::Event::KeyReleased:
HandleInput(event.key.code, false);
break;
case sf::Event::Closed:
mWindow.close();
break;
}
}
}
void Game::update() {
sf::Vector2f movement(0.f, 0.f);
if (mMoveUp)
movement.y -= 1.f;
if (mMoveDown)
movement.y += 1.f;
if (mMoveLeft)
movement.x-= 1.f;
if (mMoveRight)
movement.x += 1.f;
mPlayer.move(movement);
}
void Game::render() {
mWindow.clear();
mWindow.draw(mPlayer);
mWindow.display();
}
void Game::HandleInput(sf::Keyboard::Key key, bool isPressed) {
if (key == sf::Keyboard::W)
mMoveUp = isPressed;
if (key == sf::Keyboard::S)
mMoveDown = isPressed;
if (key == sf::Keyboard::A)
mMoveLeft = isPressed;
if (key == sf::Keyboard::D)
mMoveRight = isPressed;
}
Game.h
#pragma once
#include <SFML/Graphics.hpp>
class Game
{
public:
Game();
~Game();
void run();
private:
void processEvents();
void update();
void render();
void HandleInput(sf::Keyboard::Key key, bool isPressed);
bool mMoveUp, mMoveDown, mMoveLeft, mMoveRight = false;
private:
sf::RenderWindow mWindow;
sf::CircleShape mPlayer;
};
Main.cpp
#include "Game.h"
int main()
{
Game game;
game.run();
return 0;
}
答案 0 :(得分:3)
为什么不转向基于时间的处理? 请务必阅读http://gameprogrammingpatterns.com/game-loop.html。
我目前坐在火车上,所以请为这个简短的答案道歉,但我想你明白了。请参阅Game :: run and update(dtAsSeconds)
中的更改Game.cpp
#include "Game.h"
Game::Game()
:mWindow(sf::VideoMode(1440, 900, 32),"yeeboi1!!!!!") , mPlayer()
{
mPlayer.setRadius(20.f);
mPlayer.setPosition(100.f, 110.f);
mPlayer.setFillColor(sf::Color::Cyan);
}
Game::~Game()
{
}
void Game::run() {
sf::Clock m_Clock = sf::Clock();
while (mWindow.isOpen()) {
sf::Time dt = m_Clock.restart();
// Count seconds since last process
float dtAsSeconds = dt.asSeconds();
processEvents();
update(dtAsSeconds);
render();
}
}
void Game::processEvents()
{
sf::Event event;
while (mWindow.pollEvent(event))
{
switch (event.type)
{
case sf::Event::KeyPressed:
HandleInput(event.key.code, true);
break;
case sf::Event::KeyReleased:
HandleInput(event.key.code, false);
break;
case sf::Event::Closed:
mWindow.close();
break;
}
}
}
void Game::update(float dtAsSeconds) {
sf::Vector2f movement(0.f, 0.f);
if (mMoveUp)
movement.y -= 1.f * dtAsSeconds * 100;
if (mMoveDown)
movement.y += 1.f * dtAsSeconds * 100;
if (mMoveLeft)
movement.x-= 1.f * dtAsSeconds * 100;
if (mMoveRight)
movement.x += 1.f * dtAsSeconds * 100;
mPlayer.move(movement);
}
void Game::render() {
mWindow.clear();
mWindow.draw(mPlayer);
mWindow.display();
}
void Game::HandleInput(sf::Keyboard::Key key, bool isPressed) {
if (key == sf::Keyboard::W)
mMoveUp = isPressed;
if (key == sf::Keyboard::S)
mMoveDown = isPressed;
if (key == sf::Keyboard::A)
mMoveLeft = isPressed;
if (key == sf::Keyboard::D)
mMoveRight = isPressed;
}
Game.h
#pragma once
#include <SFML/Graphics.hpp>
class Game
{
public:
Game();
~Game();
void run();
private:
void processEvents();
void update(float dtAsSeconds);
void render();
void HandleInput(sf::Keyboard::Key key, bool isPressed);
bool mMoveUp, mMoveDown, mMoveLeft, mMoveRight = false;
private:
sf::RenderWindow mWindow;
sf::CircleShape mPlayer;
};
main.cpp
#include "Game.h"
int main()
{
Game game;
game.run();
return 0;
}
答案 1 :(得分:0)
您的游戏运行速度尽可能快(这意味着您的圈子在最轻微的输入处飞离屏幕)。尝试限制帧速率:
mWindow.setFramerateLimit(60);
然后每次拨打mWindow.display()
都会等待一段时间。
编辑:确保您的对象不依赖于帧速率。您可以使用sf::Clock
。
class Game {
...
sf::Clock mClock;
}
然后在更新函数中,将输出乘以deltaTime:
void Game::update(sf::Time dt) {
sf::Vector2f movement(0.f, 0.f);
if (mMoveUp)
movement.y -= 1.f * dt.asSeconds();
...
mPlayer.move(movement);
}
//Now you can call the function
update(mClock.restart());