Skip to content

Dynamic Camera Control

Explore zooming into a bitmap and camera movements with mouse clicks
Written by: Sharvani Kandala, Vishnu Vengadeswaran
Last updated: 02 Aug 2025


This tutorial shows how to use the camera in SplashKit to create interactive, dynamic game experiences. We’ll focus on zooming into specific areas and making the camera follow a moving bitmap as per user clicks, allowing you to create more immersive applications.

The camera in SplashKit enables navigation through a game world larger than the visible window. By adjusting the camera’s position, you can control the part of the world that the player sees. This tutorial explores using camera functions to move the camera and adjust the positions as required.

This example demonstrates how to implement a zoom effect on a preloaded bitmap of a colored grid. When the user clicks on an area of the grid, the camera zooms into the clicked section. The zoomed-in area fills the screen, and pressing the ESC key resets the view to show the entire grid again.

#include "splashkit.h"
// Zoom scale factor
const int ZOOM_SCALE = 5;
// Initial camera position at (0,0)
point_2d camera_pos = { 0, 0 };
const int BOX_SIZE = 100;
bool zoomed_in = false;
int main()
{
// Open window with specified dimensions
open_window("Camera Zooming Example", 500, 550);
// Load bitmap for the grid of colors
load_bitmap("color_grid", "color-grid.png");
while (!window_close_requested("Camera Zooming Example"))
{
process_events();
// Zoom In
if (mouse_clicked(mouse_button(LEFT_BUTTON)) && !zoomed_in)
{
int clicked_box_x = (int)(mouse_x()) / BOX_SIZE;
int clicked_box_y = (int)(mouse_y()) / BOX_SIZE;
// Update the camera position to center on the clicked box
camera_pos.x = (clicked_box_x * BOX_SIZE - BOX_SIZE * 2) * ZOOM_SCALE;
camera_pos.y = (clicked_box_y * BOX_SIZE - BOX_SIZE * 2) * ZOOM_SCALE;
// Update the camera position
set_camera_position(camera_pos);
zoomed_in = true;
}
// If Escape key is pressed, return to the full grid view
if (key_typed(key_code(ESCAPE_KEY)) && zoomed_in)
{
camera_pos.x = 0;
camera_pos.y = 0;
// Reset the camera position
set_camera_position(camera_pos);
zoomed_in = false;
}
// Draw a 5x5 grid of different colored boxes
clear_screen();
if (!zoomed_in)
{
draw_bitmap("color_grid", 0, 0, option_defaults());
}
else
{
draw_bitmap("color_grid", 0, 0, option_scale_bmp(ZOOM_SCALE, ZOOM_SCALE));
}
fill_rectangle(color_light_gray(), 0, 500, screen_width(), 50, option_to_screen());
draw_text("Click a box to zoom in. Press ESC to return to grid", color_black(), 10, screen_height() - 30, option_to_screen());
refresh_screen();
}
// Close the window when finished
close_all_windows();
return 0;
}

Let’s break this code into smaller sections and analyze each part.

Setting Up the Window and Loading the Bitmap

Section titled “Setting Up the Window and Loading the Bitmap”

In this section, we’ll start by creating a window and loading a bitmap that represents a grid of colors. We also define the camera’s zoom factor and initial position.

#include "splashkit.h"
// Zoom scale factor
const int ZOOM_SCALE = 5;
// Initial camera position at (0,0)
point_2d camera_pos = { 0, 0 };
const int BOX_SIZE = 100;
bool zoomed_in = false;
int main()
{
// Open window with specified dimensions
open_window("Camera Zooming Example", 500, 550);
// Load bitmap for the grid of colors
load_bitmap("color_grid", "color-grid.png");
}

Here, we open a 500x550 window using OpenWindow and load a bitmap using LoadBitmap. The CameraPosition is initially set to (0, 0).

Now we’ll add functionality to zoom into the clicked area. When a user clicks within the window, the camera zooms into the grid, centered around the clicked box.

while (!window_close_requested("Camera Zooming Example"))
{
process_events();
// Zoom In
if (mouse_clicked(LEFT_BUTTON) && !zoomed_in)
{
int clicked_box_x = (int)(mouse_x()) / BOX_SIZE;
int clicked_box_y = (int)(mouse_y()) / BOX_SIZE;
// Update the camera position to center on the clicked box
camera_pos.x = (clicked_box_x * BOX_SIZE - BOX_SIZE * 2) * ZOOM_SCALE;
camera_pos.y = (clicked_box_y * BOX_SIZE - BOX_SIZE * 2) * ZOOM_SCALE;
set_camera_position(camera_pos);
zoomed_in = true;
}
}

