Jump to content


timebased sleep, 0 FPS issue.


24 replies to this topic

#1 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 29 December 2012 - 08:00 PM

hi there,
i have been trying to get my game at roughly 60 FPS , a bit more or does not matter, but it was running at 150 FPS, which worked fine for using the frames as time, but i wanted to get a more steady speed, by putting in a sleep function at the end of the frame with as sleeptime 1000/60-elapsed time.
for this i used :


long long milliseconds_now() {
static LARGE_INTEGER s_frequency;
static BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
if (s_use_qpc) {
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart) / s_frequency.QuadPart;
} else {
return GetTickCount();
}
}



long long start = milliseconds_now();


long long elapsed = milliseconds_now() - start;
printf ("time: %f\n", elapsed );
Sleep(((1000/60)-elapsed));




i found this code on the internet, as i could not find a good place to get the codes for getting the elapsed time, and i honestly dont know if there is something wrong with this code or not, but as soon as i put this in i had a issue so now and then of the game running with 0 FMS
i got no errors, and it started, but just did nothing.

can anyone tell me what i did wrong, or point me at a place where i can learn this better?, as i want my game to work with frames as the time, and therefor i need a roughly steady FPS :)
thanks a lot for helping :)

#2 jbadams

    Member

  • Members
  • PipPip
  • 27 posts
  • LocationVictoria, Australia

Posted 30 December 2012 - 07:11 AM

View Postfdmfdm, on 29 December 2012 - 08:00 PM, said:

point me at a place where i can learn this better
Try "Fix Your Timestep!"

#3 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 30 December 2012 - 12:08 PM

i tried that one, but they give as ultimate code:

	double t = 0.0;
	const double dt = 0.01;

	double currentTime = hires_time_in_seconds();
	double accumulator = 0.0;

	State previous;
	State current;

	while ( !quit )
	{
		 double newTime = time();
		 double frameTime = newTime - currentTime;
		 if ( frameTime > 0.25 )
			  frameTime = 0.25;	  // note: max frame time to avoid spiral of death
		 currentTime = newTime;

		 accumulator += frameTime;

		 while ( accumulator >= dt )
		 {
			  previousState = currentState;
			  integrate( currentState, t, dt );
			  t += dt;
			  accumulator -= dt;
		 }

		 const double alpha = accumulator / dt;

		 State state = currentState*alpha + previousState * ( 1.0 - alpha );

		 render( state );
	}

but never explain what is what,
like it uses hires_time_in_seconds , which microsoft visual studio 2010 does not know:

1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(505): error C3861: 'hires_time_in_seconds': identifier not found


same goes with state, time, currentTime, accumulator and dt
now the problem here is that i need to know how long the program took for the last frame, so that i can sleep the rest of the 1/60th second.
i have read that entire tutorial, and altough the text itself is quite easy to follow, but does not explain much about the variables used in it :(

i might have to add (altough i think its quite clear now XD) that im quite new to C++, and altough i followed multiple tutorials, this is the first time im making an entire game with the need of controlling the time

#4 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1586 posts

Posted 30 December 2012 - 05:52 PM

It looks overly complicated to me. I know I did something like this in java. Basically, I got the time right before render, kept it in temp variable for currentTime, but before that, kept another variable for last loop time and put the value in there, subtract and sleep if it's less than 1/60 th of a second. so it's something like
lastTime = currentTime;
currentTime = getTime();
sleepTime = 1/60 - (currentTime - lastTime);
if(sleepTime > 0) Sleep(sleepTime);
Currently using Blender and Unity.

#5 Reedbeta

    DevMaster Staff

  • Administrators
  • 5305 posts
  • LocationBellevue, WA

Posted 30 December 2012 - 05:56 PM

View Postfdmfdm, on 30 December 2012 - 12:08 PM, said:

but never explain what is what, like it uses hires_time_in_seconds , which microsoft visual studio 2010 does not know

This is pseudocode; it's not supposed to be copy/pasted. The author is assuming you're smart enough to adapt the idea of this code to your own project. :) For instance, hires_time_in_seconds() is just a placeholder for however you measure time in your language/API/OS. In your case, you'd write a function that would use QueryPerformanceCounter and convert the result to seconds as a double. (BTW, most advanced articles on programming are like this: you usually cannot just copy/paste others' code into your own project and expect it to work, because they've made different design decisions or called things different names from you. You must adapt their code to your project.)

