Switching Animations
This time, we’ll look at a sample implementation.
The player’s animation changes depending on the movement direction.
Adding Ninja Images
Add the following images into the ninja folder under the images directory.
1. Back View
| Image | File Name | Image | File Name | Image | File Name |
|---|---|---|---|---|---|
| back_01.png | back_02.png | back_03.png | |||
| back_04.png | back_05.png |
2. Running to the Left
| Image | File Name | Image | File Name | Image | File Name |
|---|---|---|---|---|---|
| left_01.png | left_02.png | left_03.png | |||
| left_04.png | left_05.png |
3. Running to the Right
| Image | File Name | Image | File Name | Image | File Name |
|---|---|---|---|---|---|
| right_01.png | right_02.png | right_03.png | |||
| right_04.png | right_05.png |
The folder structure should look like this:
# Folder structure
working_directory/
├ main.py
├ sprite.py
└ images/
├ bg_temple.png
├ coin/
└ ninja/ # Folder for ninja images
├ front_01.png
├ front_02.png
├ front_03.png
├ front_04.png
├ front_05.png
├ back_01.png
├ back_02.png
├ back_03.png
├ back_04.png
├ back_05.png
├ left_01.png
├ left_02.png
├ left_03.png
├ left_04.png
├ left_05.png
├ right_01.png
├ right_02.png
├ right_03.png
├ right_04.png
└ right_05.png
Complete Code
Below is the complete code implementing all features 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
# Animation
self.anim_counter = 0
self.anim_interval = 4
self.anim_index = 0
self.anim_key = "" # current animation key
self.anim_pause = True # whether animation is paused
self.anims = {} # animation dictionary
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)
# Register animations
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)
# Register animation
self.load_animation("coin", "images/coin/coin_{:02d}.png", 5)
self.change_animation("coin")
# 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 sprite
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 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)
# Coin sprites
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=x, y=y)
self.coins.append(coin)
# Score
self.score = 0
self.score_text = arcade.Text(
f"SCORE: {self.score}",
self.w / 2,
self.h - 20,
arcade.color.BLACK,
16,
anchor_x="center",
anchor_y="top"
)
# Sound
self.se_coin = arcade.Sound("sounds/se_coin.ogg")
def on_key_press(self, key, modifiers):
# Move (WASD)
if key == arcade.key.W:
self.player.move(90, 90, "back") # up
if key == arcade.key.A:
self.player.move(90, 180, "left") # left
if key == arcade.key.S:
self.player.move(90, 270, "front") # down
if key == arcade.key.D:
self.player.move(90, 0, "right") # 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)
# Player x coin collision
hit_coins = arcade.check_for_collision_with_list(
self.player,
self.coins
)
for coin in hit_coins:
coin.remove_from_sprite_lists()
# Score
self.score += 1
self.score_text.text = f"SCORE: {self.score}"
# Play sound
arcade.play_sound(self.se_coin)
def on_draw(self):
self.clear()
self.backgrounds.draw()
self.players.draw()
self.coins.draw()
self.score_text.draw()
def main():
"""Main entry point"""
window = arcade.Window(480, 320, "Hello, Arcade!!")
game = GameView(window)
window.show_view(game)
arcade.run()
if __name__ == "__main__":
main()
The result looks like this:
Closing Thoughts
Thank you for reading!
I hope this series inspires you to start making your own games. ޱ(ఠ皿ఠ)ว👍

Top comments (0)