Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (492)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (556)
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  
  Game is freezing and not working properly  (Read 2113 times)
0 Members and 1 Guest are viewing this topic.
Offline Jsn

Junior Newbie





« Posted 2008-09-05 17:23:50 »

Hi!

I've made a first little java applet game (not my first game ever though). It's an simple "Monty on the run"-styled plattform game. The player is supposed to collect discs and avoiding angry monsters. The game has no level scrolling and every level is one screen only.

Logically the game is working just fine, but the game has got some irritating performance issues. The game is running a bit jerky and on computers with Windows Vista the speed is not constant (sometimes it's running faster and sometimes slower).  Sad

The game is also freezing for short periods now and then.  Sad The game started freezing for even longer periods when I included sound in the game, which I feel is a bit strange since all sound is handled by java.applet.AudioClip. I do not instantiate new audioclips every time they are played. All audioclips used in the game are loaded when the game is starting and stored in a special object.

I am using double buffering and active rendering for my animation. My main loop is looking like this:

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  
long lastSleep = System.nanoTime();
      long sleepTime;
     
      while (true) {
         
         if (state == State.RUNNING) {
            sven.move(); // Moving the player sprite
           checkControls(); // Check keyboard controls
           collisions(); // Checking if the player is colliding the enemies
 
            levelElementCollision(); // Checking if the player is colliding with level elements such as walls.
        }      
     
         if (state == State.RUNNING || state == State.GAMEOVER) {  
            animateDiscs(); // Animate all the discs the player should collect
           handleEnemies(); // Performing enemy "AI" and moving enemies
        }
         
         paintScreen(); // Painting active to the screen
       
         sleepTime = 16000000 - (System.nanoTime() - lastSleep);      
         lastSleep = System.nanoTime();
         
         if (sleepTime > 0) {      
            try {
               Thread.sleep(sleepTime/1000000L);
            } catch (InterruptedException ex) {}
         }
      }


I really do not know what I am doing wrong  Huh. I'm not instantiating any objects at all during a level and is doing a "System.gc()"-call after each level. I've checked the applet with Eclipses profiler and saw that my game was instantiating a LOT of char[] and int[]. I am not instantiating a single one however, so this must be some sort of system operation? Is this normal, or is it a result of me doing something terribly wrong?  Huh

I am having around 8-10 sprites on screen at once. All level graphics (walls, floor etc.) are drawn to the background at the start of a new level.

I know that some things in the game are not perfectly optimized, for example the collision detection and the paint method (including a lot of list iterations). However, even if I bybass the collision, or most of the paint-method, the game is still running jerky and freezy at the same level as before.  Undecided

I really want my game to work, but do not know what to do. What could cause these problems? You are my only hope!
Offline skyuzo

Senior Newbie





« Reply #1 - Posted 2008-09-06 06:29:25 »

Not sure, but maybe it's the Thread.sleep() and division problems...
Offline Jsn

Junior Newbie





« Reply #2 - Posted 2008-09-06 07:53:07 »

Yes, maybe... But how can I get rid off rounding errors? Or is there a way I can handle this without division?

Using System.NanoTime() is my only choice since System.getTimeMillis() is VERY inaccurate and makes the game run 10 times worse.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline fletchergames

Senior Member





« Reply #3 - Posted 2008-09-06 16:11:45 »

It sounds like you're oversleeping some of the time.  Try changing Thread.sleep to Thread.yield.  Then add code something like the following:

1  
2  
3  
4  
5  
6  
if(currentPhaseTime - lastPhaseTime >= timePerPhase) {
   //do the moving, animating, etc.
  ....

   lastPhaseTime = currentPhaseTime;
}


I expect that the following will happen:

1. Your game won't be anywhere near as jerky.
2. Your game will consume all available CPU cycles.

If this is what happens, you're oversleeping.

Here is an excerpt from my own main loop code:

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  
//verify that the loop will continue
  shouldContinueLoop = true;
   
   //This variable is used to only skip yielding a certain number of times in a row.
  byte numDelays = 0;
   
   //This variable stores how much time the loop overslept by in the last cycle.
  //Negative values probably won't occur because Thread.sleep shouldn't undersleep.
  long overSleepTime = 0L;
   
   //This variable is used for computing the length of an update phase.
  long lastUpdatePhase = Time.currentTimeMillis();

   while(shouldContinueLoop) {
      //if the application isn't visible, sleep for half a second
     if(!isApplicationActive()) {
         try {
            Thread.sleep(500);
         } catch(InterruptedException exception) {}
           
         continue;
      } //end if the frame isn't visible
     
      //figure out the start of the current phase
     long currentCycle = Time.currentTimeMillis();
      long updatePhaseLength = currentCycle - lastUpdatePhase;
      if(updatePhaseLength > period)
         updatePhaseLength = period;
     
      //update the current model
     doUpdatePhase(updatePhaseLength);
      lastUpdatePhase = Time.currentTimeMillis();
   
      //render the game
     render();
   
      //figure out how long the cycle took
     long timeAfterCycle = Time.currentTimeMillis();
      long cycleLength = timeAfterCycle - currentCycle;
      long sleepTime = period - cycleLength - overSleepTime;
     
      //if some time is left in this cycle
     if(sleepTime > 0) {
         //sleep
        try {
            Thread.sleep(sleepTime);
         } catch(InterruptedException exception) {}
           
         overSleepTime = Time.currentTimeMillis() - timeAfterCycle - sleepTime;
      } //end if some time is left in this cycle
     //else no time is left in this cycle
     else {
         overSleepTime = 0L;

         //don't sleep, but yield if absolutely necessary
        numDelays++;
         if(numDelays >= maximumDelaysPerYield) {
            //yield to let other threads execute
           Thread.yield();
            numDelays = 0;
         } //end if there have been too many delays
     } //end else no time is left in this cycle
  } //end while forever


This code is practically copied out of Killer Game Programming in Java.  Mine is a little different, and there's some stuff I left out because it isn't relevant.

You need to watch for sleeping too long.  I think it's clear how this is done from the code.  That should fix your problem, but you should change it so that rendering and updating are independent of eachother.

My doUpdatePhase method does all the animation and so forth.  This method uses something like the if statement I told you to add earlier.  The only difference is that I accumulate the elapsed time rather than comparing the current time to the old time.  I do this way in case the game is minimized and then returned to.  This prevents having an extra phase happen right away.

My render method isn't limited in that way.  The screen is rendered as often as possible except for the sleep time that allows other Threads and Processes to run.

The idea is to do the following:

1) Update animations, movement, etc. a set number of times per second
2) Sleep a fair amount of the time so that other Threads and Processes can run
3) Render as often as possible without screwing up 1 or 2