Anyway, trying to maintain a stable framerate by calculating the remaining time and sleeping is actually not a good approach. The problem is that "sleep" is not a precise operation. The OS will wake up your app at some point later, but you can't rely on it being at the time you requested - it will be whenever the OS decides to give you another time-slice.

A better approach is to use your graphics API to wait for the next screen vsync. The details depend on what API you're using, but hopefully there is a way to do this. It will use some internal graphics HW / OS magic to do a better job of syncing your program to 60 Hz (or whatever the screen refresh rate is, but 60 Hz is the most common) than you could likely do by yourself. Then you'd use QueryPerformanceCounter or whatever to measure the time at the start of each frame, subtract from the previous frame's result to get the time elapsed, and run your game by that amount of time, either using a fixed timestep or not.
reedbeta.com - developer blog, OpenGL demos, and other projects

#6 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 30 December 2012 - 08:02 PM

View PostReedbeta, on 30 December 2012 - 05:56 PM, said:

This is pseudocode; it's not supposed to be copy/pasted.

i had figured out that much, but as i dont know the actual codes for it, i did not get much further :)

but more on the topic, i did read something about vsync somewhere, but they said it was a bad idea because it could be turned off?
and you say it depends on what API i use, do you mean there is no standart time-calculator in c++
i know many people use libraries made by others (as i do with the library given with the template of the tutorials im following here made by IGAD), but i expected to be some standard timecalculator, that is not perfect, but given with the normal libraries.

if not, is there a way to find what does what?
the system i use now, which solved the issue of 0FPs, but gives a very rough 60 FPS:

long long milliseconds_now() {
static LARGE_INTEGER s_frequency;
static BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
if (s_use_qpc) {
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart) / s_frequency.QuadPart;
} else {
return GetTickCount();
}
}

main()
{
long long start = milliseconds_now();

long long elapsed = milliseconds_now() - start;
if((elapsed>0)&(elapsed<1000/60))
{
Sleep ((1000/60)-elapsed);
}
}

this usually gives about 57, but sometimes goes down under 40, and sometimes gives up to 62, which does proof your point of it not bieing the time i told it :D

1 last thing,
i dont know QueryPerformanceCounter, so i googled it, and i found :
http://msdn.microsof...s644904(v=vs.85).aspx

here they gave this piece of code:

BOOL WINAPI QueryPerformanceCounter(
_Out_ LARGE_INTEGER *lpPerformanceCount
);

in which if i understand it right, lpPerformanceCount, is the variable where they put the total counts, but what i was wondering here, is that in seconds(or rather, mseconds? for if it is not in seconds, it is no use to me XD
and the idea here is to use this time to make a Delta time, to get the speed, not matter what the time is?
my question here is, is it needed to sync with vsync if i can me the speed dependent of the ammount of frames/second ?





a quick summary to make sure i am not mistaken:
Dont use sleep to get a fixed framerate, as it is not precise enough.
use vsync to get the framerate (59 in my case (small question here, any idea why my default is 59? always wondered that))
and then i use QueryPerformanceCounter to make sure my games runs at the right speed.

#7 Reedbeta

    DevMaster Staff

  • Administrators
  • 5305 posts
  • LocationBellevue, WA

Posted 30 December 2012 - 09:16 PM

BTW, you can use [ code ] ... [ /code ] tags around your code to preserve the formatting on the forum.

Yes, a lot of graphics drivers these days have the option to force vsync on or off for an application, regardless of what the application actually asks for. That's a bit unfortunate, but it's not such a big deal because your game has to deal with different refresh rates anyway. (If your game is locked to 60 Hz and someone runs it on a monitor that refreshes at 75 Hz, it's going to look terrible.) Anyway, the way to ask for vsync depends on what graphics API you're using (Direct3D, OpenGL, etc). There is no standard way to do it in C++, because this doesn't have anything to do with the language - it has to do with the graphics API.

As for QueryPerformanceCounter, you already have the code to use it; it's in your milliseconds_now() function (didn't you notice that?). Obviously if you have the time in milliseconds then you can easily convert to seconds if you need to.
reedbeta.com - developer blog, OpenGL demos, and other projects

#8 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1586 posts

Posted 30 December 2012 - 09:40 PM

I think it's usually better to time animation sequences and let the game run as fast as it wants. I don't notice as much stutter that way. The only time I've stopped frames was with a browser app because it needed a pause for other things in the browser to be working. Since I had to have a pause, I used it also as a buffer for when the computer was working harder on a particular loop.
Currently using Blender and Unity.

#9 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 30 December 2012 - 09:48 PM

hehehe nope did not notice that :)
it was yesterday when i tried to figure it out, and forgot it while sleeping :)

