Weird Run Speeds on Different Computers

Very well written explanation, thank you very much. I will implement this as soon as possible :).

EDIT: So I did this, followed Eli’s tutorial (Very helpful by the way) and everything is up and running, but the walking for the mob is all messed up. I used to say to add 1/-1 to the x or y for the movement. That was a very smooth walking speed. Now it is all jerky, jumping forward when I use MOVESPEED * delta. I know this has something to do with delta… Any suggestions?

EDIT 2: When I replace MOVESPEED * delta with just a 1 like it used to be there is still no smooth walking speed. So it has something to do with the loop I am using. Here is the code foe anyone interested:


	public void run() {
		long lastLoopTime = System.nanoTime();
		final int TARGET_FPS = 60;
		final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;

		while (inRealGame) {
			if (inGame) {
				long now = System.nanoTime();
				long updateLength = now - lastLoopTime;
				lastLoopTime = now;
				double delta = updateLength / ((double) OPTIMAL_TIME);

				lastFpsTime += updateLength;
				fps++;

				if (lastFpsTime >= 1000000000) {
					System.out.println("(FPS: " + fps + ")");
					lastFpsTime = 0;
					fps = 0;
				}

				gamePhysic(delta);
				try {
					Thread.sleep((lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			repaint();
		}
	}

	public void gamePhysic(double delta) {
		if (!isFirst) {
			room.physic();
			mobSpawner();
			for (int i = 0; i < currLevel.mobs.length; i++) {
				if (currLevel.mobs[i].inGame) {
					currLevel.mobs[i].physic((int) delta);
				}
			}
			if (currLevel.levelOver) {
				getNextLevel(currLevel);
			}
		}
	}

And the moving for the mob (superclass) :


public void physic(int delta) {
		if (walkFrame >= walkSpeed) {
			if (direction == right) {
				x += MOVESPEED;
			} else if (direction == upward) {
				y -= MOVESPEED;
			} else if (direction == downward) {
				y += MOVESPEED;
			} else if (direction == left) {
				x -= MOVESPEED;
			}
			mobWalk += 1;

			if (mobWalk == Screen.room.blockSize) {
				if (direction == right) {
					xC += MOVESPEED;
					hasRight = true;
				} else if (direction == left) {
					xC -= MOVESPEED;
					hasLeft = true;
				} else if (direction == upward) {
					yC -= MOVESPEED;
					hasUpward = true;
				} else if (direction == downward) {
					yC += MOVESPEED;
					hasDownward = true;
				}

				if (!hasUpward) {
					try {
						if (Screen.room.block[yC + 1][xC].groundID == Value.groundRoad) {
							direction = downward;
						}
					} catch (Exception e) {
					}
				}

				if (!hasDownward) {
					try {
						if (Screen.room.block[yC - 1][xC].groundID == Value.groundRoad) {
							direction = upward;
						}
					} catch (Exception e) {
					}
				}

				if (!hasLeft) {
					try {
						if (Screen.room.block[yC][xC + 1].groundID == Value.groundRoad) {
							direction = right;
						}
					} catch (Exception e) {
					}
				}

				if (!hasRight) {
					try {
						if (Screen.room.block[yC][xC - 1].groundID == Value.groundRoad) {
							direction = left;
						}
					} catch (Exception e) {
					}
				}

				if (Screen.room.block[yC][xC].airID == Value.airCastle) {
					deleteMob();
					loseHealth();
				}

				mobWalk = 0;
				hasUpward = false;
				hasDownward = false;
				hasLeft = false;
				hasRight = false;
			}
			walkFrame = 0;
		} else {
			walkFrame += 1;
		}
	}

I can’t really say much without more information. Can you show us some key parts of your code?

Post updated with information

Ok, I figured out something. If I raise the variable “targetfps” to something higher, the movement is much, much smoother. The only problem is that the game should be totally smooth at 60 FPS, which is what it is set to in the example. 60 FPS is more than enough to be smooth. Also, when I set the move speed of the mob to more than one, it jumps pixels instead of smoothly going faster, like I would like it to. Anyone got a better way of doing all this?

If it moves >1 per frame, then it will obviously more >1 pixel.

The human eye will see anything >=24 fps as moving. All the extra frames just smooth everything out in case an object is moving too fast for the brain to realise that it’s the same object just in a different place.

The player won’t notice.

You can’t make anything go faster or slower without skipping/stopping on pixels. “Smoothly going faster” is not going to happen on a screen made up of pixels.

Also, your loop is faulty.

You are sleeping for icode/1000000[/icode] which basically means you are sleeping for a whole frame plus whatever the differnce between nanoTime and lastLoopTime.

This means you will get deltas of >2 and frame rates of <30fps.

alright, makes sense. If the sleep time is faulty, what do I need to change?

And another strange something thats happening. The reason that the mobs hardly move at all when I use MOVESPEED * delta is because the delta I am passing it is like this:


0.9676847
0.8476047
0.8783945
0.9083911
0.9012535
0.8945824
0.9042859
0.9009269
0.8978947
0.9003671
0.8992475
0.9031663
0.9527097
0.8525964
0.8930429
0.9051722
0.9019999
0.8964018
0.9016734
0.90172
0.9006471
0.896635
0.9050323
0.9174881
0.9091376
0.8735427

This is the output to the console when I print out delta.


//-snip-
	public void gamePhysic(double delta) {
		if (!isFirst) {
			room.physic();
			mobSpawner();
			for (int i = 0; i < currLevel.mobs.length; i++) {
				if (currLevel.mobs[i].inGame) {
					currLevel.mobs[i].physic((int) delta);
				}
			}
			if (currLevel.levelOver) {
				getNextLevel(currLevel);
			}
		}
	}
//-snip-

You are casting the delta to an int, which means that it will be zero unless you have lag, in which case it will be 1 or more.
As you know, multiplying by zero = zero. So as long as you don’t get lag, nothing moves.

Don’t cast the delta to an int and you should be fine.

Wow. I feel very silly. It works fine now, thanks! Now I want to go further though, and the way I used to have it, I could adjust the gameSpeed variable to make the game go faster. I’m guessing there is no real easy way to do this now though, correct?

If you want to do that, DON’T CHANGE THE SPEED OF THE LOOP!

Leave the loop alone, but multiply all movement/fire rate/other values by a “speed” variable. Then you can adjust the speed of everything without ruining the rendering, overusing CPU, or having input lag.

That’s what I was thinking, but I didnt know if there was an alternative method. Thank you VERY much for all of your help.