Log In  

I am coming back to Pico8 after a few month pause just to find that I still cannot fix a problem I have with my platformer project. I would appreciate any help on it.

what I have:

The camera follows a point offset from the character.
I achieved a rubberband effect with

v = (cam.aim-cam.p)*0.1 
cam.p += v

where cam.aim is a vector with an offset from the players position vector and cam.p is the current camera position.
When using the parachute this is only true when the character has a certain distance form the camera position. Also there is a different behavior while the parachute is opening.

While the camera is totaly fine while running and jumping, it becomes jittery when the character is mid air and moving really slowly. That's because, I think, the camera cannot decide if it is one pixel away from it's destination or not.

Whatever I do .. It stays that way. or doesn't work at all ^^"

How can I force it to stay at it's destination position when moving really slow?

P#66551 2019-08-11 17:21

Hard to say without being shown the camera aim point calculation.

What you do show isn't capable of overshoot, so it at least isn't capable of causing the back-and-forth problem you suspected.

The problem is most likely that some combination of player position, aim point, and camera position are crossing pixel boundaries at different times, due to fractional velocities, causing e.g. the camera to advance a pixel before the player does.

If so, you might need to do some flr()ing while calculating relative offsets, to accommodate/counter the eventual snapping to screen pixels.

Like, let's do this in 1D, where the position is just one value:

If cam.p-cam.aim is 5.2, that means the two should be 5 indivisible pixels apart on screen, right? However, let's say that distance comes from cam.p being 9.1 and cam.aim being 3.9. Those numbers will effectively get flr()ed to 9 and 3 when passed off to the gpu, and thus they'll end up 6 pixels apart instead. In this case, this will happen about 1/5th of the time, when the two straddle integer boundaries like this. This will cause a visible, asymmetrical jitter.

The solution, when you have two fractional positions, let's say p1 and p2, doing this sort of thing when converted to integer values, is to store p1 as an absolute position and p2 instead as r2, the relative offset from p1 to p2. When rendering, you'd use p1 as-is, but you'd calculate p2 dynamically as p1+flr(r2). Something like that, anyway.

TL;DR: The camera, player, and aim point can all snap to pixels independently, and not necessarily in sync. Do what you can do make them all snap at the same time.

P#66567 2019-08-11 20:17 ( Edited 2019-08-11 20:21)

Yes you were right. Thank you!
When I forced the camera to move with the player + offset, everything was fine but when I created that offset later, e.g. mid jump, it became jiggery.
I couldn't get around it, because I have zero math skills to be honest xD
instead I wrote a helping function to check if the camera position is in proximity of the 'ideal' camera aim/destination and than snap to it if true.

here is how I've done it:

--util function

function get_distance(v1, v2)
    return sqrt(v1.x-v2.x) * (v1.x-v2.x) + (v1.y-v2.y) * (v1.y-v2.y)
end

function in_proximity(d,a,b)
    return d>get_distance( a,b ) or d>get_distance( b,a ) 
end
--inside update camera
local v = make_vector(0,0)
if player.parachute_open then
    --look down while parachute is open
    cam.aim.y = player.p.y+35
    --camera snapping
    if in_proximity(5, cam.p, cam.aim) then
        cam.p = cam.aim
    else
        v = (cam.aim-cam.p)*0.1
    end
end
    cam.p+=v
    camera(cam.p.x-64, cam.p.y-64)      
end
P#66645 2019-08-13 16:10 ( Edited 2019-08-15 14:58)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 11:54:45 | 0.008s | Q:12