Here, we use Mouse Clicked to detect when the user clicks inside the window. If the left mouse button is clicked and the camera is not already zoomed in, we calculate the coordinates of the clicked box by dividing the mouse’s position by “BOX SIZE”. Once we know which box was clicked, we update the camera position. The function SetCameraPosition is used to reposition the camera so that the clicked box is centered in the view. The camera’s position is updated based on the new camera position values, which take into account both the clicked box and the zoom factor. This zooms into the selected area by moving the camera and enlarging the view, creating the zoom-in effect.

When the Escape key is pressed, the camera will reset to its original position, showing the entire grid again.

// If Escape key is pressed, return to the full grid view
if (key_typed(ESCAPE_KEY) && zoomed_in)
{
camera_pos.x = 0;
camera_pos.y = 0;
set_camera_position(camera_pos);
zoomed_in = false;
}

Here, the Key Typed function is used to detect whether the “ESCAPE KEY” was pressed. When the “ESCAPE KEY” is pressed and the view is zoomed in, the camera’s position is reset by setting camera position values to 0. This moves the camera back to the original full grid view. The function SetCameraPosition is then called to update the camera position.

Drawing the Bitmap and Refreshing the Screen

Section titled “Drawing the Bitmap and Refreshing the Screen”

In this final part, we draw the bitmap and refresh the screen. If zooming is active, the bitmap is scaled according to the ZOOM_SCALE.

// Draw the grid with or without zoom
clear_screen();
if (!zoomed_in)
{
draw_bitmap("color_grid", 0, 0, option_defaults());
}
else
{
draw_bitmap("color_grid", 0, 0, option_scale_bmp(ZOOM_SCALE, ZOOM_SCALE));
}
fill_rectangle(color_light_gray(), 0, 500, screen_width(), 50, option_to_screen());
draw_text("Click a box to zoom in. Press ESC to return to grid", color_black(), 10, screen_height() - 30, option_to_screen());
refresh_screen();

In this code, the Draw Bitmap function displays the grid with optional zooming, using Option Defaults for default settings. The Option Scale Bmp function scales the bitmap based on the zoom factor. The Option To Screen function is used to ensure that additional elements like rectangles and text are drawn with the correct positioning and transformations based on the current screen settings. After drawing the bitmap, we refresh the screen using Refresh Screen.

This example illustrates a dynamic camera system that follows the target position within a large bitmap grid. The camera initially centers on the bitmap’s middle. When the user clicks within the window, the camera’s target position updates to the mouse click location, causing the camera to move smoothly towards this new position. Additionally, scrolling with the mouse wheel allows for manual camera adjustments. The bitmap is drawn in the window, and the camera movement is continuously updated based on user input.

#include "splashkit.h"
// Speed of camera movement
const int SPEED = 4;
int main()
{
// Open a window
open_window("Camera Movement Example", 800, 600);
// Load a 5x5 colored grid bitmap
bitmap grid = load_bitmap("grid", "color-grid-5000.png");
// Set the initial camera position to center the bitmap
set_camera_position(
point_at(bitmap_width(grid) / 2 - screen_center().x,
bitmap_height(grid) / 2 - screen_center().y)
);
// Target position where the camera will move towards
point_2d target = point_at(bitmap_width(grid) / 2, bitmap_height(grid) / 2);
// Main game loop
while (!window_close_requested("Camera Movement Example"))
{
process_events();
// Set target Camera position to be centered on Mouse Position
if (mouse_clicked(LEFT_BUTTON))
{
target = to_world(mouse_position());
}
// Move camera to center target position on screen
if (camera_x() < target.x - screen_width() / 2)
{
move_camera_by(SPEED, 0);
}
if (camera_x() + screen_width() > target.x + screen_width() / 2)
{
move_camera_by(-SPEED, 0);
}
if (camera_y() < target.y - screen_height() / 2)
{
move_camera_by(0, SPEED);
}
if (camera_y() + screen_height() > target.y + screen_height() / 2)
{
move_camera_by(0, -SPEED);
}
// Allow scroll movement
if (mouse_wheel_scroll().x < 0 || mouse_wheel_scroll().x > 0 || mouse_wheel_scroll().y < 0 || mouse_wheel_scroll().y > 0 )
{
move_camera_by(SPEED * mouse_wheel_scroll().x, 0);
move_camera_by(0, SPEED * -mouse_wheel_scroll().y);
target = screen_center();
}
// Draw Bitmap
clear_screen(color_black());
draw_bitmap(grid, 0, 0);
refresh_screen(60);
}
close_all_windows();
return 0;
}

