DEV Community

Kajiru
Kajiru

Posted on

Getting Started with 2D Games Using Arcade Library (Part 7): Collecting Coins

Let’s Collect Coins

In this chapter, we’ll place many coins on the screen and remove them using collision detection.

1. Prepare the Coin Image

Inside the images folder, create a new coin folder

(separating folders by image type), and place the following image inside it.

(Ninjas and coins go hand in hand!)

Image File name
 coin_01.png

The folder structure should look like this:

# Folder structure
working_folder/
 ├ main.py
 ├ sprite.py
 └ images/
    ├ bg_temple.png
    ├ ninja/
    └ coin/      # Folder for coin images
       └ coin_01.png
Enter fullscreen mode Exit fullscreen mode

2. Define the Coin Sprite

In sprite.py, define a new class called Coin.

Just like the Player class, this class should inherit from BaseSprite.

# sprite.py (excerpt)
class Coin(BaseSprite):

    def __init__(self, filename, x, y):
        super().__init__(filename, x, y)
Enter fullscreen mode Exit fullscreen mode

3. Import the Random Module

In main.py, import the random module.
We’ll use it later to place coins at random positions.

# main.py (excerpt)
import random
Enter fullscreen mode Exit fullscreen mode

4. Create Coin Sprites

In the constructor of GameView, create coin sprites using the Coin class.

As before, we use arcade.SpriteList to manage and draw multiple sprites at once.

# main.py (excerpt)
# Coin sprites
self.coins = arcade.SpriteList()
for i in range(10):
    x = random.random() * self.w  # random x position
    y = random.random() * self.h  # random y position
    coin = sprite.Coin(
        "images/coin/coin_01.png",
        x=x, y=y
    )
    self.coins.append(coin)
Enter fullscreen mode Exit fullscreen mode

Here, we create 10 coins using a loop.

The random.random() function returns a floating-point number
between 0.0 (inclusive) and 1.0 (exclusive).

By multiplying it by the screen size, we can generate
a random position inside the screen.

(The coins may appear right at the edges of the screen,

but we’ll ignore that for now.)

5. Update the Coin Sprites

In the on_update() method of GameView,
update the coin list all at once.

Coins don’t move yet, but this is where you could update
their positions if needed.

# main.py (excerpt)
self.coins.update(delta_time)  # update coin list
Enter fullscreen mode Exit fullscreen mode

6. Draw the Coin Sprites

In the on_draw() method of GameView,
draw the coin list all at once.

(You’re getting the hang of this, right?)

# main.py (excerpt)
self.coins.draw()  # draw coin list
Enter fullscreen mode Exit fullscreen mode

7. Collision Detection Between Player and Coins

Finally, in the on_update() method of GameView,
implement collision detection between the player and the coin list.

# main.py (excerpt)
# Collision check: player x coin list
hit_coins = arcade.check_for_collision_with_list(
    self.player,
    self.coins
)

# Remove collided coins from the list
for coin in hit_coins:
    coin.remove_from_sprite_lists()
Enter fullscreen mode Exit fullscreen mode

The check_for_collision_with_list() function
returns a list of sprites that collided with the sprite
passed as the first argument.

After detecting collisions, we iterate over hit_coins
and remove each coin using remove_from_sprite_lists().

Complete Code

Below is the complete code with all features implemented so far.
You can copy and run it as-is.

# sprite.py (complete code)
import arcade
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

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

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

    def stop(self):
        """ Stop Sprite """
        self.vx = 0
        self.vy = 0

class Player(BaseSprite):

    def __init__(self, filename, x, y):
        super().__init__(filename, x, y)

class Coin(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
import random

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)

        # Coin sprites
        self.coins = arcade.SpriteList()
        for i in range(10):
            x = random.random() * self.w  # random x position
            y = random.random() * self.h  # random y position
            coin = sprite.Coin(
                "images/coin/coin_01.png",
                x=x, y=y
            )
            self.coins.append(coin)

    def on_key_press(self, key, key_modifiers):
        # Move (WASD)
        if key == arcade.key.W: self.player.move(90, 90)
        if key == arcade.key.A: self.player.move(90, 180)
        if key == arcade.key.S: self.player.move(90, 270)
        if key == arcade.key.D: self.player.move(90, 0)

    def on_key_release(self, key, key_modifiers):
        self.player.stop()  # stop

    def on_update(self, delta_time):
        self.players.update(delta_time)
        self.coins.update(delta_time)  # update coin list

        # Collision check: player x coin list
        hit_coins = arcade.check_for_collision_with_list(
            self.player,
            self.coins
        )
        # Remove collided coins
        for coin in hit_coins:
            coin.remove_from_sprite_lists()

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

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 the program, the result will look like this:

Coming Up Next...

Thank you for reading.
The next chapter is titled “Let’s Add Animation.”

Stay tuned 👍

Top comments (0)