Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
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  
  Bouncing Balls  (Read 822 times)
0 Members and 1 Guest are viewing this topic.
Offline grom358

Senior Newbie





« Posted 2005-06-23 17:18:11 »

I am writing a simple bouncing balls animation, where the balls bounce off the walls and the other balls. I am following the worm example from "Killer Game Programming in Java". Here is my main game loop:

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  
   public void run() {
      long beforeTime, afterTime, timeDiff, sleepTime;
      long overSleepTime = 0L;
      int noDelays = 0;
      long excess = 0L;
     
      Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
      isRunning = true;
     
      gameStartTime = System.nanoTime();
      prevStatsTime = gameStartTime;
      beforeTime = gameStartTime;
     
      while (isRunning) {                  
         nextFrame(period/1000000L);
         updateDisplay();
         
         afterTime = System.nanoTime();
         timeDiff = afterTime - beforeTime;
         sleepTime = (period - timeDiff) - overSleepTime;
         
         if (sleepTime > 0) {
            try {
               Thread.sleep(sleepTime / 1000000L /* nanosecs -> ms */);
            } catch (InterruptedException ex) {
               // do nothing
           }
            overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
         } else { // sleepTime <= 0; the frame took longer than the period
           excess -= sleepTime;  // store excess time value
           overSleepTime = 0L;
           
            if (++noDelays >= NO_DELAYS_PER_YIELD) {
               Thread.yield();   // give another thread a chance to run
              noDelays = 0;
            }            
         }
         
         beforeTime = System.nanoTime();
         
         /*
          * If frame animation is taking too long, update the game state
          * without rendering it, to get the updates/sec nearer to the
          * required FPS.
          */

         int skips = 0;
         while ((excess > period) && (skips < MAX_FRAME_SKIPS)) {
            excess -= period;
            nextFrame(period/1000000L); // update state but don't render
           skips++;
         }
         framesSkipped += skips;
         
         updateStats();
      }
   }


And here is my the code for updating the animation state:
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  
   public void nextFrame(double t) { // t is in microseconds
     if (isPaused) return;
     
      // t is the time of the earliest collision.
     // if t == RATE then there are either no collisions
     // or collision occur at time RATE      
     // Since only the earliest collision needs to be found,
     // the collision test are performed for the current
     // time of the earliest collision (t).
     
      // Test for wall collisions
     for (int i = 0; i < balls.length; i++) {
         t = Math.min(t, balls[i].testWallCollision(t));  
      }
     
      // Test for ball collisions
     // collision are added to the head of this list      
     List<Collision> collisions = new LinkedList<Collision>();
      Ball a, b;
      for (int i = 0; i < balls.length; i++) {
         a = balls[i];
         for (int j = i+1; j < balls.length; j++) {
            b = balls[j];
            t = Math.min(t, a.testBallCollision(b, t, collisions));  
         }
      }
     
      // Move the balls
     for (int i = 0; i < balls.length; i++) {        
         balls[i].move(t);
      }
     
      // Handle the collisions that occured
     // NOTE: It is possible that two collision occurred at the
     // same time. Therefore the collision list is iterated
     // until we get to a collision that occured after the
     // time of the first collision
     for (Collision c : collisions) {
         if (c.t == t) {
            c.handle();
         } else {
            break;
         }
      }
   }


My problem is that I want the frame to update according to how much time has passed since the last frame. At the moment I just assign t to the period (converting to ms) . Should I pass in timeDiff from the last loop instead (for the first nextFrame call that is rendered)?

Also multiple collisions may have occured since the last frame. At the moment I update the state to the time of first collision (or t if no collisions occured). I should continue to handle collision until no collisions are left for the frame. However will this not likely mean the nextFrame() method takes too much CPU time before we paint the next frame? How should I be handling this?
Offline grom358

Senior Newbie





« Reply #1 - Posted 2005-06-23 17:51:17 »

Below is a modified nextFrame() that will repeat if the frame period has not expired. Is this the right way of doing this? Should I be checking CPU time that has elapsed?

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  
   /**
    * Creates the next frame
    */

   public void nextFrame(double t) {
      if (isPaused) return;
     
      long startTime = System.nanoTime();
     
      double rt = t; // remaining frame time
     boolean isCollision = false;
     
      do {
         isCollision = false;
         
         // t is the time of the earliest collision.
        // if t == rt then there are either no collisions
        // or collision occured at time rt      
        // Since only the earliest collision needs to be found,
        // the collision test are performed for the current
        // time of the earliest collision (t).
       
         // Test for wall collisions
        for (int i = 0; i < balls.length; i++) {
            t = Math.min(t, balls[i].testWallCollision(t));  
         }
         
         // Test for ball collisions
        // collision are added to the head of this list      
        List<Collision> collisions = new LinkedList<Collision>();
         Ball a, b;
         for (int i = 0; i < balls.length; i++) {
            a = balls[i];
            for (int j = i+1; j < balls.length; j++) {
               b = balls[j];
               t = Math.min(t, a.testBallCollision(b, t, collisions));  
            }
         }
         
         // Move the balls
        for (int i = 0; i < balls.length; i++) {        
            balls[i].move(t);
         }
         
         // Handle the collisions that occured
        // NOTE: It is possible that two collision occurred at the
        // same time. Therefore the collision list is iterated
        // until we get to a collision that occured after the
        // time of the first collision
        for (Collision c : collisions) {
            if (c.t == t) {
               c.handle();
               isCollision = true;
            } else {
               break;
            }
         }
         
         // calculate frame time renaming
        t = rt - t;
         rt = t;
         
      // continue updating frame if there was a collision and the frame period has not expired
     } while(isCollision && rt > 0 && System.nanoTime() - startTime < period);
   }
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.

Riven (20 views)
2014-07-29 18:09:19

Riven (13 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (31 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

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

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

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

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

ctomni231 (60 views)
2014-07-18 06:55:21
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!