Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (553)
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  
  Movement speed different on different computers?  (Read 1688 times)
0 Members and 1 Guest are viewing this topic.
Offline cubemaster21
« Posted 2013-01-15 23:38:36 »

I've been trying to make a movement equation without much luck. I might just be over complicating it, but I'm not sure why it's not working. On my brother's computer, it runs much too slow (His computer is wicked fast.). And on mine, it runs just right.
Here's my movement equation that I've got. Any criticism is also welcome.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
public void move(int delta){
      xCollision = false;
      yCollision = false;
      pastX = x;
      pastY = y;
      velocity.y += (G_ACCELERATION * delta)/1000.0;
      x += (velocity.x * delta)/1000.0;
      collisionBox = new CollisionBox(x, y, sprite.getWidth(),sprite.getHeight());
      if(doesCollideOnX()){
         x = pastX;
         velocity.x = 0.0;
         xCollision = true;
      }
      y += (velocity.y * delta)/1000.0;
      collisionBox = new CollisionBox(x, y, sprite.getWidth(),sprite.getHeight());
      if(doesCollideOnY()){
         y = pastY;
         velocity.y = 0.0;
         yCollision = true;
      }
      collisionBox = new CollisionBox(x, y, sprite.getWidth(),sprite.getHeight());
   }

If it helps any, the main specs on my computer are 2.1ghz Core 2 duo CPU, 4gb RAM, and 256mb on board video memory.

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Agro
« Reply #1 - Posted 2013-01-15 23:41:34 »

You need to keep a constant frame rate. I see delta in there somewhere, are you using delta timing?

Offline cubemaster21
« Reply #2 - Posted 2013-01-15 23:43:07 »

Yeah, i'm using delta timing.

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Vladiedoo
« Reply #3 - Posted 2013-01-15 23:44:52 »

Maybe his computer runs so fast that the program reads delta as "0".

EDIT: A quick "System.out.println(delta);" will show.

EDIT2: Ah I read too fast, sorry.
Offline cubemaster21
« Reply #4 - Posted 2013-01-15 23:46:39 »

Well, it does move, and i've monitored the delta as 1 on his computer.

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #5 - Posted 2013-01-15 23:49:57 »

Probably a rounding-error somewhere, or you haven't capped your deltaTime.

- Jonas
Offline cubemaster21
« Reply #6 - Posted 2013-01-15 23:54:43 »

I cannot say that I've capped my deltaTime. What do you suggest would be a good cap?

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #7 - Posted 2013-01-15 23:59:51 »

Depends. Are you using libgdx or some other library? If so, you shouldn't have these problems, and you shouldn't need to implement a cap. deltaTime should probably not be 1. It should be a float. My deltaTime, using libgdx is something like 0.000165532564577 (taken from memory, not an actual case). Which deltaTime do you get on your own computer vs his?

- Jonas
Offline cubemaster21
« Reply #8 - Posted 2013-01-16 00:02:58 »

Well, I'm using my own engine, and all the delta is measured in milliseconds. For his computer, he gets 1ms as his delta. I usually get around 5ms on mine.

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #9 - Posted 2013-01-16 00:06:36 »

Please yield code snippet where you calculate deltaTime and apply it to something.

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

Junior Member





« Reply #10 - Posted 2013-01-16 00:08:35 »

It seems like you did not do serious debugging. The problem is most likely your game loop, but we can only make wild guesses at what the problem might be.

Note that if you have a delta of 1.999 milliseconds that scraps the remainder after rounding, then you will not have consistent movement and will move slower at that rate than 1.000000001 rounded to 1.
Online HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #11 - Posted 2013-01-16 00:10:19 »

Velocity movement with deltas is complicated.

It means that if loop A runs twice as fast as loop B, and the velocity increment is 0.5.

loop A delta = 1
loop B delta = 2

tick 1
A speed = 0.5 dist = 0.5
B speed = 1.0 dist = 2.0

tick 2 (still tick 1 for loop B)
A speed = 1.0 dist = 1.5
B speed = 1.0 dist = 2.0

tick 3 (tick 2 for loop B)
A speed = 1.5 dist = 3.0
B speed = 2.0 dist = 6.0

etc.

You need to work out a way to fix this or switch to a fixed timestep.

Offline cubemaster21
« Reply #12 - Posted 2013-01-16 00:13:47 »

