đĨ Mastering the Camera System â Follow, Shake, Zoom
A Complete Guide to Camera Control in Limn Engine
đ Introduction
The camera is your player's window into the game world. A well-implemented camera system can make your game feel smooth, responsive, and professional. A poorly implemented camera can make even the best game feel clunky and frustrating.
In Limn Engine, the camera system is simple to use but powerful enough for complex games. You can make the camera follow the player, shake for dramatic effect, zoom in and out, and combine all three for cinematic experiences.
In this guide, we'll cover everything you need to know about the camera â from basic follow to advanced shake effects and zoom.
đ¯ What We'll Cover
- Camera Follow â Keeping the player centered
- Smooth Follow â Making the camera feel natural
- Camera Shake â Adding impact to explosions and hits
- Rotation Shake â A unique twist on camera shake
- Camera Zoom â Zooming in and out (correctly)
- Combining Effects â Using everything together
- Practical Example â A complete game with camera effects
đŽ Part 1: Camera Follow â The Basics
What Is Camera Follow?
Camera follow means the camera moves with the player, keeping them centered on the screen. Without it, the player would walk off the screen and disappear.
Why Is It Important?
| Without Camera Follow | With Camera Follow |
|---|---|
| Player walks off screen | Player stays centered |
| Can't see where you're going | Always see the player's surroundings |
| Feels clunky and limited | Feels smooth and professional |
The Code
// Make the camera follow the player
display.camera.follow(player);
What It Does
| Line | What It Does |
|---|---|
display.camera |
Access the camera object attached to the display |
.follow() |
Tell the camera to follow a target |
player |
The target to follow (any Component) |
Important Note
follow() must be called every frame because the player is constantly moving. This is the one camera function that needs to run in your update loop.
function update(dt) {
// Follow the player every frame
display.camera.follow(player);
}
When to Use It
| Use Case | Why |
|---|---|
| Platformers | Player moves through large levels |
| Open-world games | Player explores a large map |
| Top-down games | Player moves around a big area |
đŽ Part 2: Smooth Follow â Making It Feel Natural
What Is Smooth Follow?
Smooth follow is a lerp (linear interpolation) effect. Instead of the camera snapping to the player instantly, it slowly eases toward them, creating a natural, floating feel.
Why Is It Better?
| Instant Follow | Smooth Follow |
|---|---|
| Camera snaps instantly | Camera glides smoothly |
| Can feel jerky | Feels natural and polished |
| No motion delay | Slight delay creates anticipation |
The Code
// Smooth follow â the 'true' parameter enables lerp
display.camera.follow(player, true);
How It Works
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â Instant Follow: â
â Camera follows player exactly. No delay. â
â â
â Player: [â] â â â â [â] â
â Camera: [â ] â â â â [â ] â
â â
â Smooth Follow: â
â Camera lags slightly behind. Creates a natural feel. â
â â
â Player: [â] â â â â [â] â
â Camera: [â ] â â â [â ] â [â ] â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
When to Use It
| Use Case | Why |
|---|---|
| Platformers | Creates a natural, floating feel |
| Exploration games | Gives a sense of scale |
| Cinematic scenes | Smooth camera moves |
đŽ Part 3: Camera Shake â Adding Impact
What Is Camera Shake?
Camera shake is a quick, random movement of the camera that creates a feeling of impact. When an explosion happens or the player gets hit, the camera shakes briefly, making the action feel more powerful.
Why Is It Important?
| Without Shake | With Shake |
|---|---|
| Explosions feel weak | Explosions feel powerful |
| Hits feel flat | Hits feel impactful |
| No feedback for actions | Immediate visual feedback |
The Code
// Shake the camera â (x intensity, y intensity)
display.camera.shake(8, 8);
How It Works
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â Shake Effect: â
â â
â Camera moves randomly for a split second: â
â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â Normal: [â ] â â
â â Shake 1: [â â ] (moves right) â â
â â Shake 2: [â ] (returns) â â
â â Shake 3: [â ] (moves left) â â
â â Shake 4: [â ] (returns) â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â The shake effect automatically resets after about 1 frame. â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Different Shake Intensities
| Intensity | When to Use |
|---|---|
shake(2, 2) |
Coin collection, light impacts |
shake(5, 5) |
Player hit, enemy death |
shake(8, 8) |
Explosion, heavy impact |
shake(12, 12) |
Boss attacks, big explosions |
Important Note
shake() is a one-time call â you don't need to call it every frame. Just call it when the impact happens:
// When player hits an enemy
if (player.crashWith(enemy)) {
display.camera.shake(8, 8); // One call, auto-resets
}
đŽ Part 4: Rotation Shake â The Unique Twist
What Is Rotation Shake?
Rotation shake rotates the camera slightly, creating a dramatic screen-twist effect. This is a unique feature that most game engines don't have.
Why Is It Unique?
| Position Shake | Rotation Shake |
|---|---|
| Moves the camera side to side | Rotates the camera around the center |
| Feels like a bump | Feels like a twist or impact |
| Good for most impacts | Great for heavy impacts |
The Code
// Rotation shake â angle in radians
display.camera.shakeRotation(0.08);
How It Works
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â Rotation Shake: â
â â
â Normal: ââââââââââââ â
â â Game â â
â â World â â
â ââââââââââââ â
â â
â Rotated: ââââââââââââ â
â â Game â â Slight twist â
â â World â â
â ââââââââââââ â
â â
â The rotation effect automatically resets after about 1 frame. â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Different Rotation Intensities
| Angle | When to Use |
|---|---|
shakeRotation(0.03) |
Subtle impact |
shakeRotation(0.05) |
Moderate impact |
shakeRotation(0.08) |
Heavy impact |
shakeRotation(0.12) |
Very heavy impact |
Important Note
Like shake(), shakeRotation() is a one-time call â you don't need to call it every frame.
đŽ Part 5: Camera Zoom â Changing Perspective
What Is Camera Zoom?
Camera zoom changes the scale of the canvas, making the game world appear larger or smaller. It's like looking through a zoom lens.
Why Is It Useful?
| Zoom In | Zoom Out |
|---|---|
| See things up close | See more of the world |
| Focus on action | Show the bigger picture |
| Cinematic effect | Strategic view |
The Code
// Zoom in (closer)
display.camera.setZoom(1.5);
// Zoom out (farther)
display.camera.setZoom(0.6);
// Normal zoom
display.camera.setZoom(1);
Important Note â This Is Different from Follow!
setZoom() does NOT need to be called every frame. It's a one-time change that sticks until you change it again.
// â
CORRECT: Only call when zoom changes
function handleZoomInput() {
if (display.keys[90]) {
display.camera.setZoom(1.5);
display.keys[90] = false;
}
if (display.keys[88]) {
display.camera.setZoom(0.6);
display.keys[88] = false;
}
}
// â WRONG: Calling every frame unnecessarily
function update(dt) {
display.camera.setZoom(1.5); // DON'T DO THIS!
}
Why This Matters
| Approach | Problem |
|---|---|
| Calling every frame | Wastes CPU cycles, unnecessary |
| Calling only on change | Efficient, clean |
How It Works
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â Zoom 1.0 (Normal): â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â â â Game World â â â
â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â Zoom 1.5 (Zoom In): â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â â â Game World (zoomed in) â â â
â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â Zoom 0.5 (Zoom Out): â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â â â Game World (zoomed out) â â â
â â ââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
đŽ Part 6: Combining Effects
Why Combine?
Combining effects creates a more dramatic and impactful experience. Position shake + rotation shake + zoom creates a cinematic effect that feels professional.
Example: Explosion
// Combined explosion effect â one-time calls
display.camera.shake(10, 10); // Position shake
display.camera.shakeRotation(0.08); // Rotation shake
display.camera.setZoom(1.2); // Zoom in slightly
Example: Boss Attack
// Boss attack effect
display.camera.shake(15, 15); // Heavy position shake
display.camera.shakeRotation(0.12); // Heavy rotation shake
display.camera.setZoom(0.8); // Zoom out slightly
Example: Player Death
// Player death effect â slow motion zoom out
display.camera.shake(5, 5); // Light shake
display.camera.shakeRotation(0.05); // Light rotation
display.camera.setZoom(0.6); // Zoom out
đŽ Part 7: Practical Example â Complete Game
Here's a complete example that demonstrates all camera features:
<!DOCTYPE html>
<html>
<head>
<title>Camera System Demo</title>
<script src="epic.js"></script>
</head>
<body>
<script>
// ââ 1. SETUP ââ
const display = new Display();
display.perform();
display.start(800, 600);
display.backgroundColor("#1a1a2e");
// ââ 2. WORLD SIZE ââ
display.camera.worldWidth = 2000;
display.camera.worldHeight = 2000;
// ââ 3. CREATE THE PLAYER ââ
const player = new Component(40, 40, "#5b8cff", 100, 100, "rect");
display.add(player);
// ââ 4. CREATE SOME OBSTACLES ââ
const wall = new Component(200, 20, "#ff6b6b", 400, 300, "rect");
display.add(wall);
// ââ 5. SCORE UI ââ
const scoreText = new Tctxt("24px", "Arial", "white", 20, 50);
scoreText.setText("Score: 0");
display.add(scoreText);
// ââ 6. GAME STATE ââ
let score = 0;
let zoomLevel = 1;
// ââ 7. GAME LOOP ââ
function update(dt) {
// ââ PLAYER MOVEMENT ââ
let mx = 0, my = 0;
if (display.keys[37]) mx = -1;
if (display.keys[39]) mx = 1;
if (display.keys[38]) my = -1;
if (display.keys[40]) my = 1;
if (mx !== 0 && my !== 0) {
mx *= 0.707;
my *= 0.707;
}
player.x += mx * 300 * dt;
player.y += my * 300 * dt;
// ââ WORLD BOUNDARIES ââ
player.x = Math.max(0, Math.min(1960, player.x));
player.y = Math.max(0, Math.min(1960, player.y));
// ââ CAMERA FOLLOW (EVERY FRAME) ââ
display.camera.follow(player, true);
// ââ CHECK COLLISION ââ
if (player.crashWith(wall)) {
// ââ CAMERA EFFECTS (ONE-TIME CALLS) ââ
display.camera.shake(8, 8);
display.camera.shakeRotation(0.05);
// Increase score
score += 10;
scoreText.setText("Score: " + score);
// Move the wall to a new position
wall.x = Math.random() * 1800 + 100;
wall.y = Math.random() * 1800 + 100;
}
// ââ ZOOM (ONLY WHEN CHANGED) ââ
if (display.keys[90]) { // Z key
zoomLevel = 1.5;
display.camera.setZoom(zoomLevel);
display.keys[90] = false;
}
if (display.keys[88]) { // X key
zoomLevel = 0.6;
display.camera.setZoom(zoomLevel);
display.keys[88] = false;
}
if (display.keys[67]) { // C key
zoomLevel = 1;
display.camera.setZoom(1);
display.keys[67] = false;
}
// ââ UI ââ
scoreText.fixed();
}
console.log("đŽ Camera System Demo");
console.log("đšī¸ Arrow keys to move");
console.log("đ Z to zoom in, X to zoom out, C to reset zoom");
console.log("đĨ Walk into the red wall to trigger camera shake!");
</script>
</body>
</html>
đ Quick Reference
| Feature | When to Call | Code |
|---|---|---|
| Follow player | Every frame | display.camera.follow(player); |
| Smooth follow | Every frame | display.camera.follow(player, true); |
| Position shake | Once (on impact) | display.camera.shake(8, 8); |
| Rotation shake | Once (on impact) | display.camera.shakeRotation(0.08); |
| Zoom in | Once (when zoom changes) | display.camera.setZoom(1.5); |
| Zoom out | Once (when zoom changes) | display.camera.setZoom(0.6); |
| Reset zoom | Once (when zoom changes) | display.camera.setZoom(1); |
đĄ Key Takeaways
| Function | Called Every Frame? | Why |
|---|---|---|
follow() |
â Yes | Player is constantly moving |
shake() |
â No | Only when an impact happens |
shakeRotation() |
â No | Only when an impact happens |
setZoom() |
â No | Only when zoom changes |
đ¯ The One-Line Summary
"Follow every frame, shake on impact, zoom only when needed â mastering these three patterns gives you professional camera control."
Draw your game into existence â with a camera system that feels professional. đĨđ
Top comments (0)