DEV Community

Kajiru
Kajiru

Posted on

Getting Started with 2D Games Using Arcade Library (Part 5): Moving the Player

Getting Started with 2D Games Using Arcade Library (Part 5): Moving the Player

Let’s Move the Player

In this chapter, we won’t use keyboard input yet.
Instead, we’ll try moving the player directly from the program.

1. Improve the Player Sprite

First, import the math module.
This module is one of the standard libraries that makes mathematical calculations easy.

# sprite.py (excerpt)
import math  # module for mathematical calculations
Enter fullscreen mode Exit fullscreen mode

2. Add Variables to Store Movement Speed

From here on, we’ll add new functionality to the base sprite class, BaseSprite.

In the constructor, add:

  • vx to store velocity in the x direction
  • vy to store velocity in the y direction
# sprite.py (added to BaseSprite)
def __init__(self, filename, x, y):
    super().__init__(filename)
    # Position
    self.center_x = x
    self.center_y = y
    # Velocity
    self.vx = 0  # velocity in x direction
    self.vy = 0  # velocity in y direction
Enter fullscreen mode Exit fullscreen mode

3. Apply Velocity to Position in the Update Method

Add an update() method and implement logic to apply velocity to the position.

# sprite.py (added to BaseSprite)
def update(self, delta_time):
    """ Update """
    self.center_x += self.vx * delta_time  # update x position
    self.center_y += self.vy * delta_time  # update y position
Enter fullscreen mode Exit fullscreen mode

Here, we add vx and vy multiplied by delta_time to the x and y coordinates.
delta_time represents the elapsed time since the previous frame.

In other words, after about one second, the sprite will move a distance equal to vx and vy.
(By running this every frame, the position changes little by little over time.)

4. Prepare a Method to Start Moving

Add a move() method to set movement speed and direction.
This method takes speed and angle as arguments.

  • 0°: right
  • 90°: up
  • 180°: left
  • 270°: down
# sprite.py (added to BaseSprite)
def move(self, spd, deg):
    """ Move Sprite """
    rad = deg * math.pi / 180  # convert degrees to radians
    self.vx = spd * math.cos(rad)  # velocity in x direction
    self.vy = spd * math.sin(rad)  # velocity in y direction
Enter fullscreen mode Exit fullscreen mode

In the math module, math.pi represents π (pi).
We use it to convert degrees (0°–360°) into radians (0–2π).

Next, we multiply the speed (spd) by cos to calculate the x-direction velocity
and by sin to calculate the y-direction velocity.
(cos and sin only appear here, so you don’t need to dig too deeply into them.)

5. Prepare a Method to Stop Movement

Add a stop() method to stop the sprite.
This method simply sets vx and vy to 0.

# sprite.py (added to BaseSprite)
def stop(self):
    """ Stop Sprite """
    self.vx = 0  # set x velocity to 0
    self.vy = 0  # set y velocity to 0
Enter fullscreen mode Exit fullscreen mode

6. Test the Movement

Finally, let’s test the behavior in main.py.
Call player.move() with speed 90 and angle 30.

# main.py (excerpt)
# player sprite
self.players = arcade.SpriteList()
self.player = sprite.Player(
    "images/ninja/front_01.png",
    x=self.w / 2,
    y=self.h / 2
)
self.players.append(self.player)

self.player.move(90, 30)  # try moving the player
Enter fullscreen mode Exit fullscreen mode

In this case, the player moves at 90 pixels per second in the 30° upper-right direction.
Feel free to try other values as well.

Complete Code

Below is the complete code implementing everything so far.
You can copy and run it as-is.

# sprite.py (complete code)
import arcade
import math  # module for mathematical calculations

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  # velocity in x direction
        self.vy = 0  # velocity in y direction

    def update(self, delta_time):
        """ Update """
        self.center_x += self.vx * delta_time  # update x position
        self.center_y += self.vy * delta_time  # update y position

    def move(self, spd, deg):
        """ Move Sprite """
        rad = deg * math.pi / 180  # convert degrees to radians
        self.vx = spd * math.cos(rad)  # velocity in x direction
        self.vy = spd * math.sin(rad)  # velocity in y direction

    def stop(self):
        """ Stop Sprite """
        self.vx = 0  # set x velocity to 0
        self.vy = 0  # set y velocity to 0

class Player(BaseSprite):

    def __init__(self, filename, x, y):
        super().__init__(filename, x, y)
Enter fullscreen mode Exit fullscreen mode
# main.py (complete code)
import arcade
import sprite

class GameView(arcade.View):

    def __init__(self, window):
        super().__init__()
        self.window = window
        self.w = self.window.width
        self.h = self.window.height

        # background color
        self.background_color = arcade.color.PAYNE_GREY

        # background sprites
        self.backgrounds = arcade.SpriteList()
        bkg = arcade.Sprite("images/bg_temple.png")
        bkg.center_x = self.w / 2
        bkg.center_y = self.h / 2
        self.backgrounds.append(bkg)

        # player sprites
        self.players = arcade.SpriteList()
        self.player = sprite.Player(
            "images/ninja/front_01.png",
            x=self.w / 2,
            y=self.h / 2
        )
        self.players.append(self.player)

        self.player.move(90, 30)  # try moving the player

    def on_key_press(self, key, key_modifiers):
        pass

    def on_key_release(self, key, key_modifiers):
        pass

    def on_update(self, delta_time):
        self.players.update(delta_time)

    def on_draw(self):
        self.clear()  # Clear
        self.backgrounds.draw()
        self.players.draw()

def main():
    """ main process """
    window = arcade.Window(480, 320, "Hello, Arcade!!")
    game = GameView(window)
    window.show_view(game)
    arcade.run()

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

When you run it, the result will look like this:

Coming Up Next...

Thank you for reading.
The next chapter is titled “Let’s Control the Player.”
Stay tuned 👍

Top comments (0)