Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (600)
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  
  This is killing my computer D: (simple task)  (Read 3175 times)
0 Members and 1 Guest are viewing this topic.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Posted 2010-06-10 13:16:33 »

I made this as a serverside. It is still very very simple - the only things it has is a 5 second game loop, and I played around with some packets Tongue
Sadly the game-loop is killing my computer CPU wise.

This is my classes:

Main 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  
package Mads;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/**
 * @author Mads
 */

public class Main {
    public static void main(String[] args) throws IOException {

        //Making and running the socket
        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket(4445);
        } catch (SocketException e) {}

        //Starting the game cycle
        //Thread iC = new Thread(new iniCycle());
        //iC.start();

        //Rechieving a packet
        byte[] buf = new byte[256];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);
        socket.receive(packet);

        //Figure what to respond
        String message = "COOL_MATE";
        buf = message.getBytes();

        //Send the response
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        packet = new DatagramPacket(buf, buf.length, address, port);
        socket.send(packet);
    }
}



iniCycle 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  
package Mads;

/**
 *
 * @author Mads
 */


public class iniCycle implements Runnable {

    public long timer = System.currentTimeMillis();
    public boolean isTrue = true;

    public void run() {
        while (isTrue = true) {
            if (System.currentTimeMillis() - timer >= 5000) {

                //Handling the timer
                //System.out.println("Valid");
                timer = System.currentTimeMillis();

                //Executing the actual game loop
                Thread gC = new Thread(new gameCycle());
                gC.start();
            }
            else {

            }
        }
    }
}


gameLoop class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
package Mads;

/**
 * @author Mads
 */

public class gameCycle implements Runnable {

    public gameCycle() {

    }
    public void run() {

        //System.out.println("gameCycle initialized");

         
    }
}



Any ideas, why this is soooo heavy?

Offline TheMatrix154

Junior Devvie


Medals: 2



« Reply #1 - Posted 2010-06-10 13:42:39 »

iniCycle.class
1  
while (isTrue = true)

should be
1  
while (isTrue == true)

or just
1  
while (isTrue)


Offline lhkbob

JGO Knight


Medals: 32



« Reply #2 - Posted 2010-06-10 13:55:27 »

