Getting Started with 2D Games Using Pyxel (Part 7): Control the Character

Published: (January 10, 2026 at 10:00 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Control the Character

In this chapter we detect when the Space key is pressed and flip the player’s movement direction left ↔ right. This gives a stronger sense of direct control.

Set Initial Movement Direction

In the Game constructor we randomly choose the ship’s initial direction (right = 0° or left = 180°) and set its velocity.

# main.py – inside Game.__init__()
import random

# Randomly choose left or right
deg = 0 if random.random() < 0.5 else 180
self.ship.move(SHIP_SPD, deg)

Flip X Method

Add a flip_x() method to BaseSprite that reverses the x‑axis velocity.

# sprite.py – added to BaseSprite class
def flip_x(self):
    """Flip movement in the x direction"""
    self.vx *= -1

Calling flip_x() changes the direction:

  • Right → Left
  • Left → Right

Handle Keyboard Input

Create a control_ship() method in the Game class. It uses pyxel.btnp() to detect the exact moment the Space key is pressed and then flips the ship’s direction.

# main.py – added to Game class
def control_ship(self):
    """Handle input"""
    if pyxel.btnp(pyxel.KEY_SPACE):
        self.ship.flip_x()  # Reverse movement

Each press of Space toggles the ship’s horizontal movement.

Screen‑Wrap Logic

When the ship leaves the screen we move it to the opposite side. The reusable overlap_spr() method works for any sprite (e.g., future asteroids).

# main.py – added to Game class
def overlap_spr(self, spr):
    """Wrap sprite around screen edges"""
    if spr.x < -spr.w:
        spr.x = W
        return
    if W < spr.x:
        spr.x = -spr.w
        return
    if spr.y < -spr.h:
        spr.y = H
        return
    if H < spr.y:
        spr.y = -spr.h
        return

Complete Code

Below is the full implementation of the features described above.

# sprite.py
import pyxel
import math
import random

class BaseSprite:
    def __init__(self, x, y, w=8, h=8):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.vx = 0
        self.vy = 0

    def update(self):
        self.x += self.vx
        self.y += self.vy

    def draw(self):
        pass  # Implemented in subclasses

    def move(self, spd, deg):
        rad = deg * math.pi / 180
        self.vx = spd * math.cos(rad)
        self.vy = spd * math.sin(rad)

    def flip_x(self):
        """Flip movement in the x direction"""
        self.vx *= -1

class ShipSprite(BaseSprite):
    def __init__(self, x, y):
        super().__init__(x, y)

    def draw(self):
        pyxel.blt(self.x, self.y, 0, 0, 0, self.w, self.h, 0)
# main.py
import pyxel
import random
import sprite

W, H = 160, 120
SHIP_SPD = 1.4  # Player speed

class Game:
    def __init__(self):
        self.score = 0
        self.ship = sprite.ShipSprite(W / 2, H - 40)

        # Random initial direction
        deg = 0 if random.random() < 0.5 else 180
        self.ship.move(SHIP_SPD, deg)

        pyxel.init(W, H, title="Hello, Pyxel!!")
        pyxel.load("shooter.pyxres")
        pyxel.run(self.update, self.draw)

    def update(self):
        self.ship.update()
        self.control_ship()
        self.overlap_spr(self.ship)

    def draw(self):
        pyxel.cls(0)
        pyxel.text(10, 10, f"SCORE:{self.score:04}", 12)
        self.ship.draw()

    def control_ship(self):
        if pyxel.btnp(pyxel.KEY_SPACE):
            self.ship.flip_x()  # Reverse movement

    def overlap_spr(self, spr):
        if spr.x < -spr.w:
            spr.x = W
            return
        if W < spr.x:
            spr.x = -spr.w
            return
        if spr.y < -spr.h:
            spr.y = H
            return
        if H < spr.y:
            spr.y = -spr.h
            return

def main():
    Game()

if __name__ == "__main__":
    main()

Running the game shows the ship moving horizontally; pressing Space flips its direction, and it wraps around the screen edges.

In the next chapter we’ll cover “Let’s Spawn Asteroids.”

Back to Blog

Related posts

Read more »