but i should be using direct3d if im not mistaken, so ill check the internet for that :)

and fireside, the issue with running it as fast as it wants, is that everything will run faster, unless you adjust the speed according to the framerate.

and thanks for all the help :) this time issue really was the biggest problem i faced so far, because of my lack of knowledge on the subject XD
working on the background and collision detector with the map at the moment, but ill check this timer tomorrow (or if i can this evening/night) to see if i catch any problems :)
thanks again

ps. i'll do that code thing next time :)

#10 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1586 posts

Posted 30 December 2012 - 10:09 PM

Quote

and fireside, the issue with running it as fast as it wants, is that everything will run faster, unless you adjust the speed according to the framerate.

No, because you are adjusting animations and distances using a timer instead of using the framerate as a timer. It sounds complicated, but it really isn't. Unity uses this method. I think a lot of engines do. You are just taking the time from the last frame and factoring it into animations. It has the added advantage of making animations more asynchronous because you aren't suddenly stopping everything and then dropping all the frames at that loop, and you aren't basically punishing people who have fast computers.
Currently using Blender and Unity.

#11 Stainless

    Member

  • Members
  • PipPipPipPip
  • 577 posts
  • LocationSouthampton

Posted 30 December 2012 - 10:21 PM

In general using sleep for timing is very rare these days.

Most platforms now work on a timed event system.

The model is

Setup a timer at the require framerate
Release back to host
Event fires and control passes back to game
Game draws/updates and returns


XNA uses a separate update / draw cycle. The update method is going to be be called at the required frame rate, the draw method might not

Most other systems I work on use call backs. You register a timer callback and set the timer off

You cannot be sure to have a system clock with the required accuracy, hell the granularity on some systems is 100ms so when you query the system timer your max framerate is 10fps

I would look for other techniques, otherwise your code is not portable

#12 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 31 December 2012 - 12:04 AM

View Postfireside, on 30 December 2012 - 10:09 PM, said:

No, because you are adjusting animations and distances using a timer instead of using the framerate as a timer. It sounds complicated, but it really isn't. Unity uses this method. I think a lot of engines do. You are just taking the time from the last frame and factoring it into animations. It has the added advantage of making animations more asynchronous because you aren't suddenly stopping everything and then dropping all the frames at that loop, and you aren't basically punishing people who have fast computers.

i actually meant that with adjusting speed according to the framerate :)


btw a small question that is offtopic, but no need to make another topic if someone here can explain this to me,
i have read in the tutorial i was following that a warning of a int going to float or the other way around is bad,
not my physics are working fine as i have them now, so should i worry about these warnings or just take them out by telling the compiler i know its happening?

#13 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1586 posts

Posted 31 December 2012 - 02:09 AM

If you go from float to int, the decimal portion will be dropped, which can be inaccurate. For instance 1.999 would end up being 1 as an int. I prefer to round in that situation. A simple way is to add .5 to it before the conversion. Use a typecast to eliminate the warning. It's kind of bad form and it pays to eliminate them. If you have more than one, write a function. Take warnings seriously, especially when you are new. It's a good time to do a little more study and learn a bit more. There may be a rounding function in the standard library, also. I haven't used c++ in a while.
Currently using Blender and Unity.

#14 Stainless

    Member

  • Members
  • PipPipPipPip
  • 577 posts
  • LocationSouthampton

Posted 31 December 2012 - 10:40 AM

going from float to int sometimes is a requirement.

