Moving Characters
Now it’s time to finally move the sprite we created in the previous chapter.
In this chapter, we will give sprites a concept of velocity and build a simple movement system.
The complete code is shown at the end of this article.
1. Improving the Sprite Class
First, we enhance the common base class BaseSprite.
In its constructor, we add two new member variables: vx and vy.
These variables are added to the sprite’s coordinates x and y during the update() step.
By doing this, the character’s position changes little by little,
which makes it appear to move on the game screen.
We also add a new method called move().
As the name suggests, this method starts the movement.
It takes speed and angle as arguments:
- The horizontal component (X direction) is calculated with
math.cos()and assigned tovx - The vertical component (Y direction) is calculated with
math.sin()and assigned tovy
(You don’t need to fully understand the math behind this yet—it’s totally fine!)
# sprite.py (excerpt)
class BaseSprite:
def __init__(self, x, y, w=8, h=8):
""" Constructor """
self.x = x
self.y = y
self.w = w
self.h = h
self.vx = 0 # Velocity (X direction)
self.vy = 0 # Velocity (Y direction)
def update(self):
""" Update logic """
self.x += self.vx # Move in X direction
self.y += self.vy # Move in Y direction
def draw(self):
""" Drawing logic (implemented in subclasses) """
pass
def move(self, spd, deg):
""" Start movement """
rad = deg * math.pi / 180
self.vx = spd * math.cos(rad) # X velocity
self.vy = spd * math.sin(rad) # Y velocity
2. Defining Constants
Next, add a constant to main.py that represents the player’s movement speed.
Defining values as constants makes them much easier to adjust later.
# main.py (add constants)
SHIP_SPD = 1.4 # Player speed
3. Testing Sprite Movement
Now let’s check whether the sprite actually moves.
Inside the constructor of the Game class, we give the player a movement command for testing.
# main.py (added to the Game class constructor)
# Test movement (toward the upper-left)
self.ship.move(SHIP_SPD, 220)
Try changing the angle value and confirm that the movement direction changes as well.
Complete Code
Below is the complete code with all features implemented so far.
# sprite.py
import pyxel
import math
import random
class BaseSprite:
def __init__(self, x, y, w=8, h=8):
""" Constructor """
self.x = x
self.y = y
self.w = w
self.h = h
self.vx = 0 # Velocity (X direction)
self.vy = 0 # Velocity (Y direction)
def update(self):
""" Update logic """
self.x += self.vx # Move in X direction
self.y += self.vy # Move in Y direction
def draw(self):
""" Drawing logic (implemented in subclasses) """
pass
def move(self, spd, deg):
""" Start movement """
rad = deg * math.pi / 180
self.vx = spd * math.cos(rad) # X velocity
self.vy = spd * math.sin(rad) # Y velocity
class ShipSprite(BaseSprite):
def __init__(self, x, y):
""" Constructor """
super().__init__(x, y)
def draw(self):
""" Drawing logic """
pyxel.blt(
self.x, self.y, 0,
0, 0,
self.w, self.h, 0
) # Ship
# main.py
import pyxel
import math
import random
import sprite
W, H = 160, 120
SHIP_SPD = 1.4 # Player speed
# Game
class Game:
def __init__(self):
""" Constructor """
# Initialize score
self.score = 0
# Initialize player
self.ship = sprite.ShipSprite(W / 2, H - 40)
# Test movement (toward the upper-left)
self.ship.move(SHIP_SPD, 220)
# Start Pyxel
pyxel.init(W, H, title="Hello, Pyxel!!")
pyxel.load("shooter.pyxres")
pyxel.run(self.update, self.draw)
def update(self):
""" Update logic """
# Update player
self.ship.update()
def draw(self):
""" Drawing logic """
pyxel.cls(0)
# Draw score
pyxel.text(
10, 10,
"SCORE:{:04}".format(self.score),
12
)
# Draw player
self.ship.draw()
def main():
""" Main entry point """
Game()
if __name__ == "__main__":
main()
When you run this program, the result will look like this:
Coming Up Next...
Thank you for reading this chapter.
The next title is “Controlling the Character.”
See you next time!!

Top comments (0)