You need to work out a way to fix...
That's what I've been trying to do, and that's the reason I posted here.
Please yield code snippet where you calculate deltaTime and apply it to something.
As for the game loop, you'll probably all think it to be atrocious, but here you go, copy and pasted straight from my engine.
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  
log("Starting Toasted Engine...");
      boolean successfulShutdown = true;
      Screen.setTransform(backupTransform);
      long lastTime = System.nanoTime();
      double unprocessedSecond = 0;
      int frames = 0;
      boolean ticked = false;
     
      splashTimer.start();
      while (running) {
         long currentTime = System.nanoTime();
         long deltaTime = currentTime - lastTime;
         lastTime = currentTime;
         unprocessedSecond += deltaTime / 1000000000.0;
         while (unprocessedSecond > secondsPerTick) {

            unprocessedSecond -= secondsPerTick;
            ticked = true;
            tickCount++;
            if (tickCount % 60 == 0) {
               FPS = frames;
               lastTime += 1000;
               frames = 0;
               if (printFPS)
                  log(Integer.toString(FPS));
            }

         }

         if (ticked) {
            delta = (int) (deltaTime / 1000000);
            if(!splashTimer.isDone() && showCustomStaticSplash){
               splash(delta);
               Screen.add(customStaticSplash, 0, 0, Screen.getScreenWidth(), Screen.getScreenHeight());
               Screen.drawToWindow();
               continue;
            }
            if(updateTimers)
               for (Timer t : timers)
                  t.update(delta);
            for (EngineLoop el : methods)
               el.doProcesses(delta);
            AffineTransform preRender = Screen.getGraphicalTransform();
            for (RenderLoop rl : renderLoops){
               rl.render();
               Screen.setTransform(preRender);
            }
            if (renderDebug) {
               Font.RenderText("FPS:" + FPS, 0, 0, 1, debugColor);
               Font.RenderText("Delta:" + delta, 0,Font.getCharHeight() + 2, 1, debugColor);
               Font.RenderText("Tick:" + tickCount, 0,   2 * (Font.getCharHeight() + 2), 1, debugColor);
               Font.RenderText("Render loops:" + renderLoops.size(), 0,3 * (Font.getCharHeight() + 2), 1,debugColor);
               Font.RenderText("Logic loops:" + methods.size(), 0,4 * (Font.getCharHeight() + 2), 1,debugColor);
               Font.RenderText("Timers:" + timers.size(), 0, 5 * (Font.getCharHeight() + 2),1, debugColor);
            }
            frames++;
            Screen.drawToWindow();

            long timeTaken = System.currentTimeMillis();
            long sleepTime = period - timeTaken;
            try {
               Thread.sleep(sleepTime);
            } catch (Exception e) {
               
            }
         }

      }

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #13 - Posted 2013-01-16 00:18:08 »

Off the bat:
long lastTime = System.nanoTime();
should be changed to
long lastTime = 0;

Otherwise your first update will run with a deltaTime of 0.

- Jonas
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #14 - Posted 2013-01-16 00:25:33 »

These variables are weird. timeTaken is not actually set to the time taken to render the frame, and period is, for us, undefined. Please elaborate.

long timeTaken = System.currentTimeMillis();
long sleepTime = period - timeTaken;

- Jonas
Offline cubemaster21
« Reply #15 - Posted 2013-01-16 00:28:36 »

These variables are weird. timeTaken is not actually set to the time taken to render the frame, and period is, for us, undefined. Please elaborate.

long timeTaken = System.currentTimeMillis();
long sleepTime = period - timeTaken;
I've been using this loop since I started programming, I got it from a youtube tutorial. I'm not quite sure of what's going on there. I should probably just remove it

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #16 - Posted 2013-01-16 00:29:33 »

No no no, you have to sleep (or yield) between updates!

- Jonas
Offline cubemaster21
« Reply #17 - Posted 2013-01-16 00:32:34 »

No no no, you have to sleep (or yield) between updates!
Yeah, idk what I was thinking. Btw, the period variable is equal to 30. At this point, I'm thinking I might need to rewrite my engine....

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #18 - Posted 2013-01-16 00:33:00 »

What is period set to? It seems to me, that you'd have to change
long timeTaken = System.currentTimeMillis();
to
long timeTaken = System.currentTimeMillis()-lastTime;

But I don't think this'll help your problem.

- Jonas
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #19 - Posted 2013-01-16 00:34:53 »

You can easily implement another gameLoop, without having to change all your update-code. I do think you have to simplify/rethink your time-handling.

- Jonas
Offline cubemaster21
« Reply #20 - Posted 2013-01-16 00:39:05 »

Yeah, a new game loop seems to be in order... Thanks for the help guys.  Ultroman, which would you recommend? Fixed or variable time step?

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #21 - Posted 2013-01-16 00:57:10 »

You have a lot of stuff about unprocessedSeconds and ticking. It seems like a mix of methods, and it gets very confusing.

It seems weird to me that you'd ever get deltatimings of 1 and 5. I'm running my game at 60fps using a variable timestep loop, and my deltatimings are usually around 16.0. I only update each frame, because I don't need any more than that. If I need to do any collision-detection more precisely (so bullets don't go through something in a single frame), I simply divide the deltaTime by a factor in my bullet collision-code, and check the progression and collisions for the bullet each iteration of the divided time.

This run-through of gameloops may help you, although the fixed timestep implementation is a bit confusing. I'd go with the variable timestep loop, but read through that article, and see which one is the best for your situation.