If you are working on opengles, there is a known issue with aliasing. If you draw a sprite at pixel x = 10.1 it will look different than if you draw it at pixel 10

Use casts to get rid of the warning and think about what you are doing each time.

#15 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 31 December 2012 - 12:00 PM

im working on directRd and i have seen no problems with aliasing, so at least thats not a issue,
but are you guys saying its best to recheck all the warnings to see if it is really needed to make that conversion, and if it is use a cast (im guessing a cast is like putting (int) before the variable)?
as you can see under here there are quite some warnings,
now the & warnings will be gone in seconds :D, but the others, is this ammount a issue?
(dont worry about the error, just put that in to get the warnings, did not know how to see them otherwise :D)

warnings:

1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(254): warning C4244: '+=' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(283): warning C4244: '+=' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(285): warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(302): warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(303): warning C4244: 'argument' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(308): warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(309): warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(312): warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(313): warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(314): warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(315): warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(335): warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(376): warning C4244: '=' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(377): warning C4244: '=' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(378): warning C4244: '=' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(379): warning C4244: '=' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(457): warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(462): warning C4244: 'argument' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(462): warning C4244: 'argument' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(463): warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(463): warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(473): warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(474): warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(487): warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(487): warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(508): error C2065: 'a' : undeclared identifier
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(508): error C2146: syntax error : missing ';' before identifier 'i'
1>c:\myprojects\template\devmaster_intro-to-c-tmpl83.00c_oct14\game.cpp(518): warning C4244: '=' : conversion from 'float' to 'int', possible loss of data
under here my code untill this point, still need to clean some things as i was converting from max and min x/y values to tilecollision, so thats not finished yet.

// Template, major revision 3
// IGAD/NHTV - Jacco Bikker - 2006-2009


#include "string.h"
#include "surface.h"
#include "stdlib.h"
#include "template.h"
#include "game.h"



using namespace Tmpl8;

// sprites

Sprite poppetje( new Surface("assets/poppetje.BMP"), 1);
Sprite bullet( new Surface("assets/bullet.BMP"), 1);
Sprite bubble1( new Surface("assets/bubble1.BMP"), 1);


//background
Surface* tileSet[9];
int landTile[11][40] = {{2, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,1},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
{3, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4}};
   int floory = 640;


// player variables
float xplayer = 320;
float yplayer = 200;
float dyplayer;
int xspeed = 3;
int playerheigth = 30;
int playertilex1;
int playertilex2;
int playertiley1;
int playertiley2;
bool left;
bool right;
bool up;
bool down;


// bullet variables
float xbullet[6];
float ybullet[6];
float x1bullet[6];
float y1bullet[6];
float x2bullet[6];
float y2bullet[6];
float dxbullet[6];
float dybullet[6];
float speed = 10;
float steps[6];
int bullet1[6]; // 1 is false 2 is true
int i=0;
bool shot = false;
int shotbreak = 0;
int shoottime = 10;


// bubble variables
int bubble1x[6]; //= 100;
int bubble1y[6]; //= 50;
int drawbubble[6]; //= true;
float bubble1dy[6]; //= 1;
float bubble1ddy[6]; //= 0.1;
float bubble1ddx[6]; //= 0.1;
float bubble1dx[6]; //= 1;
float maxyspeed[6]; //= 12;
float maxxspeed[6];
int bubblecount;
float bubbledist;
int bubbledistcount;
float bubbledistfix;
float bubblefraction;
float bubblexdist;
float bubbleydist;
int bubbleradius[6];
int bubbledoubler[6];

// collision variables
int distance;

//level variables
int deadbubblecount;
int bubblestokill;
int lvl;


// timer variables




long long milliseconds_now() {
    static LARGE_INTEGER s_frequency;
    static BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
    if (s_use_qpc) {
        LARGE_INTEGER now;
        QueryPerformanceCounter(&now);
        return (1000LL * now.QuadPart) / s_frequency.QuadPart;
    } else {
        return GetTickCount();
    }
}