Let’s break this code into smaller sections and analyze each part.

We start by defining the speed of the camera movement, opening the window, and loading the bitmap that represents the game world. We then position the camera at the center of the bitmap.

#include "splashkit.h"
// Speed of camera movement
const int SPEED = 4;
int main()
{
// Open a window
open_window("Camera Movement Example", 800, 600);
// Load a 5x5 colored grid bitmap
bitmap grid = load_bitmap("grid", "color-grid-5000.png");
// Set the initial camera position to center the bitmap
set_camera_position(
point_at(bitmap_width(grid) / 2 - screen_center().x,
bitmap_height(grid) / 2 - screen_center().y)
);
}

In this part, the OpenWindow function creates an 800x600 window, and the LoadBitmap function loads a large 5x5 grid bitmap. The SetCameraPosition function centers the camera on the middle of the bitmap by adjusting the camera’s position based on the bitmap’s width and height.

Defining the Target Position for Camera Movement

Section titled “Defining the Target Position for Camera Movement”

Next, we define a target position (target) where the camera will move when the user clicks inside the window.

// Target position where the camera will move towards
point_2d target = point_at(bitmap_width(grid) / 2, bitmap_height(grid) / 2);

Here, we set the initial target to the center of the bitmap, which the camera will follow when the user interacts with the game world.

In the main game loop, we listen for user inputs. If the left mouse button is clicked, the target position is updated to the mouse click’s world position.

// Main game loop
while (!window_close_requested("Camera Movement Example"))
{
process_events();
// Set target Camera position to be centered on Mouse Position
if (mouse_clicked(LEFT_BUTTON))
{
target = to_world(mouse_position());
}
}

In this part of code, the MouseClicked function detects when the left mouse button is clicked. When clicked, the mouse’s screen position is changed to a position in the game world. This updates the target to the mouse’s clicked location.

Next, the camera moves smoothly toward the target by adjusting its position horizontally and vertically until the target is centered on the screen.

// Move camera to center target position on screen
if (camera_x() < target.x - screen_width() / 2)
{
move_camera_by(SPEED, 0);
}
if (camera_x() + screen_width() > target.x + screen_width() / 2)
{
move_camera_by(-SPEED, 0);
}
if (camera_y() < target.y - screen_height() / 2)
{
move_camera_by(0, SPEED);
}
if (camera_y() + screen_height() > target.y + screen_height() / 2)
{
move_camera_by(0, -SPEED);
}

This section checks if the camera’s current position (CameraX and CameraY) is not centered on the target. The Screen Width and Screen Height functions are used to calculate half the screen’s dimensions to ensure the target is centered. If the camera is off-center relative to the target, MoveCameraBy function moves the camera incrementally at the defined SPEED to adjust the position. This ensures that the target remains within the center of the visible screen.

Handling Camera Movement with Mouse Scroll

Section titled “Handling Camera Movement with Mouse Scroll”

We also allow the camera to move manually by using the mouse wheel. Scrolling the mouse wheel in any direction will move the camera in small steps.

// Allow scroll movement
if (mouse_wheel_scroll().x < 0 || mouse_wheel_scroll().x > 0 || mouse_wheel_scroll().y < 0 || mouse_wheel_scroll().y > 0)
{
move_camera_by(SPEED * mouse_wheel_scroll().x, 0);
move_camera_by(0, SPEED * -mouse_wheel_scroll().y);
target = screen_center();
}

This section detects scrolling through the Mouse Wheel Scroll function. If the user scrolls in any direction, the camera moves vertically based on the scroll input. The target is reset to the center of the screen after scrolling.

We have already discussed how to draw the bitmap and refresh the screen in the “Zooming into a Colored Grid” example above. The process remains the same here, where we clear the screen, draw the bitmap, and refresh the display to reflect any changes.

This tutorial covered the basics of dynamic camera control in SplashKit using SetCameraPosition and MoveCameraBy functions. These examples showed how to zoom into specific areas and how to make the camera movements with mouse clicks and mouse wheel scrolls, both of which are key techniques for creating more interactive and immersive games. You can now apply these concepts to your own projects, enhancing the way your games interact with the camera and the player.