Advertisement

i need learn more about the Game Loop

Started by January 04, 2018 09:05 PM
22 comments, last by JoeJ 6 years, 10 months ago

i only know the Game Loop standard:
- input;

- collision test;

- draw;

- test if ends or restart.

 but i need understand more about these: like how can i give the enemy move? and more

This question is pretty vague. I'll just describe how I generally do the main game loop, but this is just one of many ways that it can work.

I have an object Game... this is the object that contains the main game loop. It also contains a member called ActiveGameScene which implements the interface IGameScene. The IGameScene has three primary responsibilites... Respond to a request, Update the GameState or Render the gamestate. The IGameScene contains a list of IGameSystems. Game Systems are very tightly focused "functionality packets" so, one system may be my input system and another may be my rendering system and there may be many more... lighting systems, ai systems etc. Each System has methods ProcessRequest, Update, and Render.

 

So, the Game contains a Scene which contains a set of Systems and the main game loop is

//Pseudo Code

//In Game

while(running)

{

    while(requestsPending) 

            Scene.ProcessRequest(request);

    Scene.Update();

   Scene.Render();

}

 

//In GameScene

ProcessRequest(){

       Foreach(ISystem sys in Systems)

              sys.ProcessRequest(request);

}

Update(){foreach(ISystem sys in Systems) sys.Update();}

Render(){foreach(ISystem sys in Systems) sys.Render();}

 

Then, it's in the specific systems where the interesting things happen.

Maybe there is an AI System...

//In AI System

ProcessRequest(request){   }

Update(){

    Foreach(AIUnit){

            if (AIUnit.CurrentAction==null)

            {

                  AIUnit.CurrentAction = AIUnit.ChooseNextAction();

            }

            switch(AIUnit.CurrentAction)

           {

                  case Idle : Break;

                  case Attack: AIUnit.Attack(); break;

                  case Move: AIUnit.Position+= (AIUnit.Dest-AIUnit.Pos).Normalize();

           }

    }

}

 

 

Advertisement

This is not a Game Design question. Moving to a more appropriate forum.

-- Tom Sloper -- sloperama.com

7 hours ago, cambalinho said:

but i need understand more about these: like how can i give the enemy move? and more

Your Game loop is most of the game.

GameLoop.jpg.0a01b7fddea1dae1e7645d046d079383.jpg

You can say that everything that happens in a game after it started is done in the Game Loop. It's isn't a fact that everything is inside the loop but most of the game is.

Pseudocode:

Spoiler




//First you define variables
GameRunning   = true;
CombatRunning = false;
  
//We would declare functions to use

string GetPlayerInput(){
//Here would be code to get input as a string or something
  return //The key as a string
}

void Combat(){
    //Fight
}

void QuitGame(){
  //All the quit game function does is changes a variable
  GameRunning = false;
};


//About here we make the game loop

void UpdateGameLoop(){
  if (GetPlayerInput() == "Space_Key"){
    CombatRunning = true; // so pressing space turn on the combat.
  }
  //The combat loop will keep runing as needed
  while (CombatRunning == true){
    Combat();
  }
  
  if (GetPlayerInput() == "Q_Key"){
    QuitGame() = false; //Q sets GameRunning to false
  }
}

//Finally you run the game loop

while(GameRunning == true){ // when Q is pressed GameRunning = false so it no longer does this loop.
  UpdateGameLoop();
}

 

 

As can be seen my code structure and @Eightvo are different but neither is wrong, there is many ways to do game loops.

The main purpose of a game loop is to advance time, so mostly it is used for real time content.

Warning: Third version of how it can look ;)

I have my "Game Loop" completely decoupled from the "main process" so what this means is that in a multithreaded environment you can let your traditional game loop update run in parallel so that you update all the game states, physics, AI whatever in different threads while your rendering is processing on another thread. This means some kind of synchronization is needed (I use a global/local shared event system to populate synchronization requests) when rendering has completed processing the command buffers telling other systems to populate there graphics changes.

Input is another task because you have two different kinds of input system; either message based or polling. I use a message based system so there is no real "gather my input know" state but when OS sends a message it will be processed in a task parallel to any other system update.

This is a kind of more advanced version of the "simple" game loop :D

Just to take this back to a more fundamental level...

At a very basic level, for pretty much any task, computers work like this:

Collect input -> Process data based on input -> Display output

Lots of tasks require - or at least benefit from - repeating this process so that new input can be processed, and perhaps so the user can view the output and provide different input based on it.

Collect input -> Process data based on input -> Display output -> Repeat from start

Real-time systems like computer games and simulations work this way, with the additional constraint that they have some sort of hard or soft 'deadline'. In a computer game, the deadlines are typically 'soft' (in that the program doesn't break entirely if they are missed) but they are quite short, e.g. 33ms for a 30fps game or 16ms for a 60fps game. So the loop is executed with this deadline in mind. Note that on personal computers it's impractical to guarantee that each loop iteration takes a precise amount of time, so you normally aim for an arbitrary deadline but be prepared to measure the actual time taken and process with that in mind instead.

Collect input for next 16ms -> Process data based on input to cover the next 16ms -> Display output for the next 16ms-> Repeat from start (16ms can be swapped for any other small value, constant or variable)

Each of these iterations is generally called a 'frame' because you get one iteration for every one frame rendered to the screen (generally).

So, the way you would make an enemy move, in this basic system, is to recognise that a moved enemy is a type of data processing (i.e. the position data changes), and that the movement covers a certain time span (how far can an enemy move in 16ms? Or however long your frame took?) Each time though the loop, you move the enemy that tiny amount, then display the new position on the screen, and repeat.

Advertisement

my problem was that i was confused that doing enemy moving was taking several time. of course that time depends what i program.

thanks to all, now i understand: if i need several things on loop, the best is use multithread, if not, i do it normaly on loop.

thanks to all for all

59 minutes ago, cambalinho said:

now i understand: if i need several things on loop, the best is use multithread, if not, i do it normaly on loop.

Just to clarify, you do not need to use a multithreaded setup to make multiple enemies move over time. Or to loop over enemies and also loop over spinning traps. For a beginner, I would recommend focusing on singlethreaded setups, not multithreaded.

Multithreading when it comes to a game loop is more an optimization -- you can do the same stuff as in a singlethread setup, but potentially quicker.

Hello to all my stalkers.

for now i need to understand what can i do without consuming very CPU\GPU. but i know that moving the enemies is more or less like using the AI, that's why i was confused... what i will consuming on CPU

thanks for all

3 minutes ago, cambalinho said:

but i know that moving the enemies is more or less like using the AI,

It's vector math. So lets say you have a enemy at point (0,0) in the game. Your enemy needs to get to (8,8). It needs to get there in 8 frames.

So velocity is movement over time = Target(8,8)/Steps(8 frames) = (1,1) per step. So each loop you add (1,1) to the position of the enemy:

Step1 (0,0)+(1,1) = (1,1)

Step2 (1,1)+(1,1) =(2,2)

Step3 (2,2)+(1,1) = (3,3) etc.

So every loop you add (1,1) and then after the 8th step your enemy will be at (8,8), you will also see it move every frame.

If your new to the concept of vectors you can start here, it's a bit old but great post; it's very easy to understand:

 

This topic is closed to new replies.

Advertisement