- Jonas
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #22 - Posted 2013-01-16 02:07:01 »

This is what I use:

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  
   private volatile boolean running = false;
   private int desiredFPS = 60;
   private int fps = 0;
   private int frames = 0;
   private long totalTime = 0L;
   private long sleepTime = 0L;
   private long deltaTime = 0L;
   private long lastUpdateTime = 0L;
   private long currentUpdateTime = 0L;
   private long endLoopTime = 0L;
   private long maxDelta = 17 * (long)1e6, desiredDelta = Math.round((double)1000000000L / desiredFPS);


   public void run() {
      currentUpdateTime = System.nanoTime(); // game-loop timing variable
     
      while (running) {
         currentUpdateTime = System.nanoTime();

         // I've separated the FPS-calculations for readability purposes.
        updateTimersForFPScounter();

         deltaTime = currentUpdateTime - lastUpdateTime;
         lastUpdateTime = currentUpdateTime;
         
         
         /* Update all objects. If deltaTime is above the maxDelta, we keep running it through
          * with maxDelta, until the remaining deltaTime is less than maxDelta.
          * Then we run it through for the last time, with the remaining deltaTime,
          * and we should be exiting the loop after that. This makes sure our gameLogic never
          * gets passed a deltaTime it cannot handle. So all collisions are checked each time
          * we go through the loop. Good for avoiding anomalies in gamelogic calculations.
         */

         while(deltaTime > 0) {
             long delta = deltaTime > maxDelta ? maxDelta : deltaTime;
             updateGameLogic(delta);
             deltaTime -= delta;
         }
         

         // This construction is taken from some of Ra4king's code (most of this is, really).
        // Ignore this if you're not using Java2D, and just draw all your things here instead.
        do{
            do{
               // Get a graphics2D object to draw with.
              Graphics2D g = (Graphics2D)s.getBufferStrategy().getDrawGraphics();
               draw(g); // draws whatever you'd like

               //Dispose of graphics context
              g.dispose();
            }while(s.getBufferStrategy().contentsRestored());
               
            s.getBufferStrategy().show();
               
         }while(s.getBufferStrategy().contentsLost());

         

         // Find out the amount of time we should sleep after this update, to hit 60fps.
        endLoopTime = System.nanoTime();
         sleepTime = desiredDelta - (endLoopTime - currentUpdateTime);

         long diff;
         if(sleepTime>0){
            while((diff = System.nanoTime()-endLoopTime) < getSleepTime()) {
               if(diff < getSleepTime()*0.8)
                  try { Thread.sleep(1); } catch(Exception exc) {}
                  else
                     Thread.yield();
            }
         }
      }

      // These last lines make sure that if my game is currently in fullscreen mode, I reset the screen
     // and close the program completely. This is where you'd normally unload everything, and shut down,
     // as we have just exited the while(running) loop.

      if(!s.isWindowedMode())s.restoreScreen();

      System.exit(-1);
   }




   private void updateTimersForFPScounter() {
      totalTime += currentUpdateTime - lastUpdateTime;
      // count up frames per second...
     frames++;

      if( totalTime >= 1000000000) {
         totalTime = 0;
         setFps(frames);
         frames = 0;
      }
   }

- Jonas
Offline cubemaster21
« Reply #23 - Posted 2013-01-16 02:19:55 »

Yeah, that's A LOT better than the monstrosity that I posted, do you mind if I use it?

Check out my game, Viking Supermarket Smash
http://www.java-gaming.org/topics/iconified/28984/view.html
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #24 - Posted 2013-01-16 08:35:07 »

Off the bat:
long lastTime = System.nanoTime();
should be changed to
long lastTime = 0;

Otherwise your first update will run with a deltaTime of 0.
What is the problem with that? Wouldn't it be more of a problem if you set lastTime to 0 and then have uncontrollable delta in the first frame? Because you never know the relative starting point of the time measuring of nanotime().
I prefer having no movement or change in the first frame. Why should that be a problem at all?
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #25 - Posted 2013-01-16 19:05:27 »

Yeah, that's A LOT better than the monstrosity that I posted, do you mind if I use it?
Not at all Smiley

Off the bat:
long lastTime = System.nanoTime();
should be changed to
long lastTime = 0;

Otherwise your first update will run with a deltaTime of 0.
What is the problem with that? Wouldn't it be more of a problem if you set lastTime to 0 and then have uncontrollable delta in the first frame? Because you never know the relative starting point of the time measuring of nanotime().
I prefer having no movement or change in the first frame. Why should that be a problem at all?
If the timings of lastTime and the deltaTime you use later to update before the first frame, you will get a little bit of remainder from their differences, which I would define as an abnormal deltaTime for a frame. Better to ensure that it updates a correct amount of time.

- Jonas
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.

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

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

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

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

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

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

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

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (33 views)
2014-08-08 02:01:56

Norakomi (42 views)
2014-08-06 19:49:38
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!