void Game::Init()
{

// background
  tileSet[0] = new Surface( "assets/background1.BMP" );
   tileSet[1] = new Surface( "assets/background2.BMP" );
   tileSet[2] = new Surface( "assets/background3.BMP" );
   tileSet[3] = new Surface( "assets/background4.BMP" );
   tileSet[4] = new Surface( "assets/background5.BMP" );
   tileSet[5] = new Surface( "assets/background6.BMP" );
   tileSet[6] = new Surface( "assets/background7.BMP" );
   tileSet[7] = new Surface( "assets/background8.BMP" );


// bullet inits
bullet1[0]=1;
bullet1[1]=1;
bullet1[2]=1;
bullet1[3]=1;
bullet1[4]=1;
bullet1[5]=1;

// bubbles inits
bubble1x[0]=100; 
bubble1x[1]=200;
bubble1x[2]=300;

bubble1y[0]=50;
bubble1y[1]=50;
bubble1y[2]=50;

drawbubble[0]=2;
drawbubble[1]=2;
drawbubble[2]=2;

bubble1dy[0]=1;
bubble1dy[1]=1;
bubble1dy[2]=1;

bubble1ddy[0]=0.1;
bubble1ddy[1]=0.1;
bubble1ddy[2]=0.1;
bubble1ddy[3]=0.1;
bubble1ddy[4]=0.1;
bubble1ddy[5]=0.1;

bubble1ddx[0]=0.00;
bubble1ddx[1]=0.00;
bubble1ddx[2]=0.00;
bubble1ddx[3]=0.00;
bubble1ddx[4]=0.00;
bubble1ddx[5]=0.00;

bubble1dx[0]=1;
bubble1dx[1]=1;
bubble1dx[2]=1;

maxyspeed[0]=12;
maxyspeed[1]=12;
maxyspeed[2]=12;
maxyspeed[3]=12;
maxyspeed[4]=12;
maxyspeed[5]=12;


bubblestokill = 3;

maxxspeed[0] = 5;
maxxspeed[1] = 5;
maxxspeed[2] = 5;
maxxspeed[3] = 5;
maxxspeed[4] = 5;
maxxspeed[5] = 5;

bubbleradius[0] = 20;
bubbleradius[1] = 20;
bubbleradius[2] = 20;
bubbleradius[3] = 20;
bubbleradius[4] = 20;
bubbleradius[5] = 20;

bubbledoubler[0] = 0;
bubbledoubler[1] = 0;
bubbledoubler[2] = 0;
bubbledoubler[3] = 0;
bubbledoubler[4] = 0;
bubbledoubler[5] = 0;

// lvl inits
lvl = 1;

}
int mousex, mousey;
void Game::MouseMove( unsigned int x, unsigned int y )
{
    mousex = x;
    mousey = y;
}


