I'm designing a platform. For the scrolling levels, I've see an effect where the screen is very smoothing moving. So if you move in any direction the screen take a moment to catch up. Instead of the usual jerky left, right, up, down and you character stays exactly in the middle all the time.
Does anyone know how to do this effect? I hope I've tried to explain what I'm talking about.
Nim made a nice smooth scrolling engine recently (about 3-4 months ago) that I like to use, but I just searched and couldn't find it... perhaps it's well hidden
Hm, well, I've come across a few techniques for a smoother scrolling that I've come to prefer...
The way I like it is such (all values used within are arbitrary, and need to be tuned to taste):
Horizontal scrolling is centered on a point relative to the player. This point is based off of a cosine wave of a value that changes when the player is facing the other direction. That way you get a sort of smooth acceleration/deceleration of the camera.
Something like this:
Center Horizontal Window at X( "Player" ) + 120 * cos( Value )
Where 120 is the amount you want to see ahead of the player. When the Value is at 0, you see fully to the right, and at 180 you see to the left.
Then you alter the value slightly when the player turns, and alter it more significantly when the player is moving (so that he doesn't have to wait for the camera).
And if you want to get really fancy, you can make the foresight value (the 120 in the equation) extend based on the player's speed.
Vertical is a bit more tricky. I like to have sort of a range in the center of the screen where the camera won't scroll if the player's within it. That way the smaller jumps won't jostle the screen too much. So only if the player's Y position is lower than 80 or greater than 160 will the screen scroll.
And even then there are further measures.
At all times (when the player is out of the range) the camera will adjust itself towards the player slightly, like so:
Center Vertical Window at ( ( ( Y Top Frame + 120 ) * 20 ) + Y( "Player" ) ) / 21
So that the frame will gradually move towards the player. But if the player's on the ground, the camera will do something like this:
Center Vertical Window at ( ( ( Y Top Frame + 120 ) * 5 ) + Y( "Player" ) ) / 6
A more significant change.
The result is that, even if the player is out of the central zone, the camera won't adjust too quickly unless he's on the ground. This is to stabilize things a bit more while making tricky jumps.
Besides what Fifth posted; it also can depend on the type of movement of your character. If you are using a built-in movement, such as "Platform Movement" or "Ball Movement", you will indeed have to do something like that. However, if you are using a custom movement, for example "Position of Player = Position + 1" style stuff in the event editor, it can be alot easier; all you need to do is make sure your "Center Camera on Player" event is lower down in the event editor then anything that affects movement.
For example;
Always
:Y = Y+1
If Left Button
:X = X+1
If Right Button
:X = X-1
Always
:Center Scrolling at Player
Since it occurs AFTER the new position is calculated, it will be exactly on the player at every frame, giving a smooth effect. If you aren't using a custom movement engine yet, I highly suggest looking into it.
Create a new active object, which we'll program to function as a camera.
The screen will follow this object, which softly follows the player.
In properties, give it these alterable values:
--- XPOS
--- YPOS
--- RATIO (set its default value to something like 300)
We're gonna do with this what we do with float-point custom movements. We'll store the camera's X and Y position in alterable values, so they can have decimal points. It makes movement smoother and more precise.
The 'Ratio' value will be the rate of delay. 1000 will follow the player exactly, the same as 'Scroll to Player' would do. I find 300 is a good value, you'll have to experiment.
So the events are:
//Set the XPOS and YPOS values at the start, to match where we put the camera.
//This enables us to place the camera object anywhere in the level,
// and at the start of the frame, the camera will migrate from that location to the
// player. So you could place the camera at the end of the level, and the player
// at the start, and the camera will swoosh back to the player, giving a brief
// preview of the whole level.
on START OF FRAME
--- Camera: Set XPOS to 'X("CAMERA")'
--- Camera: Set YPOS to 'Y("CAMERA")'
//Now, AFTER any custom movement events, we will use a simple formula to softly follow the player:
ALWAYS
--- Camera: Set XPOS to
Xpos("CAMERA") + (X("PLAYER") - Xpos("CAMERA")) * Ratio("CAMERA")/1000.0
--- Camera: Set YPOS to
Ypos("CAMERA") + (Y("PLAYER") - Ypos("CAMERA")) * Ratio("CAMERA")/1000.0
--- Camera: Set X position to 'Xpos("CAMERA")'
--- Camera: Set Y position to 'Ypos("CAMERA")'
And that's it. All the variables, like how much the camera must move per frame, are all calculated using alterable variables, so we can keep them precise to several thousandths of a pixel. And at the end of it, we position the camera to follow those variables. This way, the movement is smooth.
The actual formula we're using is this:
cpos = cpos + (target - cpos) * r
where:
cpos = the position of the camera
target = the target position (in this case, of the player)
r = the rate of movement (a decimal value between 1 and 0, like 0.3).
How this works:
(target - cpos) finds the distance between the target (the player) and the camera's current position.
Multiplying it by the rate value gives us a percentage of the distance. This is what gives the formula its smoothness.
Finally, we add this to the camera's current position, which has the effect of moving the camera.
It works wonderfully! I love it! Better yet, you can add ANOTHER object to function as the target, instead of the player. Then, during conversations, you can reposition this target object to whoever's speaking at the time, or to important objects or cutscenes.
This way, during conversations the camera will softly swing between the two speakers.
I tried a few different ways to go about smooth scrolling but found yours was the best. It's great, it's only 2 event. Over the past week I was trying all sorts of things using heaps of different events so I'm glad you wrote what you did. Anyway I found that a RATIO of 50 worked perfect for me.
Anyway, thanks again and anyone who wants smooth scrolling, do this!
This method is smoother in the sense that it dampens the movement of the camera. I rather like systems where the camera can actually swing a bit, I oughta try building one if I have time.