Problems with gameloop and threading

The game im making is Pong. I have GUI, Player, Controller,Ball and Main Class.
The problem is where should i make my gameloop? also should Player and Ball have different gameloops?

What classes should be threads?(my guess is Player, Ball, and GUI classes).

please keep in mind that im a complete noob when it comes to gameloops and that this is my first game
where two or more things happen in the same time.

Thank you.

You should only have one thread, the main thread that runs the whole game. You shouldn’t multithread unless you need to do something thats resource intensive that will affect the performance of the main game. For example, terrain generation.

Your game loop should be in the main class and you only need one. It should call a super render and update methods which you will call via other classes. Those two methods will render and update every single part of the game. The game loop is really only used to limit the fps unless you’re getting into advanced game programming. On these forums we have a bunch of example game loops you can use, just search for them!

He is totally correct , only use one gameloop unless you are creating a lighting map or something like that. For a game loop I would recommend using the basic setup which is this. Im sure lots of people have seen this and this is one i use almost every time.

public void run() {
		long lasttime = System.nanoTime();
		double nspertick = 1000000000D / 60.0;//edit 60.0 to something else it means 60 ticks per second(if you arnet lagging like hell)

		long lasttimer = System.currentTimeMillis();
		double detla = 0;

		while (running) {
			long now = System.nanoTime();
			detla += (now - lasttime) / nspertick;
			lasttime = now;
			while (detla >= 1) {
				ticks++;
				tick();
				detla -= 1;
			}

			if (System.currentTimeMillis() - lasttimer >= 1000) {
				lasttimer += 1000;
				System.out.println(frames + "," + ticks);//not required but useful for debugging.
				frames = 0;
				ticks = 0;

			}
			render();//render function, if needed.
			frames++;

		}

	}

For a game like pong, you don’t really need anything more than

public void gameloop()
    // Initialize stuff before starting the loop

    running = true;
    while (running)
    {
        // Render graphics

        // Update game logic
    }
}

I think for someone’s first game, a game loop that tracks FPS and delta time or attempts any sort of frame smoothing is unnecessary. Especially when you aren’t really explaining what’s going on in your example.

I may consider throttling the FPS, as that can get sporadic. If you are using LWJGL, that’s as simple as Display.sync(60) at the end of the loop.

I don’t think thats a good idea. I really think people need to learn from the get go that not limiting the frame rate isn’t a good idea. Its hard is not a good reason not to learn something. Really, i doubt he’s dumb. He can figure it out, or ask for help, but it shouldn’t take him more than a few hours to understand what it actually means an how it works. I’m sorry, but I’ve always thought that was a terrible excuse for not learning something.

When did I ever say not to learn it? If he continues to make games, inevitibly, he’s going to run into issues where he needs to learn how to handle the frame rate. In this situation though, there’s no need for it. lcass pretty much said just to use the gameloop he provided, giving no description of how to use it, where to put his game code, what all the other code is for, and I think that’s unnecessary. And I didn’t even say it was hard. I think what’s stupid is doing something because someone told you to, or using some code just because it was handed out. He’ll realize he needs to enhance his game loop and he should go learn how instead of just accepting one that was given to him.

He was talking about having multiple game loops and separate threads for his game objects. I think he needs to learn how to even structure a game before getting into how to enhance it.

A fps limiter isn’t enhancing the game, its a necessity. Honestly, you can find documentation on that exact loop almost anywhere. Just because he doesn’t know how it works doesnt mean he shouldn’t learn it now. Besides, we didnt hand him that code because we are evil and want to confuse him, we gave it to him because really he needs to learn it sometime if he’s going to program games. Why not take the time and learn it now and get it out of the way.

Now, I agree with you if he just started learning programming then he really shouldn’t use the loop. But really, its simple math.

Yes you should take into common practice using a timer loop. Otherwise you end up with benchmark issues with ticks ie you could have a guy with a really powerful computer getting 40000 ticks per second but a guy with a slow computer getting only 5000 and the fps limiter fixs this by usually setting it to an arbitrary value such as 60.

So i’ve made the game this far. i’ve tried to follow the MVC.

GUI class(makes only the interface)

public class GUI extends JFrame{

	Controller controller;
	JPanel mainPanel;
	
	public GUI(){
		init();
	}
	
	public void init(){
		this.setTitle("Pong");	//Setting title
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);	//Close operation
		mainPanel = new JPanel();	//Creating main panel
		this.setFocusable(true);
		this.setContentPane(mainPanel);
		this.setSize(300,300);	//Assigning size
		this.setVisible(true);	//Frame is visible
		
		//Movement
		this.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e){
				controller.movePlayer(e.getKeyChar());
			}
			public void keyReleased(KeyEvent e){
				controller.movePlayer(e.getKeyChar());
			}
		});
	}
	
	public void registerController(Controller controller){	//Registers controller
		this.controller = controller;
	}
}

Controller class(this class is the “logic”)

public class Controller {
	
	GUI gui;
	Player player;
	Ball ball;
	
	public Controller(Player player, Ball ball, GUI gui){
		this.gui = gui;
		this.player = player;
		this.ball = ball;
		
	}
	