void Game::Tick( float a_DT )
{

long long start = milliseconds_now();

//background
 m_Screen->Clear( 0 );
   for (int indexX = 0; indexX <= 39; indexX++)
    {
        for (int indexY = 0; indexY <= 10; indexY++)
        {
            int tile = landTile[indexY][indexX];
            tileSet[tile]->CopyTo( m_Screen, indexX * 20, indexY * 60 );
        }
    }

 // bubblecalculator


while (bubblecount<bubblestokill)
{
if(drawbubble[bubblecount]==2)
{
/*
if ((bubble1dy[bubblecount] < 0.01) & (bubble1dy[bubblecount] > -0.01))
{
bubble1dy[bubblecount] = 0;
}
*/



bubble1y[bubblecount] += bubble1dy[bubblecount];
bubble1dy[bubblecount] += bubble1ddy[bubblecount];

// to prevent alls from jumping straight up and down
if ((bubble1dx[bubblecount] < 1) &  (bubble1dx[bubblecount] > 0))
{
bubble1dx[bubblecount] += bubble1ddx[bubblecount];
}
if ((bubble1dx[bubblecount] < 0) &  (bubble1dx[bubblecount] > -1))
{
bubble1dx[bubblecount] -= bubble1ddx[bubblecount];
}

if ((bubble1dy[bubblecount] >maxyspeed[bubblecount]))
{
bubble1dy[bubblecount] = maxyspeed[bubblecount];
}
if ((bubble1dy[bubblecount] <-maxyspeed[bubblecount]))
{
bubble1dy[bubblecount] = -maxyspeed[bubblecount];
}


if (bubble1y[bubblecount] < 20)
{
bubble1y[bubblecount] = 40 - bubble1y[bubblecount];
bubble1dy[bubblecount]= -bubble1dy[bubblecount];
}

bubble1x[bubblecount] += bubble1dx[bubblecount];

if(((bubble1x[bubblecount]> (780 - 2 * bubbleradius[bubblecount]) )& (bubble1dx[bubblecount] > 0))|| ((bubble1x[bubblecount] <20) & bubble1dx[bubblecount] <0))
{
bubble1dx[bubblecount] = -bubble1dx[bubblecount];
}

if (bubble1y[bubblecount] > (floory- 2*bubbleradius[bubblecount]))
{
bubble1y[bubblecount]= floory - 2*bubbleradius[bubblecount];
bubble1dy[bubblecount] = -bubble1dy[bubblecount];
}

bubble1.Draw(bubble1x[bubblecount],bubble1y[bubblecount], m_Screen);
}
while(bubbledistcount<bubblestokill)
{
if (bubbledistcount!=bubblecount)
{
if(drawbubble[bubblecount] == 2 & drawbubble[bubblecount] == 2)
bubbledist = sqrtf((((bubble1x[bubbledistcount]+bubbleradius[bubbledistcount] )-(bubble1x[bubblecount]+bubbleradius[bubblecount]))*(((bubble1x[bubbledistcount]+bubbleradius[bubbledistcount])-(bubble1x[bubblecount]+bubbleradius[bubblecount])))+(((bubble1y[bubbledistcount]+bubbleradius[bubbledistcount])-(bubble1y[bubblecount]+bubbleradius[bubblecount]))*((bubble1y[bubbledistcount]+bubbleradius[bubbledistcount])-(bubble1y[bubblecount]+bubbleradius[bubblecount])))));
if (bubbledist<(bubbleradius[bubblecount]+bubbleradius[bubbledistcount]))
{
bubbledistfix = bubbleradius[bubblecount]+bubbleradius[bubbledistcount]-bubbledist;
bubblefraction = bubbledistfix / bubbledist;
bubblexdist =(bubble1x[bubbledistcount]+bubbleradius[bubbledistcount])-(bubble1x[bubblecount]+bubbleradius[bubblecount]);
bubbleydist =(bubble1y[bubbledistcount]+bubbleradius[bubbledistcount])-(bubble1y[bubblecount]+bubbleradius[bubblecount]);


bubble1dx[bubbledistcount] = bubble1dx[bubbledistcount] + 2.5 * (bubblefraction * bubblexdist * 0.5);
  bubble1dy[bubbledistcount] = bubble1dy[bubbledistcount] + 2.5 * (bubblefraction * bubbleydist * 0.5);
bubble1dx[bubblecount] = -bubble1dx[bubblecount] - (bubblefraction * bubblexdist * -0.5);
bubble1dy[bubblecount] = -bubble1dy[bubblecount] - (bubblefraction * bubbleydist * -0.5);
bubbledoubler[bubblecount]++;

if ((bubble1dy[bubblecount] >maxyspeed[bubblecount]))
{
bubble1dy[bubblecount] = maxyspeed[bubblecount];
}
if ((bubble1dy[bubblecount] <-maxyspeed[bubblecount]))
{
bubble1dy[bubblecount] = -maxyspeed[bubblecount];
}
if ((bubble1dy[bubbledistcount] >maxyspeed[bubblecount]))
{
bubble1dy[bubbledistcount] = maxyspeed[bubblecount];
}
if ((bubble1dy[bubbledistcount] <-maxyspeed[bubblecount]))
{
bubble1dy[bubbledistcount] = -maxyspeed[bubblecount];
}

if(bubbledoubler[bubbledistcount] == 10 & bubblestokill<6)
{

bubble1x[bubblestokill] = bubble1x[bubbledistcount] + 2*bubbleradius[bubbledistcount];
bubble1y[bubblestokill] = bubble1y[bubbledistcount] + 2*bubbleradius[bubbledistcount];
bubble1dx[bubblestokill] = - bubble1dx[bubbledistcount];
bubble1dy[bubblestokill] = bubble1dy[bubbledistcount];
bubble1ddy[bubblestokill] = bubble1ddy[bubbledistcount];
drawbubble[bubblestokill] = 2;
bubblestokill++;
bubbledoubler[bubbledistcount]=0;
}
if(bubble1dx[bubbledistcount]>maxxspeed[bubbledistcount])
{
bubble1dx[bubbledistcount] = maxxspeed[bubbledistcount];
}
if(bubble1dx[bubblecount]>maxxspeed[bubblecount])
{
bubble1dx[bubblecount] = maxxspeed[bubblecount];
}

if(bubble1dx[bubbledistcount]<-maxxspeed[bubbledistcount])
{
bubble1dx[bubbledistcount] = -maxxspeed[bubbledistcount];
}
if(bubble1dx[bubblecount]<-maxxspeed[bubblecount])
{
bubble1dx[bubblecount] = -maxxspeed[bubblecount];
}
}
}
bubbledistcount++;
}
bubbledistcount = 0;
bubblecount++;
}
bubblecount = 0;

// landTile[13][66]


playertilex1 = (xplayer-1)/20;
playertilex2 = (xplayer+20)/20;
playertiley1 = (yplayer/60);
playertiley2 = ((yplayer + 20)/60);
if ((
landTile[playertiley1 ][playertilex1] == 6 || 
landTile[playertiley1 ][playertilex1] == 3) & 
(landTile[playertiley2 ][playertilex1] == 6 || 
landTile[playertiley2 ][playertilex1] == 3)
)
{
left = false;
}
else
{
left = true;
}
if ((
landTile[playertiley1 ][playertilex2] == 6 || 
landTile[playertiley1 ][playertilex2] == 4 )& 
(landTile[playertiley2 ][playertilex2] == 6 || 
landTile[playertiley2 ][playertilex2] == 4)
)
{
right = false;
}
else
{
right = true;
}

if ((
landTile[playertiley2 ][playertilex1] == 5 || 
landTile[playertiley2 ][playertilex1] == 4 ||
landTile[playertiley2 ][playertilex1] == 3) & 
(landTile[playertiley2 ][playertilex2] == 5 || 
landTile[playertiley2 ][playertilex2] == 4 ||
landTile[playertiley2 ][playertilex2] == 3)
)
{
down = false;
}
else
{
down = true;
}





if(GetAsyncKeyState( 0x44 )) // D
{
if (right == true)
{
xplayer=xplayer + xspeed;
}
}
if(GetAsyncKeyState( 0x41 ))  // A
{
if (left == true)
{
xplayer = xplayer - xspeed; 
}
}
if((GetAsyncKeyState( VK_SPACE ))&(down == false))
{
dyplayer = 10;
}
if(dyplayer>0)
{
yplayer -= dyplayer;
dyplayer -= 0.1;
}
if (down == true)
{
yplayer += 5;
}

if(yplayer > (floory - playerheigth))
{
yplayer = (floory - playerheigth);
}



m_Screen->Line( xplayer, yplayer, mousex, mousey, 0xff0000 );
poppetje.Draw(xplayer,yplayer, m_Screen);

// bullet calculator

while(i<6)
{

  if((GetAsyncKeyState( MK_LBUTTON )||(GetAsyncKeyState(  WM_LBUTTONDOWN))) & (bullet1[i]==1) & (shotbreak > shoottime))
{
    bullet1[i] = 2;
x2bullet[i] = mousex;
y2bullet[i] = mousey;
x1bullet[i] = xplayer;
y1bullet[i] = yplayer;
steps[i] = ((sqrtf(((x2bullet[i]-x1bullet[i])*(x2bullet[i]-x1bullet[i]))+((y2bullet[i]-y1bullet[i])*(y2bullet[i]-y1bullet[i]))))/speed);
dxbullet[i]=(x2bullet[i]-x1bullet[i])/steps[i];
dybullet[i]=(y2bullet[i]-y1bullet[i])/steps[i];
xbullet[i] = x1bullet[i];
ybullet[i] = y1bullet[i];
shot = true;
shotbreak=0;
}
   if(bullet1[i] == 2)
{
  bullet.Draw(xbullet[i],ybullet[i], m_Screen);
xbullet[i] += dxbullet[i];
ybullet[i] += dybullet[i];

if (xbullet[i]<0||xbullet[i]>1300||ybullet[i]<0||ybullet[i]>900)
{
bullet1[i]=1;
xbullet[i]=0;
ybullet[i]=0;
}
}
if (shot == false)
{ 
i++;
}
else
{
i = 7;
}
}
a
i=0;
shot = false;
// making sure player wont shoot all bullets at once (+ giving possibilities to different kind of weapons)
shotbreak++;

// hitcalculator
while(i<6)
{
while (bubblecount < bubblestokill)
{
distance = sqrtf(((bubble1x[bubblecount]+bubbleradius[bubblecount])-(xbullet[i]+2))*((bubble1x[bubblecount]+bubbleradius[bubblecount])-(xbullet[i]+2))+((bubble1y[bubblecount]+bubbleradius[bubblecount])-(ybullet[i]+2))*((bubble1y[bubblecount]+bubbleradius[bubblecount])-(ybullet[i]+2)));

if(distance<27)
{


drawbubble[bubblecount] = 1;
xbullet[i] = 0;
ybullet[i] = 0;
bubble1x[bubblecount] = 0;
bubble1y[bubblecount] = 0;
}
bubblecount++;
}
i++;
bubblecount=0;
}


i=0;

deadbubblecount = (drawbubble[0]+drawbubble[1]+drawbubble[2]+drawbubble[3]+drawbubble[4]+drawbubble[5]);
if(deadbubblecount <= bubblestokill)
{

if(lvl == 1)
{

lvl2 ();
}
else if(lvl == 2)
{

lvl3 ();
}

}
if((deadbubblecount==bubblestokill) & (lvl == 3))
{
lvl3 ();
}






long long elapsed = milliseconds_now() - start;
// printf ("time: %f\n", elapsed );
if((elapsed>0)&(elapsed<1000/60))
{
// Sleep ((1000/60)-elapsed);
}


}


