Smooth Camera

Okay so I want to make the typical all day smooth camera we know from side scrolling games… This means some sort of fadeOut camera. So my first guess was: interpolation! But for some reason I CAN’T seem to get work!!!111 >:( This really bugs me because I tested out any option which came into my mind but I still get a jittering when I move a object and let the camera focus on in it. Especially with a slow object and likes.

So my Question, could someone tell me HOW to make it possible that I can finally have a smooth camera or look at my code so I can sleep well again? :frowning:

Here’s a test case (I’m using Slick2D btw~ But that shouldn’t be much the problem eh?):
download CameraTest.zip

There is also a jar so you can see what I mean :slight_smile: The project is a Eclipse project, hope that’s not the big problem?

I hope you guys can help me on this, I have this problem like months .__.

Edit:
oh and I round the values because I want whole pixels… no subpixels on a scaled matrix and stuff :confused:

I use a simple filter for smooth movement:


resultValue = rawValue * c + (1 - c) * oldValue;
oldValue = resultValue;

rawValue is the target (jittery) value (x, y, zoom, whatever) and c is a value between 0 and 1. The smaller c is, the faster the filter reacts to changes in the rawValue.

Just make sure to keep an internal double value and then round it when you need it to get an integer.

I usually do

resultValue += (rawValue - resultValue) * speed; //speed being 0.0 to 1.0

@krasse
I will try that the next day, thank you :slight_smile:

@theagentd
If you look at the source I did that which results in jittering :frowning: Also there is no information about the current delta in that calculation so I would need to cap the fps…
It’s some sort of problem with changing position of the object and the camera in every loop. I just use some old translate(-x, -y) so I can draw my objects by simply translating to there positions :slight_smile:

This should solve the problem of “jittery” movement. Like I said, I’ve been using it without problem for a few years now.

Sooo~ had something to do so sorry I’m answering now :frowning:

I tried BOTH version and none of them are working I still get a jittering… I’m not sure but it seems I’m doing something very simple very wrong.

All I do is the following:


public void update(GameContainer container, int delta) throws SlickException {
	camera.update(delta);
	dude.update(delta, container.getInput());
	camera.setTarget(dude.getMapPostionX(), dude.getMapPostionY());
}

the camera update then does this:


currentPosition.x += (targetPosition.x - currentPosition.y) * speed;  // I left the delta value away
currentPosition.y += (targetPosition.y - currentPosition.y) * speed;

dude is an entity class and does this:


public void update(int delta, Input in) {
	if(in.isKeyDown(Input.KEY_DOWN)) 
		position.y += moveSpeed * delta;
	if(in.isKeyDown(Input.KEY_UP)) 
		position.y -= moveSpeed * delta;
	if(in.isKeyDown(Input.KEY_RIGHT)) 
		position.x += moveSpeed * delta;
	if(in.isKeyDown(Input.KEY_LEFT)) 
		position.x -= moveSpeed * delta;
		
	if(position.x < 0)
		position.x = 0;
	if(position.y < 0)
		position.y = 0;
}

now i set the camera to the position of the entity (I set the values so that the entity is centered):


public float getMapPostionX() {
	return position.x - SimpleCamGame.WIDTH / 4 + object.getHeight() / 2;
}
public float getMapPostionY() {
	return position.y - SimpleCamGame.HEIGHT / 4 + object.getWidth() / 2;
}

Then we come to the render method, where I do this:


public void render(GameContainer container, Graphics g) throws SlickException {
	camera.translate(g);
		
	// before the dude the grid will be drawn here, I left it because there is nothing wrong with it.

	dude.render(g);
		
	g.resetTransform();
	g.drawString("Player Speed (W/S): " + dude.moveSpeed, 10, 25);
	g.drawString("Camera Speed (E/D): " + camera.fadeSpeed, 10, 40);
		
}

camera translate does this:


public void translate(Graphics g) {
	 g.scale(2, 2);
	 g.translate(-FastMath.round(currentPosition.x), -FastMath.round(currentPosition.y));
}

And the entity render looks like this (object is the image):


public void render(Graphics g) {
	object.draw(FastMath.round(position.x), FastMath.round(position.y));
}

Oh and FastMath.round(float value) does this:


public static int round(float value) {
	if(value < 0) 
		return (int)(value - 0.5f);
	else
		return (int)(value + 0.5f);
}

(I know it pretty dull .__. I just don’t want any subpixels and I tried it without round two which made it jitter too).

I can’t see where there might be a problem (except for strang float values and I do not think Slick is responsible for it :))…
Funny Fact: If I cap my Framerate to 60 and round the values of the postion of the player after there changed and doing the same for the camera the jittering goes away and gives me something like pixel-interpolation-thingie :emo:

Are there any examples out there I can try? (It really bugs me that I have a problem with something so simple ;_:wink:

I don’t think its the Camera. It’s Java / Slick.

The Java jitter problem naturally becomes the most apparent when scrolling…

Are you sure? I don’t think that this is true. Slick2D uses a neat gameloop und I also get this if I set up my own gameloop (Slick2D just has everything I wanted to make and more :D) I can only think of strange float values which will lead OpenGl to draw the images to the wrong pixels because of the round method or the subpixels on a scaled matrix. This is annoying… seems like i have to hack this with capped framerates and rounds -.- I don’t like it but it seems I have too :frowning:

Hey what do you mean with “Fade-Out” Camera?
I would try you .rar file but it says it has corrupt data I cant open it _

Can you tell me a game where it is use?
Or do you want something like in the RPG Maker that when you leave a map a transition comes up?

You may want to also consider using a what I call “slushy” camera centering algorithm.

Basically you do something like this in psudocode:

Find error in X.
Find error in Y.

Camera X = Camera X + error X * max scroll speed
Camera Y = Camera Y + error Y * max scroll speed

If you need more smoothing then look at the rate of change in error as well. Eventually at some point you will exceed the max speed for the camera and you will basically have 2 options (without changing the graphics) Either A) You zoom out (pretty neat to base zoom off of speed) or B) slow player movements.

As always a higher FPS will yield smoother results.

@GustavXIII
Whar *.rar file o.o There is just a zip and it works perfectly fine, just tested it and there is no corruption :slight_smile:

Look a Jump’n’Runs. These games often have such smooth camera or strategy games too (I think Civilization V [?] has such a camera movement, tho it’s 3D…). And no, I’m not talking about the Transitions between Maps^^ Transitions are easy. I think Slick2D already provides Interfaces an methods for it :smiley:

@drakesword

What to you mean by “error”. I do not fully understand what you mean… Or do you want so say I should imitate the interpolation effect by adding values to the camera postion? (That’s a nice Idea! But a bit hacky) And I don’t want to zoom out, I CAN do this since my Camera-System has the option to zoom out but I intend to only use it as a effect where you meet large enemies or something like that :slight_smile: But thx for the tip!

So say that in the last frame your guy and camera was at 0,0 The next frame the guy has moved to 20,20. so the error is 20 in the x and 20 in the y multiply each number by a scaling (smoothing) factor and it will approach the center of the object.

Also consider that when the camera is “close enough” that it just stops moving otherwise it will twitch continuously.

If you wanted the camera to be “no further then x” then you take the error (in the above case 20) and divide it by the maximum you want it to be off. If that number is more then 1 or less then -1 then calculate how far to get it in bounds or double the change for the position