Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (133)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 [2]
  ignore  |  Print  
  An efficient discrete step timing loop.  (Read 7843 times)
0 Members and 1 Guest are viewing this topic.
Offline Conflux

Senior Newbie




Java games rock!


« Reply #30 - Posted 2003-11-20 08:23:36 »

Quote
Well "unit" isn't an actual variable or anything.  It's just the distance you want to move in a given amount of time.  That could be 200 pixels per second or 1 inch per minute, etc.  So, in the example, clientTick is the actual framerate you get that may or may not fluctuate wildly from one second to the next, while gameTick is sort of the theoretical, constant framerate that you want to achieve a.k.a the "unit" value.  The interpolation mechanism, then, sort of works as an intermediary between the actual and theoretical framerate to keep the sprite moving at constant "unit" increments.  Thus, if you want ALL of your movement to appear to move faster, you would increase your "unit" value, which, in the case of the example given would be the value of GAMETICKS_PER_SECOND.  Anyway, that's my current understanding of it...


I still got a problem. I have a simple application where a spaceship can be moved along the x-axis of the screen.
the movement (pixels/second) is very slow with the abve example (but smooth). I can't figure out how to speed up the movement of them ship. If I set the increment to a higher value, the movement becomes inconsistent.

here's my implementation of the 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  
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  
public class GameWindow extends JFrame implements Runnable {

  private static final int GAMETICKS_PER_SECOND = 25;
  private static final int MILLISECONDS_PER_GAMETICK = 1000 / GAMETICKS_PER_SECOND;  
  private static final int screenwidth = 800;
  private static final int screenheight = 600;
  private ScenePanel pScene = new ScenePanel(this);  
  boolean running = true;
  boolean left = false;
  boolean right = false;
  boolean fire = false;
  boolean lock = false;
  int fps;
  int dir = 1; // TEST: enemy automove direction

  Ship player = new Ship("gfx/bat.gif", 480, 4, 8, 100,500);
  Ship enemy = new Ship("gfx/cow.gif", 40, 4, 8, 100, 500);

  public GameWindow() {
    this.setResizable(false);
    this.setTitle("Spacefight");
    this.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyPressed(KeyEvent e) {
        this_keyPressed(e);
      }
    });
    this.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(KeyEvent e) {
        this_keyReleased(e);
      }
    });
      this.setContentPane(pScene);
    setSize(screenwidth, screenheight);
      
      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      Dimension size = getSize();
      screenSize.height = screenSize.height/2;
      screenSize.width = screenSize.width/2;
      size.height = size.height/2;
      size.width = size.width/2;
      int y = screenSize.height - size.height;
      int x = screenSize.width - size.width;
      setLocation(x, y);

      
    setVisible(true);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
  }
  void this_keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_SPACE) {
      if(!lock ) {
        fire = true;
        player.shoot(player.posX+player.w/2);
      }
    }
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
      right = false;
      left = true;
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
      right = true;
      left = false;
    }
  }
  void this_keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
      left = false;
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
      right = false;
    }
  }

  public void run() {
      long previousTime = System.currentTimeMillis();
      long passedTime = 0;
      long frametime = previousTime;
      int framecount = 0;  
      while (running)      {  
              float interpolation = passedTime/(float)MILLISECONDS_PER_GAMETICK;
              clientTick(interpolation);  
              long time = System.currentTimeMillis();  
              passedTime += (time-previousTime);  
              previousTime = time;  
              while (passedTime>MILLISECONDS_PER_GAMETICK)  
              {  
                  framecount++;
                  if (time > (frametime + 999)) {
                    fps = framecount;
                    framecount = 0;
                    frametime = time;
                  }
                  gameTick();  
                  passedTime-=MILLISECONDS_PER_GAMETICK;  
              }  
      }
  }
      
  public void clientTick(float interpolation) {
      player.posX =(int) player.xIFloat.getValue(interpolation);
      enemy.posX =(int) enemy.xIFloat.getValue(interpolation);
      repaint();        
  }
  
  public void gameTick() {
      if (left) {
        if (player.posX > 8) {      
            player.xFloatPos = player.xIFloat.getValue(1);
            player.xFloatPos-=1;
            player.xIFloat.setValue(player.xFloatPos);
        }
        else {
            player.posX = 8;
        }
      }
      if (right) {
        if (player.posX < screenwidth-player.w-12) {
            player.xFloatPos = player.xIFloat.getValue(1);
            player.xFloatPos+=1;
            player.xIFloat.setValue(player.xFloatPos);
        }
        else {
            player.posX = screenwidth-player.w-12;
        }
      }
  }

  public void update(Graphics g) {
    paint(g);
  }

} // End Class GameWindow

Offline Markus_Persson

JGO Wizard


Medals: 16
Projects: 19


Mojang Specifications


« Reply #31 - Posted 2003-11-20 12:13:23 »

I think the problem is that you base the timing on System.currentTimeMillis(). It has an extremely poor resolution on Windows.

Play Minecraft!
Offline Conflux

Senior Newbie




Java games rock!


« Reply #32 - Posted 2003-11-20 13:52:10 »

In your example you had a "timer" object that picked the current time. But how can I create such an object?

I heard of the GAGE-Engine but I don't want to use external Libraries in my project.

Are there some other useful timers in the JDK?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Markus_Persson

JGO Wizard


Medals: 16
Projects: 19


Mojang Specifications


« Reply #33 - Posted 2003-11-20 14:13:33 »

I personally use the timer included in Gage.
There is one included somewhere in java 1.4.2, but it's fairly hidden and unsupported (I've never used it personally) that has been confirmed to be officially included in 1.5 iirc.

Play Minecraft!
Offline immudium

Junior Devvie




Gorram it!


« Reply #34 - Posted 2003-11-20 14:47:25 »

Here is my implementation of the hidden high performance timer in 1.4.2.  There has been alot of discussion about it already in the various forums if you want more information about it.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
public class PerfTimer
{
      private sun.misc.Perf hiResTimer;
      private long freq;
     
      public PerfTimer()
      {
            hiResTimer = sun.misc.Perf.getPerf();
            freq = hiResTimer.highResFrequency();
      }

      //return the number of nanoseconds per clock tick
      public long getResolution()
      {
            return (long)((1.0/freq) * 1000000000L);
      }

      //return the current time in milliseconds
      public long getCurrentTimeMillis()
      {
            return hiResTimer.highResCounter() / ((freq + 500L) / 1000L);
      }
}
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #35 - Posted 2003-11-21 00:17:52 »

Quote
I personally use the timer included in Gage.
There is one included somewhere in java 1.4.2, but it's fairly hidden and unsupported (I've never used it personally) that has been confirmed to be officially included in 1.5 iirc.

The sun.misc.Perf timer is NOT the same timer as the one that will be in 1.5.  The 1.5 timer is System.nanoTime()

Offline Markus_Persson

JGO Wizard


Medals: 16
Projects: 19


Mojang Specifications


« Reply #36 - Posted 2003-11-21 05:25:57 »

<denial>I knew that! I was just testing you!</denial>

*runs off to hide in a corner*

Play Minecraft!
Pages: 1 [2]
  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 (37 views)
2014-12-15 09:26:44

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

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

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

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

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

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

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

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

toopeicgaming1999 (38 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

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
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!