#16 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1586 posts

Posted 31 December 2012 - 12:34 PM

I guess it's up to you. Personally, I don't like them. If nothing else, you'll probably miss something more crucial in all that. If they don't bother you, they are harmless as long as it works the way you want. The way I look at it is that, I haven't written clear code if I get a warning.
Currently using Blender and Unity.

#17 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 31 December 2012 - 12:44 PM

View Postfireside, on 31 December 2012 - 12:34 PM, said:

I guess it's up to you. Personally, I don't like them. If nothing else, you'll probably miss something more crucial in all that.

hehehe, gettign rid of them was never the question ;)
it was how :D by a call or by actually changing them.

but you are right, they can be annoying if you have something serious :)

#18 Stainless

    Member

  • Members
  • PipPipPipPip
  • 577 posts
  • LocationSouthampton

Posted 31 December 2012 - 02:31 PM

Well you should know that 2.5 is a double so if you do something like float x += 2.4; you will get a warning.

It's good practice to add a 'f' to float variables. float x += 2.4f; will not generate a warning.

Then if you do something like int ix = x; that will generate a warning when int ix = (int)x; will not

Compilers are stupid, it's up to you to prove you are more intelligent than they are by telling them "I wrote the code, I know what I'm doing!"

This is boring I know, but it is important. Some things that come up as warnings really are bugs.

For example

extern void dosomething(int x, int y, int* result);

void me()
{
     int x=10;
     int y=15;
     int z=0;
     dosomething(x,y,z);
}

Will generate a warning, something like "warning converting an int to a pointer without a cast"

Running the code will cause a crash.

#19 fdmfdm

    Member

  • Members
  • PipPip
  • 25 posts

Posted 31 December 2012 - 03:41 PM

thanks stainless, that was quite a good explaination :)
ill check out all those warnings after i finished my tilecollisiondetector (which is bieing a pain as im trying to make to so that the bubbles bounce off corners realisticly.....)

#20 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 31 December 2012 - 04:47 PM

Keep in mind that casting a float to int, internally generates a call to ftol, which is quite slow. As for the VSync issue, I watched a Google I/O video yesterday that describes it pretty well, and why it helps:
"Stupid bug! You go squish now!!" - Homer Simpson





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users