Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
So my problem is this: I am making a pong game and the velocity of the ball is calculated using the screen size and on my PC it works fine. When i send the game to a friend the ball seems to move extremely fast. I think the problem is in the while loop because i put a counter in it to delay the start of the game. However on other PCs it seems like the while loop is spinning so fast it disregards the counter all together and starts the game instantaneously. My PC isn't low-end by any means so i cannot figure out what the problem is.
This is well-known and well-solved problem. Simple games from the 80's suffer from this problem. They were built to redraw the screen as fast as your computer would allow, and now (assuming you can get them to run) they run unplayably fast. The speed at which your game runs should not be determined by how fast your computer can execute a while loop, or your game will never play the same on two computers.
Games have solved this problem for decades now by scaling the advancement of the game-state by the frame-rate of the computer currently running the game.
The first thing you need to do in your while loop is calculate the elapsed time since the last iteration of your loop, this will be some tiny fraction of a second. Your game state needs to advance by that much time, and only that much time.
In very simple terms, if you're moving your ball using something like this...
ball_x += ball_horizontal_momentum
ball_y += ball_vertical_momentum
You would need to modify each momentum by a scaling factor determined by how much time has passed:
ball_x += ball_horizontal_momentum * elapsed_time
ball_x += ball_vertial_momentum * elapsed_time
So, on a very slow computer your ball might wind up jumping 100 pixels each frame. On a computer which is 10 times faster, your ball would move 10 pixels each frame. The result is that on both computers, the ball will appear to move the exact same speed.
All of your animations need to be scaled in this way.
Related
I'm learning basic frame independent movement, but I have a necessary need in the implementation.
Right now, I'm searching for C++ code, but I need a complete example inside a GameLoop that allows an increase in speed. Not a gradual increase, but just the ability to move my sprite faster. I have to translate the C++ code to vb .net since there are not many examples. So let me be clear about this ->
I have a simple GameLoop. In the GameLoop, I have two calls to functions
Update()
Render()
I understand that for the Update() function I should put a deltaTime parameter. So it should be
Update(deltaTime As double)
Since this is how most examples on the web are shown, I just copied the idea but I don't have an actual frame independent setup yet.
How can I set this up and call the Render function.
Please keep in mind, that if it works, that's fine - I cut and paste a different example like that before, but there was no way to increase the speed of the moving sprite. I don't even know where to begin with this?
Please note if you only have C++ code, I will do my best to translate it, so for me it's acceptable.
I wont give you code, cause I'm positive that you will be able to fix this with a proper description, but I will gladly explain how to move your sprite without frame rate dependency.
As you said, you already pass a delta-time in to the function.
The delta time is the time that it took between now and the last time the function was called (a frame).
When you move your sprite, you probably move it by a specific number of pixels, instead of doing this every frame, you should multiply the pixel range with the delta time.
This will make into a quite simple formula:
DetlaTime * TheNumberOfPixelsToMoveInASecond.
If you mul it with 10, then the sprite will move 10 pixels in one second. Mul it with 100, it will move 100 pixels in one second.
That deltaTime idea is to allow your game to run in a way where the perceived speed of the gameplay is constant no matter how fast or slow the machine and environment are that are running the game.
You might notice if you run some poorly coded games designed for old hardware on hardware much newer that the gameplay goes way too fast and becomes unplayable on those fast machines without deliberately slowing things down. There are actual slowdown utilities just to deal with that problem, like Mo'Slow and Cpukiller. This is because these old games were coded in a way where things were being changed by a constant amount every frame instead of a variable amount based on the time that has passed.
So to avoid this problem, you move all your sprites each frame by numbers that are multiples of deltaTime. That'll give you the sense of consistent speed regardless of the speed of the machine/environment.
Now if you want an adjustable game speed on top of that where you want to allow users to deliberately make the game faster, then you introduce a second variable on top of deltaTime that you also multiply by, like gameSpeed. So your sprites should move in Update by a multiple of both deltaTime and gameSpeed.
I am creating a physics simulator of sorts and I have thousands of point-like objects (single pixels) moving at the same time. The way I have this setup currently is each point moving only one pixel per frame, which makes it easy to keep track of them in a two dimensional array and check if they're going to collide. However, this solution doesn't permit frame independent movement, which is necessary, because the collision detection is very slow. What is the most efficient way of doing collision detection in this case?
Okay, first things first:
On any modern OS, your app will be either
Sharing processor time with another app, or the OS itself, which is about the same thing
Doing different amounts of work at different times - like, loading assets in the background, rebuilding collision trees, or playing Pac-Man
Fighting the flying toasters
Also, you never know what kind of hardware your app, if distributed, will be running on. This entails lots of headaches, but the first and foremost is that you never know, at compile time, how much real time has elapsed between frames.
(A funny situation recently arose when a customer wanted an orbital calculation to be correct after he had closed his laptop, got on a plane, and reopened it. Easy enough to fix, but you might want to anticipate a 12 hour per frame situation.)
So, how do you deal with this?
Any framework will provide a timer of some sort. I'm not sure how SDL handles this, but typically, on Windows, you'd use GetTickCount() to get the elapsed milliseconds between frames. Each particle has a velocity, expressed in units per second. (Please use meters. Save the world the pain of Units Of user1868866).
When moving the particle,
pos += velocity * elapsed_time;
Or, as a concrete example, if I am in a car moving at 50 mph,
position += 50 miles/hr * 2 hr = 100 miles.
Doing this will solve the problem where particles are moving in frame time instead of simulation/game/real time.
Now, the collision-detection problem. Since we're working in 2D here...
With more than a handful of objects, you can't compare every object to every other object in a reasonable amount of time to see if they collide.
So, we have fancy things like Quadtrees. The idea is to partition your space recursively into quadrants, each of which is really a data structure that somehow "contains" all of the items that fall within its bounds. Then, you only have to check for collision between items within the same quadtree node.
Implementation of a quadtree for your specific applicatino is way, way too long to be appropriate for an SO answer, but I encourage you to research it, try and implement it, and come back here with any issues you have. Another great resource is gamedev.stackexchange.com, which is more game/graphics focused than SO.
Good luck.
I guess I have some explaining to do:
I'm fairly new to game programming, so please don't get mad if I don't understand a concept immediately
The game makes use of DirectX 10 and is written in C++
It's very simple 2D game
The situation: Despite of being very simple in both game logic and graphics, it still takes my CPU and GPU load to 100%. Even the menu is displayed with more than 2000 frames per second.
My problem is not that the game runs too fast. I already timed sprite animations and game logic using the QueryPerformanceCounter function.
The actual problem is that the game calculates the same code numerous times without anything happening on the screen, therefore putting a massive load on my hardware.
In what ways can I decrease the hardware load of my game? I feel like using Sleep is "cheating".
Thank to Damon for pointing me in the right direction, I looked into the present function. (http://msdn.microsoft.com/en-us/library/windows/desktop/bb174576(v=vs.85).aspx)
All it took to solve both CPU and GPU load problems was changing
swapChain->Present(0, 0);
to
swapChain->Present(1, 0);
Just a quick suggestion:
Everytime you enter the game loop calculate the time passed since the last time you entered.
If this time is below a given threshold just return without processing anything.
I made a program (in C++, using gl/glut) for study purposes where you can basically run around a screen (in first person), and it has several solids around the scene. I tried to run it on a different computer and the speed was completely different, so I searched on the subject and I'm currently doing something like this:
Idle function:
start = glutGet (GLUT_ELAPSED_TIME);
double dt = (start-end)*30/1000;
<all the movement*dt>
glutPostRedisplay ();
end = glutGet (GLUT_ELAPSED_TIME);
Display function:
<rendering for all objects>
glutSwapBuffers ();
My question is: is this the proper way to do it? The scene is being displayed after the idle function right?
I tried placing end = glutGet (GLUT_ELAPSED_TIME) before glutSwapBuffers () and didn't notice any change, but when I put it after glutSwapBuffers () it slows down alot and even stops sometimes.
EDIT: I just noticed that in the way I'm thinking, end-start should end up being the time that passed since all the drawing was done and before the movement update, as idle () would be called as soon as display () ends, so is it true that the only time that's not being accounted for here is the time the computer takes to do all of the movement? (Which should be barely nothing?)
Sorry if this is too confusing..
Thanks in advance.
I don't know what "Glut" is, but as a general rule of game development, I would never base movement speed off of how fast the computer can process the directives. That's what they did in the late 80's and that's why when you play an old game, things move at light speed.
I would set up a timer, and base all of my movements off of clear and specific timed events.
Set up a high-resolution timer (eg. QueryPerformanceCounter on Windows) and measure the time between every frame. This time, called delta-time (dt), should be used in all movement calculations, eg. every frame, set an object's position to:
obj.x += 100.0f * dt; // to move 100 units every second
Since the sum of dt should always be 1 over 1 second, the above code increments x by 100 every second, no matter what the framerate is. You should do this for all values which change over time. This way your game proceeds at the same rate on all machines (framerate independent), rather than depending on the rate the computer processes the logic (framerate dependent). This is also useful if the framerate starts to drop - the game doesn't suddenly start running in slow-motion, it keeps going at the same speed, just rendering less frequently.
I wouldn't use a timer. Things can go wrong, and events can stack up if the PC is too slow or too busy to run at the required rate. I'd let the loop run as fast as it's allowed, and each time calculate how much time has passed and put this into your movement/logic calculations.
Internally, you might actually implement small fixed-time sub-steps, because trying to make everything work right on variable time-steps is not as simple as x+=v*dt.
Try gamedev.net for stuff like this. lots of articles and a busy forum.
There is a perfect article about game loops that should give you all the information you need.
You have plenty of answers on how to do it the "right" way, but you're using GLUT, and GLUT sometimes sacrifices the "right" way for simplicity and maintaining platform independence. The GLUT way is to register a timer callback function with glutTimerFunc().
static void timerCallback (int value)
{
// Calculate the deltas
glutPostRedisplay(); // Have GLUT call your display function
glutTimerFunc(elapsedMilliseconds, timerCallback, value);
}
If you set elapsedMilliseconds to 40, this function will be called slightly less than 25 times a second. That slightly less will depend upon how long the computer takes to process your delta calculation code. If you keep that code simple, your animation will run the same speed on all systems, as long as each system can process the display function in less than 40 milliseconds. For more flexibility, you can adjust the frame rate at runtime with a command line option or by adding a control to your interface.
You start the timer loop by calling glutTimerFunc(elapsedMilliseconds, timerCallback, value); in your initialization process.
I'm a games programmer and have done this many times.
Most games run the AI in fixed time increments like 60hz for example. Also most are synced to the monitor refresh to avoid screen tearing so the max rate would be 60 even if the machine was really fast and could do 1000 fps. So if the machine was slow and was running at 20 fps then it would call the update ai function 3 times per render. Doing it this way solves rounding error problems with small values and also makes the AI deterministic across multiple machines since the AI update rate is decoupled from the machine speed ( necessary for online multiplayer games).
This is a very hard question.
The first thing you need to awnser yourself is, do you really want your application to really run at the same speed or just appear to run the same speed? 99% of the time you only want it to appear to run the same speed.
Now there are two problems: Speeding up you application or slowing it down.
Speeding up your application is really hard, since that requires things like dynamic LOD that adjusts to the current speed. This means LOD in everything, not only graphics.
Slowing your application down is fairly easy. You have two options sleeping or "busy waiting". It basically depends on your target frame rate for your simulation. If your simulation is way above something like 50 ms you can sleep. The problem is that when sleeping you are depended on the process scheduler and it works on average system at granularity of 10 ms.
In games busy waiting is not such a bad idea. What you do is you update your simulation and render your frame, then you use an time accumulator for the next frame. When rendering frames without simulation you then interpolate the state to get a smooth animation. A really great article on the subject can be found at http://gafferongames.com/game-physics/fix-your-timestep/.
I am programming a game using Visual C++ 2008 Express and the Ogre3D sdk.
My core gameplay logic is designed to run at 100 times/second. For simplicity, I'll say it's a method called 'gamelogic()'. It is not time-based, which means if I want to "advance" game time by 1 second, I have to call 'gamelogic()' 100 times. 'gamelogic()' is lightweight in comparison to the game's screen rendering.
Ogre has a "listener" logic that informs your code when it's about to draw a frame and when it has finished drawing a frame. If I just call 'gamelogic()' just before the frame rendering, then the gameplay will be greatly affected by screen rendering speed, which could vary from 5fps to 120 fps.
The easy solution that comes to mind is : calculate the time elapsed since last rendered frame and call 'gamelogic()' this many times before the next frame: 100 * timeElapsedInSeconds
However, I pressume that the "right" way to do it is with multithreading; have a separate thread that runs 'gamelogic()' 100 times/sec.
The question is, how do I achieve this and what can be done when there is a conflict between the 2 separate threads : gamelogic changing screen content (3d object coordinates) while Ogre is rendering the screen at the same time .
Many thanks in advance.
If this is your first game application, using multi-threading to achieve your results might be more work than you should really tackle on your first game. Sychronizing a game loop and render loop in different threads is not an easy problem to solve.
As you correctly point out, rendering time can greatly affect the "speed" of your game. I would suggest that you do not make your game logic dependent on a set time slice (i.e. 1/100 of a second). Make it dependent on the current frametime (well, the last frametime since you don't know how long your current frame will take to render).
Typically I would write something like below (what I wrote is greatly simplified):
float Frametime = 1.0f / 30.0f;
while(1) {
game_loop(Frametime); // maniuplate objects, etc.
render_loop(); // render the frame
calculate_new_frametime();
}
Where Frametime is the calculcated frametime that the current frame took. When you process your game loop you are using the frametime from the previous frame (so set the initial value to something reasonable, like 1/30th or 1/15th of a second). Running it on the previous frametime is close enough to get you the results that you need. Run your game loop using that time frame, then render your stuff. You might have to change the logic in your game loop to not assume a fixed time interval, but generally those kinds of fixes are pretty easy.
Asynchoronous game/render loops may be something that you ultimately need, but that is a tough problem to solve. It involves taking snapshops of objects and their relevant data, putting those snapshots into a buffer and then passing the buffer to the rendering engine. That memory buffer will have to be correctly partitioned around critical sections to avoid having the game loop write to it while the render loop is reading from it. You'll have to take care to make sure that you copy all relevant data into the buffer before passing to the render loop. Additionally, you'll have to write logic to stall either the game or render loops while waiting for one or the other to complete.
This complexity is why I suggest writing it in a more serial manner first (unless you have experience, which you might). The reason being is that doing it the "easy" way first will force you to learn about how your code works, how the rendering engine works, what kind of data the rendering engine needs, etc. Multithreading knowledge is defintely required in complex game development these days, but knowing how to do it well requires indepth knowledge of how game systems interact with each other.
There's not a whole lot of benefit to your core game logic running faster than the player can respond. About the only time it's really useful is for physics simulations, where running at a fast, fixed time step can make the sim behave more consistently.
Apart from that, just update your game loop once per frame, and pass in a variable time delta instead of relying on the fixed one. The benefit you'll get from doing multithreading is minimal compared to the cost, especially if this is your first game.
Double buffering your render-able objects is an approach you could explore. Meaning, the rendering component is using 1 buffer which is updated when all game actions have updated the relevant object in the 2nd buffer.
But personally I don't like it, I'd (and have, frequently) employ Mark's approach.