Also, I always use milliseconds instead of nanoseconds because the nanosecond timer isn't particularly reliable on computers with power saving settings (which is practically all of them) as well as some older dual core AMD CPUS.

The millisecond timer has bad granularity on Windows, but it seems like it's good enough.
Offline Jsn

Junior Newbie





« Reply #4 - Posted 2008-09-07 14:04:42 »

Thanks for your help fletchergames!  Grin

I implemented your ideas in my code and the game is now running much more constant (no speed roller coaster like before). The performance is not perfect however, so I guess I have so optimize some parts of the game. However, thanks for your help!

Offline Jesja

Junior Member


Projects: 1



« Reply #5 - Posted 2008-09-14 19:57:37 »

fletchergames, wouldnt it be a good idea to encapsulate the timing things in some sort of timer class. As it is now a lot of local variables are floating around and its not very obious what they are doing, espacially if you what to do more things in the mail loop. And a timer class would be easier to reuse too.

Try the Callisto Carnival - Stunning space thruster
http://jenslidestrom.webs.com
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.

Nickropheliac (15 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (33 views)
2014-08-22 19:31:30

atombrot (41 views)
2014-08-19 09:29:53

Tekkerue (40 views)
2014-08-16 06:45:27

Tekkerue (35 views)
2014-08-16 06:22:17

Tekkerue (25 views)
2014-08-16 06:20:21

Tekkerue (37 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (49 views)
2014-08-09 21:09:32
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!