So I'm going through LazyFoo.net's tutorials and I wanted to make my program keep a constant framerate of 60FPS while displaying the framerate on the top caption of the window.
I can achieve it! ...but only one at a time.
The code acts differently depending on where I place two of my timers. (They are classes)
This code makes the framerate unregulated but provides a framerate counter that's accurate.
1 2 3 4 5 6 7 8 9 10
|
//Start the frame and update timers.
update.start();
fps.start();
while(quit == false){
while( SDL_PollEvent(&event)){
if( event.type == SDL_QUIT ){
//Quit the program
quit = true;
}
|
And this code makes the framerate regulated but the counter stays at 0.
1 2 3 4 5 6 7 8 9 10 11
|
while(quit == false){
//Start the frame and update timers.
update.start();
fps.start();
while( SDL_PollEvent(&event)){
if( event.type == SDL_QUIT ){
//Quit the program
quit = true;
}
|
If I separate both of the timer classes the program crashes.
Now I can see where my problem may lie. In my timer class, if I "start" it, it resets the ticker thingamabob. Later on in the code, after 1000 ticks on the update (for the caption) class's timer, it returns the amount of time and then resets it. But if I put it at the start of the loop, it keeps resetting before it can even count thus always being 0.
The update timer also relies on the fps class' timer to make it's calculations. Oops! So if the fps class (which also ACTUALLY regulates the framerate) is outside of the loop, there is no control, and if it is inside, there is, but the update class has to be with it or else it crashes.
I don't know what I should do to solve this. Any suggestions?
I'll post all my code below for the timer class and main .cpp file. (minus the irrelevant beginning to keep my post within' length limit. I'll email or upload the full source upon request) The ellipses lines will denote cut out code.
EDIT: Added source code download:
http://www.mediafire.com/?4p0kjx7akdr607c Press left and right arrows to add and subtract balls.
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
.........................
//Framerate control stuff
const int FRAMES_PER_SECOND = 60;
int frame = 0; //Keep track of how many frames were printed to screen.
float framerate = 0;
bool cap = true; //Cap the framerate
Timer fps; //Framerate regulator.
Timer update; //Timer used to update the caption.
.........................
//String Stream for adding ints to strings
std::stringstream ss;
//Variables for the screen.
double gravity = 0.25;
int presstimer = 0;
int ballcount = 3500;
int balllimit = 5000;
std::string title;
//Create the balls.
ball b[balllimit];
.........................
//*************************************************************************
//All initialization over! Begin game code and displaying.
//*************************************************************************
//Start the frame and update timers.
update.start();
fps.start();
while(quit == false){
while( SDL_PollEvent(&event)){
if( event.type == SDL_QUIT ){
//Quit the program
quit = true;
}
//If a key is pressed
if( event.type == SDL_KEYDOWN ){
switch( event.key.keysym.sym ){
case SDLK_ESCAPE: quit = true;
case SDLK_RETURN: cap = ( !cap );
}
}
}
//Check for key presses
Uint8 *keystates = SDL_GetKeyState( NULL );
if( keystates[ SDLK_RIGHT ] ){
if(ballcount<balllimit and presstimer <= 0){
ballcount += 1; //Create ball and refresh stuff
b[ballcount-1].init(SCREEN_WIDTH, SCREEN_HEIGHT);
presstimer = 5;
}
}
if( keystates[ SDLK_LEFT ] ){
if(ballcount>0 and presstimer <= 0){
ballcount -= 1; //Destroy ball but don't bother refreshing
presstimer = 5;
}
}
//Tick the press timer.
//Press timer is to allow a delay between ball spawning
//when holding the button down
if(presstimer>0)presstimer -= 1;
//*************************************************************************
.........................
//Update screen
if( SDL_Flip( screen ) == -1 ){
return 1;
}
//Increment frame counter
frame++;
//If framerate is capped, wait until next frame.
if((cap == true) && (fps.get_ticks() < 1000 / FRAMES_PER_SECOND))
{
SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
}
//Calculate the framerate.
if( update.get_ticks() > 1000 ){
framerate = frame / (fps.get_ticks() / 1000);
//Restart the update timer.
update.start();
}
//Update the Window Caption with new ball count and framerate
ss.str(std::string()); //Clear the caption
ss << "Ball Bounce - " << ballcount << " Balls";
ss << " | " << framerate << "FPS";
title = ss.str();
SDL_WM_SetCaption(title.c_str(), NULL );
.........................
//End of game loop
}
.........................
}
|
time.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
class Timer
{
private:
//Clock time when the timer started.
int startTicks;
//The ticks stored when the timer was paused.
int pausedTicks;
//The timer status.
bool paused;
bool started;
public:
//Initializes variables.
Timer();
//The various clock actions.
void start();
void stop();
void pause();
void unpause();
//Gets the timer's time.
int get_ticks();
//Checks the status of the timer.
bool is_started();
bool is_paused();
};
Timer::Timer()
{
//Initialize the variables.
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}
void Timer::start()
{
started = true;
//Unpause the timer
paused = false;
//Get the current clock time
startTicks = SDL_GetTicks();
}
void Timer::stop()
{
//Stop the timer.
started = false;
//Unpause the timer
paused = false;
}
int Timer::get_ticks()
{
//If the timer is running
if( started == true ){
//If the timer is paused
if( paused == true ){
//Return number of ticks when timer was paused.
return pausedTicks;
}
else{
//Return the current time minus the start time
return SDL_GetTicks() - startTicks;
}
}
//If the timer isn't running...
return 0;
}
void Timer::pause()
{
//If the timer is running and isn't already paused...
if(( started == true ) && ( paused == false ))
{
//Pause the timer.
paused = true;
//Calculate the paused ticks
pausedTicks = SDL_GetTicks() - startTicks;
}
}
void Timer::unpause()
{
//If the timer is paused...
if( paused == true ){
//Unpause the timer.
paused = false;
//Reset the starting ticks.
startTicks = SDL_GetTicks() - pausedTicks;
//Reset the paused ticks.
pausedTicks = 0;
}
}
bool Timer::is_started(){
return started;
}
bool Timer::is_paused(){
return paused;
}
|
Thanks in advance!
EDIT: Added source code download.
http://www.mediafire.com/?4p0kjx7akdr607c Press left and right arrows to add and subtract balls.