	public void movePlayer(char key){
		double x = player.getX();
		double velX;
		
		if(key == 'a'){
			player.setVelX(2);
			velX = player.getVelX();
			player.setX(x += velX);
		}else if(key == 'd'){
			player.setVelX(-2);
			velX = player.getVelX();
			player.setX(x += velX);
		}
		
		System.out.println(player.getX());
	}
	
	public void moveBall(double delta){
		double x = ball.getX();
		double y = ball.getY();
		double velX;
		double velY;
		
		ball.setVelX(1 + Math.random() * 3);
		ball.setVelY(1 + Math.random() * 3);
		velX = ball.getVelX();
		velY = ball.getVelY();
		
		x += velX * delta;
		y += velY * delta;
		
		System.out.println(ball.getX()+","+ ball.getY());
	}
}

Ball class

public class Ball{
	private double x;
	private double y;
	private double velX;
	private double velY;
	private boolean running = true;
	
	public Ball(){	//Constructor
		this.setVelX(0.05);
		this.setVelY(0.05);
		this.setX(0);
		this.setY(0);
	}
	
	//Setters and Getters
	public void setX(double x){
		this.x = x;
	}
	public void setY(double y){
		this.y = y;
	}
	public void setVelX(double velX){
		this.velX = velX;
	}
	public void setVelY(double velY){
		this.velY = velY;
	}
	public double getX(){
		return this.x;
	}
	public double getY(){
		return this.y;
	}

	public double getVelX(){
		return this.velX;
	}
	
	public double getVelY(){
		return this.velY;
	}
}

Player class

public class Player {
	private double x;
	private double y;
	private double velX;
	
	public Player(){
		this.setX(0);
		this.setY(1);
	}

	//Setters and getters
	public void setX(double x){
		this.x = x;
	}
	public void setY(double y){
		this.y = y;
	}
	public double getX(){
		return this.x;
	}
	public void setVelX(double velX){
		this.velX = velX;
	}
	
	public double getVelX(){
		return this.velX;
	}
}

and Finally Main class(the gameloop is just a test, not sure if it even works :D)

public static void main(String[] args){
		Player player = new Player();
		Ball ball = new Ball();
		GUI gui = new GUI();
		Controller controller = new Controller(player, ball, gui);
		boolean gameRunning = true;
		
		gui.registerController(controller);
		
		long lastTime = System.nanoTime();
		final double amountOfTicks = 60.0;
		double ns = 1000000000 / amountOfTicks;
		double delta = 0;
		int updates = 0;
		int frames = 0;
		long timer = System.currentTimeMillis();

		while (gameRunning){
		     long now = System.nanoTime();
		     delta += (now - lastTime) / ns;
		     lastTime = now;
		     
		     if(delta >= 1){
		    	 controller.movePlayer('a');
		    	 updates++;
		    	 delta--;
		     }
			 //render();
		     frames++;
		     
		     if(System.currentTimeMillis() - timer > 1000){
		    	 timer += 1000;
		    	 System.out.println(updates + " Ticks, FPS " + frames);
		    	 updates = 0;
		    	 frames = 0;
		     }
	    }
	}
}

So is my gameloop now in the right place :smiley: and is there anything else that i should consider/change. I know how the gameloop works, the problem is that i dont know how to use it in my code :confused:

It should be working. Check in your console, is it outputting 60 fps?

Yes it works now ;D. But still what class should be a thread is yet unclear to me(Main class)?

Am thinking that you had it working but you don’t understand the need of thread and where to make a thread. Some GUI systems like swing, swt, etc., hides the message loops from the user and they generate events. For what a message loop is, it’s the way of the underlying operating system to talk to the applications which are running. Swing creates a thread called the [icode]EDT (Event Dispatch Thread)[/icode] which is responsible to the generation of such events. So for memory intensive applications like games or high graphical applications, it is advised to write their code in a separate thread to avoid hogging of the EDT which can spoil your application since it manages the GUI system you are using. Now let’s get into your question Where should I put the code to create threads? The answer is you can create the thread in any class that implements the [icode]Runnable[/icode] interface. Most keep it in the class that extends a frame since they will access the methods of the frame.

You don’t need to make a thread.

Sry lcass, but I have to call bullshit on your last post.

You shouldn’t restricting the FPS so that your game logic runs on all systems with the same speed.
A valid reason to restrict FPS is to use vsync or to save energy (battery life on mobiles).

We had the discussion between fixed and dynamic logic time-steps already so I won’t discuss this topic.
In the case that you want to have some fixed time-steps do something as the following:


long lastTickTime = ...
long now = ...

if(lastTickTime + timeStep <= now)
{
   long ticks = (now - lastTickTime) / timeStep;
   for(int i=0; i<ticks; ++i) tick();
   lastTickTime += ticks * timeStep
}

render();

I would suggest you implement runnable class main implements runnable{
Then use the public void run() and put the loop in there , to use it where it has updates++; make a method outside of the loop called update() then call update under the updates++;

Well you could use LibGDX… It has its own built-in gameloop set at 60 fps by default and a delta value that you can use for efficient character movement.

Of course you may be doing it with runnable interface for learning purposes.

I never restricted the fps in that example though i restricted the tick rate…