Step 9 - Adding Sound#
Our game has a lot of graphics so far, but doesn’t have any sound yet. Let’s change that! In this chapter we will add a sound when the player collects the coins, as well as when they jump.
Loading and playing sounds in Arcade is very easy. We will only need two functions for this:
In our __init__
function, we will add these two lines to load our coin collection and jump sounds.
self.collect_coin_sound = arcade.load_sound(":resources:sounds/coin1.wav")
self.jump_sound = arcade.load_sound(":resources:sounds/jump1.wav")
Note
Why are we not adding empty variables to __init__
and initializing them in setup
like
our other objects?
This is because sounds are a static asset within our game. If we reset the game, the sounds don’t change, so it’s not worth re-loading them.
Now we can play these sounds by simple adding the play_sound
function wherever we want them to occur.
Let’s add one alongside our removal of coins in the on_update
function.
# Within on_update
for coin in coin_hit_list:
coin.remove_from_sprite_lists()
arcade.play_sound(self.collect_coin_sound)
This will play a sound whenever we collect a coin. We can add a jump sound by adding this to our UP
block
for jumping in the on_key_press
function:
# Within on_key_press
if key == arcade.key.UP or key == arcade.key.W:
if self.physics_engine.can_jump():
self.player_sprite.change_y = PLAYER_JUMP_SPEED
arcade.play_sound(self.jump_sound)
Now we will also have a sound whenever we jump.
Documentation for arcade.Sound
Source Code#
1"""
2Platformer Game
3
4python -m arcade.examples.platform_tutorial.09_sound
5"""
6import arcade
7
8# Constants
9SCREEN_WIDTH = 800
10SCREEN_HEIGHT = 600
11SCREEN_TITLE = "Platformer"
12
13# Constants used to scale our sprites from their original size
14TILE_SCALING = 0.5
15COIN_SCALING = 0.5
16
17# Movement speed of player, in pixels per frame
18PLAYER_MOVEMENT_SPEED = 5
19GRAVITY = 1
20PLAYER_JUMP_SPEED = 20
21
22
23class MyGame(arcade.Window):
24 """
25 Main application class.
26 """
27
28 def __init__(self):
29
30 # Call the parent class and set up the window
31 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
32
33 # Variable to hold our texture for our player
34 self.player_texture = None
35
36 # Separate variable that holds the player sprite
37 self.player_sprite = None
38
39 # SpriteList for our player
40 self.player_list = None
41
42 # SpriteList for our boxes and ground
43 # Putting our ground and box Sprites in the same SpriteList
44 # will make it easier to perform collision detection against
45 # them later on. Setting the spatial hash to True will make
46 # collision detection much faster if the objects in this
47 # SpriteList do not move.
48 self.wall_list = None
49
50 # SpriteList for coins the player can collect
51 self.coin_list = None
52
53 # A variable to store our camera object
54 self.camera = None
55
56 # Load sounds
57 self.collect_coin_sound = arcade.load_sound(":resources:sounds/coin1.wav")
58 self.jump_sound = arcade.load_sound(":resources:sounds/jump1.wav")
59
60 def setup(self):
61 """Set up the game here. Call this function to restart the game."""
62 self.player_texture = arcade.load_texture(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png")
63
64 self.player_sprite = arcade.Sprite(self.player_texture)
65 self.player_sprite.center_x = 64
66 self.player_sprite.center_y = 128
67
68 self.player_list = arcade.SpriteList()
69 self.player_list.append(self.player_sprite)
70
71 self.wall_list = arcade.SpriteList(use_spatial_hash=True)
72 self.coin_list = arcade.SpriteList(use_spatial_hash=True)
73
74 # Create the ground
75 # This shows using a loop to place multiple sprites horizontally
76 for x in range(0, 1250, 64):
77 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=TILE_SCALING)
78 wall.center_x = x
79 wall.center_y = 32
80 self.wall_list.append(wall)
81
82 # Put some crates on the ground
83 # This shows using a coordinate list to place sprites
84 coordinate_list = [[512, 96], [256, 96], [768, 96]]
85
86 for coordinate in coordinate_list:
87 # Add a crate on the ground
88 wall = arcade.Sprite(
89 ":resources:images/tiles/boxCrate_double.png", scale=TILE_SCALING
90 )
91 wall.position = coordinate
92 self.wall_list.append(wall)
93
94 # Add coins to the world
95 for x in range(128, 1250, 256):
96 coin = arcade.Sprite(":resources:images/items/coinGold.png", scale=COIN_SCALING)
97 coin.center_x = x
98 coin.center_y = 96
99 self.coin_list.append(coin)
100
101 # Create a Platformer Physics Engine, this will handle moving our
102 # player as well as collisions between the player sprite and
103 # whatever SpriteList we specify for the walls.
104 # It is important to supply static to the walls parameter. There is a
105 # platforms parameter that is intended for moving platforms.
106 # If a platform is supposed to move, and is added to the walls list,
107 # it will not be moved.
108 self.physics_engine = arcade.PhysicsEnginePlatformer(
109 self.player_sprite, walls=self.wall_list, gravity_constant=GRAVITY
110 )
111
112 # Initialize our camera, setting a viewport the size of our window.
113 self.camera = arcade.SimpleCamera(viewport=(0, 0, self.width, self.height))
114
115 self.background_color = arcade.csscolor.CORNFLOWER_BLUE
116
117 def on_draw(self):
118 """Render the screen."""
119
120 # Clear the screen to the background color
121 self.clear()
122
123 # Activate our camera before drawing
124 self.camera.use()
125
126 # Draw our sprites
127 self.player_list.draw()
128 self.wall_list.draw()
129 self.coin_list.draw()
130
131 def on_update(self, delta_time):
132 """Movement and Game Logic"""
133
134 # Move the player using our physics engine
135 self.physics_engine.update()
136
137 # See if we hit any coins
138 coin_hit_list = arcade.check_for_collision_with_list(
139 self.player_sprite, self.coin_list
140 )
141
142 # Loop through each coin we hit (if any) and remove it
143 for coin in coin_hit_list:
144 # Remove the coin
145 coin.remove_from_sprite_lists()
146 arcade.play_sound(self.collect_coin_sound)
147
148 # Center our camera on the player
149 self.camera.center(self.player_sprite.position)
150
151 def on_key_press(self, key, modifiers):
152 """Called whenever a key is pressed."""
153
154 if key == arcade.key.ESCAPE:
155 self.setup()
156
157 if key == arcade.key.UP or key == arcade.key.W:
158 if self.physics_engine.can_jump():
159 self.player_sprite.change_y = PLAYER_JUMP_SPEED
160 arcade.play_sound(self.jump_sound)
161
162 if key == arcade.key.LEFT or key == arcade.key.A:
163 self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
164 elif key == arcade.key.RIGHT or key == arcade.key.D:
165 self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
166
167 def on_key_release(self, key, modifiers):
168 """Called whenever a key is released."""
169
170 if key == arcade.key.LEFT or key == arcade.key.A:
171 self.player_sprite.change_x = 0
172 elif key == arcade.key.RIGHT or key == arcade.key.D:
173 self.player_sprite.change_x = 0
174
175
176def main():
177 """Main function"""
178 window = MyGame()
179 window.setup()
180 arcade.run()
181
182
183if __name__ == "__main__":
184 main()
Run This Chapter#
python -m arcade.examples.platform_tutorial.09_sound