Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Guide to Game Development/Theory/Game logic/Setting up ticks and frames

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

A piece of C++ set-up code for a game that separated the ticks from the frames, where ticks are constant and frames go as fast as the system allows it. BUG: Error with "ns.time_since_epoch" need to replace with a function that gets the system's nanosecond date since the start of the epoch. #include <iostream> #include <chrono> #include <thread> #include "cstdlib" #include <sys/timeb.h> #include <time.h> using namespace std; timeb tb; bool running = false; int tickCount = 0; //Stating that the following functions exist below void run(); void tick(); void render(); int main(){ run(); system("PAUSE"); return 0; } void run(){ auto ns = chrono::high_resolution_clock::now(); //Get time in nano seconds long lastTime = std::chrono::duration_cast<std::chrono::nanoseconds> (std::chrono::system_clock::now().time_since_epoch()).count(); double nsPerTick = 1000000000/60.0f; int ticks = 0; int frames = 0; long lastTimer = tb.millitm; //Get time in current milliseconds double delta = 0; while(running) { ns = chrono::high_resolution_clock::now(); //Get time in nano seconds long now = std::chrono::duration_cast<std::chrono::nanoseconds> (std::chrono::system_clock::now().time_since_epoch()).count(); delta += (now-lastTime)/nsPerTick; lastTime = now; while (delta >= 1){ ticks++; tick(); delta--; } try{ std::this_thread::sleep_for(std::chrono::milliseconds(2)); //Sleep for 2ms }catch(int e){ cout << "Error #" << e << endl; } frames++; render(); if (tb.millitm/*Get time in current milliseconds*/ - lastTimer >= 1000){ lastTimer += 1000; cout << "Ticks: " << ticks << " Frames: " << frames << endl; //Output of frames per second ticks = 0; frames = 0; } } } void tick(){ tickCount++; //Do game updates here } void render(){ //Handle graphics here } Another way that this can be done is: #include <iostream> #include <chrono> using namespace std; struct vec2 { float x, y; } ballPos, ballVel{0.707f, 0.707f}; constexpr float GAME_LOGIC_SPEED = 1.f; //Frame time step constexpr float SLICE = 1.f; //Size of a slice void FixedUpdate() { //Time relevant stuff //Operator overloading (+, *, +=) could be added to vec2 to make this better ballPos.x += ballVel.x * GAME_LOGIC_SPEED; ballPos.y += ballVel.y * GAME_LOGIC_SPEED; } void Update() { //Graphics and non-time relevant stuff //Ball.Render(); } void HandleWindowEvents() { } void HandleInput() { } void main() { float currentSlice = 0.f; int lastFrameTime = 0; auto lastTimePoint = chrono::high_resolution_clock::now(); auto deltaTime = chrono::high_resolution_clock::now() - lastTimePoint; float ftSeconds, fps; while (true) { //Game Loop HandleWindowEvents(); HandleInput(); currentSlice += lastFrameTime; for (;currentSlice >= SLICE; currentSlice -= SLICE) FixedUpdate(); Update(); deltaTime = chrono::high_resolution_clock::now() - lastTimePoint; lastTimePoint = chrono::high_resolution_clock::now(); int ft = chrono::duration_cast<chrono::duration<float, milli>>(deltaTime).count(); lastFrameTime = ft; ftSeconds = ft / 1000.f; fps = 1.f / ftSeconds; cout << "\rFT: " << ft << "\t\t\tFPS: " << fps << "\t\t\t"; } system("pause"); } /* *-----Frame---*--Frame-*--------Frame--------* |.......|.......|.......|.......|.......|.......|.......|....... | | | | | | | | \ Slice \ Slice \ Slice \ Slice \ Slice \ Slice \ Slice \ Slice */ References Dive into C++11 [2] 75%