Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (476)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (530)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Problems with gameloop and threading  (Read 1142 times)
0 Members and 1 Guest are viewing this topic.
Offline Zeta

Junior Member


Medals: 1
Exp: 1 year



« Posted 2013-09-17 21:19:00 »

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.

A clever person solves a problem. A wise person avoids it. -Albert Einstein
https://trello.com/zaniarm/recommend
Offline opiop65

JGO Kernel


Medals: 153
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #1 - Posted 2013-09-17 23:08:31 »

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!

Offline lcass
« Reply #2 - Posted 2013-09-17 23:28:29 »

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.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
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++;

      }

   }
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Troncoso

JGO Coder


Medals: 20



« Reply #3 - Posted 2013-09-17 23:40:54 »

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

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
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.
Offline opiop65

JGO Kernel


Medals: 153
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #4 - Posted 2013-09-17 23:45:31 »

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.

Offline Troncoso

JGO Coder


Medals: 20



« Reply #5 - Posted 2013-09-18 00:30:48 »

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.
Offline opiop65

JGO Kernel


Medals: 153
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #6 - Posted 2013-09-18 00:52:15 »

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.

Offline lcass
« Reply #7 - Posted 2013-09-18 19:14:37 »

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.
Offline Zeta

Junior Member


Medals: 1
Exp: 1 year



« Reply #8 - Posted 2013-09-18 21:19:18 »

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

GUI class(makes only the interface)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
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")
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
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
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
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
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
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   Cheesy)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
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 Cheesy 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 :/

A clever person solves a problem. A wise person avoids it. -Albert Einstein
https://trello.com/zaniarm/recommend
Offline opiop65

JGO Kernel


Medals: 153
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #9 - Posted 2013-09-19 00:15:10 »

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

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Zeta

Junior Member


Medals: 1
Exp: 1 year



« Reply #10 - Posted 2013-09-19 15:37:40 »

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

A clever person solves a problem. A wise person avoids it. -Albert Einstein
https://trello.com/zaniarm/recommend
Offline SHC
« Reply #11 - Posted 2013-09-19 15:48:24 »

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
EDT (Event Dispatch Thread)
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
Runnable
interface. Most keep it in the class that extends a frame since they will access the methods of the frame.

Offline Troncoso

JGO Coder


Medals: 20



« Reply #12 - Posted 2013-09-19 16:11:53 »

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

You don't need to make a thread.
Offline Danny02
« Reply #13 - Posted 2013-09-19 17:12:56 »

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:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
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();
Offline lcass
« Reply #14 - Posted 2013-09-19 23:32:53 »

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++;
Offline pploco1996

Junior Member


Medals: 1
Exp: 1 year



« Reply #15 - Posted 2013-09-20 05:01:07 »

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.
Offline lcass
« Reply #16 - Posted 2013-09-21 17:01:46 »

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:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
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 never restricted the fps in that example though i restricted the tick rate...
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (11 views)
2014-07-24 01:59:36

Riven (10 views)
2014-07-23 21:16:32

Riven (11 views)
2014-07-23 21:07:15

Riven (12 views)
2014-07-23 20:56:16

ctomni231 (42 views)
2014-07-18 06:55:21

Zero Volt (38 views)
2014-07-17 23:47:54

danieldean (32 views)
2014-07-17 23:41:23

MustardPeter (34 views)
2014-07-16 23:30:00

Cero (50 views)
2014-07-16 00:42:17

Riven (50 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!