OK I'm confused by this one...
I'm following along in the SMFL book (great book, love the fact that I'm not spoon fed!) but I've hit an issue... I've completed a couple of chapters and had the FPS and TPU showing on the screen with the plane flying around.
Went to bed, got up and added in the TextureHolder chapter, suddenly the FPS and TPU don't show... UNLESS! I add a break point on the Render() in the void Run() or on the part where the FPS/TPU string is set, but it gets set once and never changed (although I can at least see it!)
I've looked to see if I broke anything, commented out the new section and even then it doesn't show without the break point.
I created a brand new project and I can get text/fonts to work on it, but the moment I try to do anything on my project where I'm following the book it just doesn't render.
Windows 7 Pro, Visual Studio 2012, no error messages or anything in Console.
Main Code File (Note: it's not exactly like the book examples, but having now spent 8 hours I can't see my text issue):
// Game.cpp
// Main entry point to game
#include "Game.h"
const sf::Time Game::TIMEPERFRAME = sf::seconds(1.f/60.f); // Define Frame rate
const float Game::PLAYERSPEED = 100.0f; // Define player movement rate
int main(){
Game game(false); // Create a game object with v-sync on
game.Run(); // Run the game
return 0;
}
// Override of toString in std::
template <typename T>
std::string toString(const T& value){
std::stringstream stream; // Creates a stream
stream << value; // assigns/pipes value to the stream
return stream.str(); // returns the stream as string value
}
// Game Constructor
// Set rendering screen and define player object
Game::Game(bool vSync):
m_IsMovingDown(false), m_IsMovingLeft(false), m_IsMovingRight(false), m_IsMovingUp(false), // Default all movement to false
m_StatNumFrames(0), // Set frames displayed to 0
debug(true) // Set Debug output
{
// Load resources
m_Texture.Load(Textures::Airplane, "images/eagle.png"); // Load the Airplane texture
m_PlayerSprite.setTexture(m_Texture.GetTexture(Textures::Airplane)); // Set the player object to Airplane
if(!m_Font.loadFromFile("fonts/Sansation.ttf")){
// Font failed to load, handle error
std::cout << "\n\nPress enter to continue... [Program will quit]";
std::cin.ignore(std::cin.rdbuf()->in_avail() + 1);
return;
}
else {
// File loaded
std::cout << "Font Sansation loaded.\n";
}
// Set up text
m_Text.setFont(m_Font);
m_Text.setPosition(5, 5);
// Set up player sprite
m_PlayerSprite.setPosition(100.f, 100.f);
m_Window.create(sf::VideoMode(640, 480), "SFML First Game"); // Create a render window of 640x480 pixels with title
m_Window.sf::Window::setVerticalSyncEnabled(vSync); // Set v-sync on/off
}
// Game Loop
void Game::Run(){
sf::Clock clock; // Set up clock object for timing
sf::Time timeScinceLastUpdate = sf::Time::Zero; // Set the timer to zero
while(m_Window.isOpen()){
sf::Time elapsedTime = clock.restart(); // Get time passed
timeScinceLastUpdate += elapsedTime; // Add time passed to timeScinceLastUpdate
while(timeScinceLastUpdate > TIMEPERFRAME){ // If TIMEPERFRAME is shorter than the update time, do a frame step
timeScinceLastUpdate -= TIMEPERFRAME; // Stay in this loop until the frame's have caught up
ProcessEvents(); // Process events
Update(TIMEPERFRAME); // Update game logic
}
if(debug){
UpdateStats(elapsedTime); // Show FPS/Calculations if Debug is true
}
Render(); // Render the scene
}
}
// Process any/all system events
void Game::ProcessEvents(){
sf::Event event;
while(m_Window.pollEvent(event)){ // While there are a queue of events
switch (event.type)
{
case sf::Event::KeyPressed: // Check for key down
HandlePlayerInput(event.key.code, true);
break;
case sf::Event::KeyReleased: // Check for key up
HandlePlayerInput(event.key.code, false);
break;
case sf::Event::Closed: // Check for window closed
m_Window.close();
break;
default: // All other events...
break;
}
}
}
// Game logic update
void Game::Update(sf::Time deltaTime){
sf::Vector2f movement(0.f, 0.f); // 2 Dimensional movement vector
// For any movement key's give movement a value
if(m_IsMovingUp) movement.y -= PLAYERSPEED;
if(m_IsMovingDown) movement.y += PLAYERSPEED;
if(m_IsMovingLeft) movement.x -= PLAYERSPEED;
if(m_IsMovingRight) movement.x += PLAYERSPEED;
m_PlayerSprite.move(movement * deltaTime.asSeconds()); // Move player distance x speed in direction of velocity
}
// Render Screen
void Game::Render(){
m_Window.clear(); // Clear render surface
m_Window.draw(m_PlayerSprite); // Draw player object
m_Window.draw(m_Text); // Draw text object
m_Window.display(); // Display scene
}
// Handles player input
void Game::HandlePlayerInput(sf::Keyboard::Key key, bool isPressed){
if(key == sf::Keyboard::W) m_IsMovingUp = isPressed; // Move up if true
else if(key == sf::Keyboard::S) m_IsMovingDown = isPressed; // Move down if true
else if(key == sf::Keyboard::A) m_IsMovingLeft = isPressed; // Move left if true
else if(key == sf::Keyboard::D) m_IsMovingRight = isPressed; // Move right if true
else if(key == sf::Keyboard::F3) ToggleDebug(isPressed);
}
// Calculate and display FPS
void Game::UpdateStats(sf::Time elapsedTime){
m_StatUpdateTime += elapsedTime;
m_StatNumFrames += 1;
if(m_StatUpdateTime >= sf::seconds(1.0f)){
m_Text.setString("FPS: " + toString(m_StatNumFrames) + "\n" // Display FPS (Frames per second)
"TPU: " + toString(m_StatUpdateTime.asMicroseconds() / m_StatNumFrames) + "us"); // Display TPU (Time per update)
}
m_StatUpdateTime -= sf::seconds(1.0f);
m_StatNumFrames = 0;
}
// Toggle showing Debug Information on or off
void Game::ToggleDebug(bool isPressed){
if(isPressed){ // isPressed is true (toggle debug)
if(debug){ // This prevents the on/off in a single keystroke
debug = false;
}
else {
debug = true;
}
std::cout << "Toggled Debug information: " << debug << ".\n\n";
}
}