I recently saw a video that featured a cool looking NES game called Kingdom Crisis, it had a nice smooth camera, the kind you usually use linear interpolation to achieve, and I found an 8-bit lerp funcrion on SO
(A*(256-X)+B*X) /256
I tried to implement it in a game, but unlike the modern platforms that I've used lerp/floating point with before, this one doesn't seem to change speed based on the distance, am I suppose to change X based on the distance between center of camera and playerX?
Another difference is that on those modern platforms playerX just keeps increasing, on a 8-bit system you would need to scroll playerX back so it doesn't roll over, Ive tried alot of things but I can't get the camera to change speed and catch up to the player, does anyone have any experience with implementing smooth camera on a 8-bit system?
How was this done?
Moderator: Moderators
- Controllerhead
- Posts: 314
- Joined: Tue Nov 13, 2018 4:58 am
- Location: $4016
- Contact:
Re: How was this done?
Yes, you can use another byte for X and Y camera values for 256 subpixels, and the math is super quick; even a nibble of 16 subpixels can smooth it out decently, but you'll have to do some shifting every frame. Floating point is very slow.
-
- Posts: 30
- Joined: Sat Jul 04, 2020 5:27 pm
Re: How was this done?
Ok, I'm using 16 bits now, should I include playerX fraction in the calculation too? Do I need to change something else because I just have a glitchfest deluxe, I fell thru the floor..
Here's what it looks like now
and I init cameraX to 88 before that
#cameraX = 88 * 256
Here's what it looks like now
Code: Select all
temp1 = (#cameraX / 256) 'remember camera pos int
#cameraX = (#cameraX*(256-128)+#playerX*128) /256 'lerp between camera/player
scrollX = temp1 - (#cameraX / 256) 'get difference between old/new pos
fineScrollX = fineScrollX + scrollX 'scroll that distance, max 8
#playerX = #playerX + scrollX * 256 'scroll player too
and I init cameraX to 88 before that
#cameraX = 88 * 256
- Controllerhead
- Posts: 314
- Joined: Tue Nov 13, 2018 4:58 am
- Location: $4016
- Contact:
Re: How was this done?
I mean, i don't know what the rest of your code looks like, so i couldn't say why you're having issues exactly; ...however i do see some #immediate values in #cameraX and #playerX that my gut tells me might not be correct...
Having two bytes as a "camera" position allows you to have a smooth scrolling camera, but it's up to you to implement it based on the rest of your code. You could have camera X/Y acceleration values and nudge them towards player position, for example...
Having two bytes as a "camera" position allows you to have a smooth scrolling camera, but it's up to you to implement it based on the rest of your code. You could have camera X/Y acceleration values and nudge them towards player position, for example...
-
- Posts: 30
- Joined: Sat Jul 04, 2020 5:27 pm
Re: How was this done?
Yeah I caught that right after posting.Controllerhead wrote: ↑Sat May 20, 2023 6:36 pm I mean, i don't know what the rest of your code looks like, so i couldn't say why you're having issues exactly; ...however i do see some #immediate values in #cameraX and #playerX that my gut tells me might not be correct...
I allready had that before, I'm after a specific ramp up/ramp down camera using lerping.Controllerhead wrote: ↑Sat May 20, 2023 6:36 pm Having two bytes as a "camera" position allows you to have a smooth scrolling camera, but it's up to you to implement it based on the rest of your code. You could have camera X/Y acceleration values and nudge them towards player position, for example...
-
- Posts: 30
- Joined: Sat Jul 04, 2020 5:27 pm
Re: How was this done?
Nevermind, it was alot easier than I thought
Re: How was this done?
Hi there! Kingdom Crisis dev here!lillapojkenpåön wrote: ↑Sat May 20, 2023 4:30 pm I recently saw a video that featured a cool looking NES game called Kingdom Crisis, it had a nice smooth camera, the kind you usually use linear interpolation to achieve, and I found an 8-bit lerp funcrion on SO
(A*(256-X)+B*X) /256
I tried to implement it in a game, but unlike the modern platforms that I've used lerp/floating point with before, this one doesn't seem to change speed based on the distance, am I suppose to change X based on the distance between center of camera and playerX?
Another difference is that on those modern platforms playerX just keeps increasing, on a 8-bit system you would need to scroll playerX back so it doesn't roll over, Ive tried alot of things but I can't get the camera to change speed and catch up to the player, does anyone have any experience with implementing smooth camera on a 8-bit system?
Glad to know that you found a solution, there are indeed many ways of achieving this effect.
My camera code is a little bit messy due to optimization, but here's the relevant part:
Code: Select all
// Move the camera if it's off target
diff_x = (camera.target_x - camera.x) - HALF_SCREEN;
if (!diff_x) { camera.vx = 0; return; }
// Pre-calc the direction
zp_SIGNED = sign_of(diff_x);
zp_TMP = ABS(diff_x);
// Update the camera velocity (smooth camera)
if (zp_TMP < 2) camera.vx = zp_SIGNED * (!(frame % 13));
else if (zp_TMP < 3) camera.vx = zp_SIGNED * (!(frame % 8));
else if (zp_TMP < 5) camera.vx = zp_SIGNED * (!(frame % 5));
else if (zp_TMP < 8) camera.vx = zp_SIGNED * (!(frame % 3));
else if (zp_TMP < 13) camera.vx = zp_SIGNED * (!(frame % 2));
else camera.vx = zp_SIGNED;
// Move the camera (follow the player sprite)
camera.x += camera.vx;
CLAMP(int, camera.x, CAM_MIN_X, CAM_MAX_X);
camera.ox = camera.x + HALF_SCREEN;