Getting Started with 2D Games Using Arcade Library (Part x): Using the Camera
This time, we’ll use a camera to make it follow the player.
By using a camera, you can take advantage of a much wider game world.
1. Creating Two Cameras
A camera object defines the visible area of the game world.
In the constructor of GameView in main.py, we prepare two camera objects:
-
self.camerato follow the player and other world objects -
self.camera_guito keep GUI elements fixed on the screen
# main.py (excerpt)
# Camera
self.camera = arcade.Camera2D() # Camera for the player
self.camera_gui = arcade.Camera2D() # Fixed camera for GUI
2. Making the Camera Follow the Player
Next, in the on_update() method, we implement logic that makes the camera follow the player’s position.
By adjusting the last value (0.1), you can control how smoothly and quickly the camera moves.
# main.py (excerpt)
# Make the player camera follow the player position
self.camera.position = arcade.math.lerp_2d(
self.camera.position,
self.player.position,
0.1
)
3. Activating the Camera
Finally, in the on_draw() method, we decide which camera to use for drawing.
- Drawing after
self.camera.use()will follow the player - Drawing after
self.camera_gui.use()will stay fixed on the screen
# main.py (excerpt)
def on_draw(self):
self.clear() # Clear
self.camera.use() # Use the player camera
self.players.draw()
self.coins.draw()
self.camera_gui.use() # Use the fixed camera
self.msg_info.draw()
Complete Code
Below is the complete code implementing all the features described so far.
You can copy and run it as-is.
# sprite.py (complete code)
import arcade
import random
import math
class BaseSprite(arcade.Sprite):
def __init__(self, filename, x, y):
super().__init__(filename)
# Position
self.center_x = x
self.center_y = y
# Velocity
self.vx = 0
self.vy = 0
# Animation
self.anim_counter = 0
self.anim_interval = 4
self.anim_index = 0
self.anim_key = ""
self.anim_pause = True
self.anims = {}
def update(self, delta_time):
"""Update"""
self.center_x += self.vx * delta_time
self.center_y += self.vy * delta_time
# Animation
self.update_animation()
def move(self, spd, deg, tag=""):
"""Move sprite"""
rad = deg * math.pi / 180
self.vx = spd * math.cos(rad)
self.vy = spd * math.sin(rad)
if tag:
self.change_animation(tag)
def stop(self):
"""Stop sprite"""
self.vx = 0
self.vy = 0
self.stop_animation()
def update_animation(self):
"""Update animation"""
if self.anim_key not in self.anims:
return
if self.anim_pause:
return
self.anim_counter += 1
if self.anim_counter < self.anim_interval:
return
self.anim_counter = 0
self.anim_index += 1
anim = self.anims[self.anim_key]
if len(anim) <= self.anim_index:
self.anim_index = 0
self.texture = anim[self.anim_index]
def load_animation(self, key, filename, num):
"""Load animation"""
anim = []
for i in range(num):
path = filename.format(i + 1)
anim.append(arcade.load_texture(path))
self.anims[key] = anim
def change_animation(self, key):
"""Change animation"""
if key not in self.anims:
return
self.anim_counter = 0
self.anim_index = 0
self.anim_key = key
self.texture = self.anims[key][0]
self.start_animation()
def start_animation(self):
"""Start animation"""
self.anim_pause = False
def stop_animation(self):
"""Stop animation"""
self.anim_pause = True
class Player(BaseSprite):
def __init__(self, filename, x, y):
super().__init__(filename, x, y)
# Animation
self.load_animation("front", "images/ninja/front_{:02d}.png", 5)
self.load_animation("left", "images/ninja/left_{:02d}.png", 5)
self.load_animation("right", "images/ninja/right_{:02d}.png", 5)
self.load_animation("back", "images/ninja/back_{:02d}.png", 5)
self.change_animation("front")
class Coin(BaseSprite):
def __init__(self, filename, x, y):
super().__init__(filename, x, y)
# Animation
self.load_animation("coin", "images/coin/coin_{:02d}.png", 5)
self.change_animation("coin")
# main.py (complete code)
import arcade
import random
import sprite
PLAYER_SPEED = 90
class GameView(arcade.View):
def __init__(self, window):
super().__init__()
self.window = window
self.w = self.window.width
self.h = self.window.height
self.background_color = arcade.color.PAYNE_GREY
# Camera
self.camera = arcade.Camera2D() # Camera for the player
self.camera_gui = arcade.Camera2D() # Fixed camera
# Player
self.players = arcade.SpriteList()
self.player = sprite.Player(
"images/ninja/front_01.png",
self.w / 2,
self.h / 2
)
self.players.append(self.player)
# Coin
self.coins = arcade.SpriteList()
for _ in range(10):
x = random.random() * self.w
y = random.random() * self.h
coin = sprite.Coin("images/coin/coin_01.png", x, y)
self.coins.append(coin)
# Info text (GUI)
self.msg_info = arcade.Text(
"GAME",
self.w / 2,
self.h - 20,
arcade.color.WHITE,
12,
anchor_x="center",
anchor_y="top"
)
def on_key_press(self, key, modifiers):
# Move (WASD)
if key == arcade.key.W:
self.player.move(PLAYER_SPEED, 90, "back")
if key == arcade.key.A:
self.player.move(PLAYER_SPEED, 180, "left")
if key == arcade.key.S:
self.player.move(PLAYER_SPEED, 270, "front")
if key == arcade.key.D:
self.player.move(PLAYER_SPEED, 0, "right")
def on_key_release(self, key, modifiers):
self.player.stop()
def on_update(self, delta_time):
self.players.update(delta_time)
self.coins.update(delta_time)
# Make the player camera follow the player
self.camera.position = arcade.math.lerp_2d(
self.camera.position,
self.player.position,
0.1
)
def on_draw(self):
self.clear()
self.camera.use()
self.players.draw()
self.coins.draw()
self.camera_gui.use()
self.msg_info.draw()
def main():
"""Main entry point"""
window = arcade.Window(480, 320, "Hello, Arcade!!")
window.show_view(GameView(window))
arcade.run()
if __name__ == "__main__":
main()
The result looks like this:
Closing Thoughts
Thank you for reading!
I hope this series becomes a starting point for your own game development. ޱ(ఠ皿ఠ)ว👍

Top comments (0)