1  
2  
if (System.currentTimeMillis() - timer >= 5000) {
...

does a busy wait so for those entire 5 seconds that you're waiting, the JVM is running a loop that does nothing, which means it can do the loop really, really fast and thus uses up the CPU.  You need to use the Thread.sleep(5000) to sleep for about 5 seconds.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline teletubo
« League of Dukes »

JGO Ninja


Medals: 48
Projects: 4
Exp: 8 years



« Reply #3 - Posted 2010-06-10 14:15:58 »

1  
2  
if (System.currentTimeMillis() - timer >= 5000) {
...

does a busy wait so for those entire 5 seconds that you're waiting, the JVM is running a loop that does nothing, which means it can do the loop really, really fast and thus uses up the CPU.  You need to use the Thread.sleep(5000) to sleep for about 5 seconds.

or you could also add a
1  
Thread.yield();


in you else statement .

Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #4 - Posted 2010-06-10 14:35:43 »

It is because I want the game loop to be precise no matter how long it takes to execute. If I use Thread.sleep() there will eventually be some millis delay, and that would be growing over time

Offline williamwoles

Senior Newbie





« Reply #5 - Posted 2010-06-10 14:46:59 »

Make the Thread sleep for 25msec for example or read some tutorials about how wait() and notify() works in Java Threads.. Before starting make something it's better to read some documentation before..

EDIT: The code you have is has infinite cycle... probably your PC has 2+ core CPU, this is what saving you from complete freeze of machine...

EDIT2: This question should go to "Newless Clubies" section Wink

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #6 - Posted 2010-06-10 16:16:57 »

It is because I want the game loop to be precise no matter how long it takes to execute. If I use Thread.sleep() there will eventually be some millis delay, and that would be growing over time
You'll never get something that's precise. A lost ms or two is no big deal and if you write your loop intelligently it will automatically be picked up in the next timestep. You're essentially doing a fixed timestep right now, but you're doing it wrong.

Here is a fixed game loop test I made. It just draws a ball bouncing around, using a fixed timestep and a target FPS. If the FPS would exceed the target, it yields the thread. This keeps the game from being a processor hog (unless you need it).

Note that you very rarely need a 60 GAME_HERTZ, I just kept it there for the test. Oftentimes you can get away with a game hertz of 20, and it looks fine as long as the FPS is high.

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  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GameLoopTest extends JFrame implements ActionListener
{
   private GamePanel gamePanel = new GamePanel();
   private JButton startButton = new JButton("Start");
   private JButton quitButton = new JButton("Quit");
   private boolean running = false;
   private int fps = 60;
   private int frameCount = 0;
   
   public GameLoopTest()
   {
      super("Fixed Timestep Game Loop Test");
      Container cp = getContentPane();
      cp.setLayout(new BorderLayout());
      JPanel p = new JPanel();
      p.setLayout(new GridLayout(1,2));
      p.add(startButton);
      p.add(quitButton);
      cp.add(gamePanel, BorderLayout.CENTER);
      cp.add(p, BorderLayout.SOUTH);
      setSize(500, 500);
     
      startButton.addActionListener(this);
      quitButton.addActionListener(this);
   }
   
   public static void main(String[] args)
   {
      GameLoopTest glt = new GameLoopTest();
      glt.setVisible(true);
   }
   
   public void actionPerformed(ActionEvent e)
   {
      Object s = e.getSource();
      if (s == startButton)
      {
         running = !running;
         if (running)
         {
            startButton.setText("Stop");
            runGameLoop();
         }
         else
         {
            startButton.setText("Start");
         }
      }
      else if (s == quitButton)
      {
         System.exit(0);
      }
   }
   
   //Starts a new thread and runs the game loop in it.
   public void runGameLoop()
   {
      Thread loop = new Thread()
      {
         public void run()
         {
            gameLoop();
         }
      };
      loop.start();
   }
   
   //Only run this in another Thread!
   private void gameLoop()
   {
      //This value would probably be stored elsewhere.
      final double GAME_HERTZ = 60.0;
      //Calculate how many NS each frame should take for our target game hertz.
      final double TIME_BETWEEN_UPDATES = 1000000000 / GAME_HERTZ;
      //At the very most we will update the game this many times before a new render.
      final int MAX_UPDATES_BEFORE_RENDER = 5;
      //We will need the last update time.
      double lastUpdateTime = System.nanoTime();
      //Store the last time we rendered.
      double lastRenderTime = System.nanoTime();
     
      //If we are able to get as high as this FPS, don't render again.
      final double TARGET_FPS = 60;
      final double TARGET_TIME_BETWEEN_RENDERS = 1000000000 / TARGET_FPS;
     
      //Simple way of finding FPS.
      int lastSecondTime = (int) (lastUpdateTime / 1000000000);
     
      while (running)
      {
         double now = System.nanoTime();
         int updateCount = 0;
         
         //Do as many game updates as we need to, potentially playing catchup.
         while( now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER )
         {
            updateGame();
            lastUpdateTime += TIME_BETWEEN_UPDATES;
            updateCount++;
         }
         
         //If for some reason an update takes forever, we don't want to do an insane number of catchups.
         //If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.
         if (lastUpdateTime - now > TIME_BETWEEN_UPDATES)
         {
            lastUpdateTime = now - TIME_BETWEEN_UPDATES;
         }
         
         //Render. To do so, we need to calculate interpolation for a smooth render.
         float interpolation = Math.min(1.0f, (float) ((now - lastUpdateTime) / TIME_BETWEEN_UPDATES) );
         drawGame(interpolation);
         lastRenderTime = now;
         
         //Update the frames we got.
         int thisSecond = (int) (lastUpdateTime / 1000000000);
         if (thisSecond > lastSecondTime)
         {
            System.out.println("NEW SECOND " + thisSecond + " " + frameCount);
            fps = frameCount;
            frameCount = 0;
            lastSecondTime = thisSecond;
         }

         //Yield until it has been at least the target time between renders. This saves the CPU from hogging.
         while ( now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES)
         {
            Thread.yield();
            now = System.nanoTime();
         }
      }
   }
   
   private void updateGame()
   {
      gamePanel.update();
   }
   
   private void drawGame(float interpolation)
   {
      gamePanel.setInterpolation(interpolation);
      gamePanel.repaint();
   }
   
   private class GamePanel extends JPanel
   {
      float interpolation;
      float ballX, ballY, lastBallX, lastBallY;
      int ballWidth, ballHeight;
      float ballXVel, ballYVel;
     
      int lastDrawX, lastDrawY;
     
      public GamePanel()
      {
         ballX = lastBallX = 100;
         ballY = lastBallY = 100;
         ballWidth = 25;
         ballHeight = 25;
         ballXVel = (float) Math.random() * 10 - 5;
         ballYVel = (float) Math.random() * 10 - 5;
      }
     
      public void setInterpolation(float interp)
      {
         interpolation = interp;
      }
     
      public void update()
      {
         lastBallX = ballX;
         lastBallY = ballY;
         
         ballX += ballXVel;
         ballY += ballYVel;
         
         if (ballX + ballWidth/2 >= getWidth())
         {
            ballXVel *= -1;
            ballX = getWidth() - ballWidth/2;
         }
         else if (ballX - ballWidth/2 <= 0)
         {
            ballXVel *= -1;
            ballX = ballWidth/2;
         }
         
         if (ballY + ballHeight/2 >= getHeight())
         {
            ballYVel *= -1;
            ballY = getHeight() - ballHeight/2;
         }
         else if (ballY - ballHeight/2 <= 0)
         {
            ballYVel *= -1;
            ballY = ballHeight/2;
         }
      }
     
      public void paintComponent(Graphics g)
      {
         //BS way of clearing out the old rectangle to save CPU.
         g.setColor(getBackground());
         g.fillRect(lastDrawX-1, lastDrawY-1, ballWidth+2, ballHeight+2);
         g.fillRect(5, 0, 75, 30);
         
         g.setColor(Color.RED);
         int drawX = (int) ((ballX - lastBallX) * interpolation + lastBallX - ballWidth/2);
         int drawY = (int) ((ballY - lastBallY) * interpolation + lastBallY - ballHeight/2);
         g.fillOval(drawX, drawY, ballWidth, ballHeight);
         
         lastDrawX = drawX;
         lastDrawY = drawY;
         
         g.setColor(Color.BLACK);
         g.drawString("FPS: " + fps, 5, 10);
         
         frameCount++;
      }
   }
}

See my work:
OTC Software
Offline JL235

JGO Coder


Medals: 10



« Reply #7 - Posted 2010-06-11 02:52:42 »

or you could also add a
1  
Thread.yield();


in you else statement .
I've fallen into this trap myself, so I don't recommend this. Somewhere online Sun does recommend users not to use yield as an alternative to sleep. I used yield instead of sleep for some of my sound code and on XP and Linux I continued to get terrible performance (although it ran perfectly on Vista).

Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #8 - Posted 2010-06-11 09:04:49 »

EDIT: The code you have is has infinite cycle... probably your PC has 2+ core CPU, this is what saving you from complete freeze of machine...

Last time I checked, even single core CPUs could do context-switching Wink

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline williamwoles

Senior Newbie





« Reply #9 - Posted 2010-06-11 11:38:31 »

Last time I checked, even single core CPUs could do context-switching Wink

True, have tried now putting 5 infinite cycles running and still getting machine response, though it's kinda slow, but anyway, better then restart Cheesy. But I know for sure, infinite cycle with forks(C) would kill machine in 10 seconds Tongue (not applies to the case, but anyways Tongue)

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.

rwatson462 (29 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (40 views)
2014-12-09 22:41:13

BurntPizza (75 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (50 views)
2014-12-03 16:27:13

CopyableCougar4 (45 views)
2014-11-29 21:32:03

toopeicgaming1999 (113 views)
2014-11-26 15:22:04

toopeicgaming1999 (100 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!