1"""
2Starting Template
3
4Once you have learned how to use classes, you can begin your program with this
5template.
6
7If Python and Arcade are installed, this example can be run from the command line with:
8python -m arcade.examples.sound_demo
9
10The top button is to play a music track.
11The 3 rows of buttons are arranged such that the audio is panned in the direction of the button,
12and the volume increases as you go down the column.
13
14Left click a button to play a sound.
15If a sound is playing right click to increase volume, middle click to decrease.
16"""
17import typing
18
19import arcade
20
21SCREEN_WIDTH = 800
22SCREEN_HEIGHT = 600
23SCREEN_TITLE = "Starting Template"
24BUTTON_SIZE = 30
25
26
27class SoundButton(arcade.SpriteSolidColor):
28 """ Button, click-for-sound """
29
30 def __init__(self, sound_file, pan, volume):
31 super().__init__(BUTTON_SIZE, BUTTON_SIZE, arcade.color.WHITE)
32 self.sound = arcade.Sound(sound_file)
33 self.pan = pan
34 self.volume = volume
35
36 def play(self):
37 """ Play """
38 self.sound.play(pan=self.pan, volume=self.volume)
39
40
41class AudioStreamButton(arcade.SpriteSolidColor):
42 """ Button, click-for-streaming-sound """
43
44 def __init__(self, sound_file, pan, volume):
45 super().__init__(BUTTON_SIZE, BUTTON_SIZE, arcade.color.WHITE)
46 self.sound = arcade.Sound(sound_file, streaming=True)
47 self.pan = pan
48 self.volume = volume
49
50 def play(self):
51 """ Play """
52 self.sound.play(volume=self.volume, pan=self.pan)
53
54 def volume_up(self):
55 vol = self.sound.get_volume()
56 self.sound.set_volume(vol + 0.1)
57 print(f"Volume: {self.sound.get_volume()}")
58
59 def volume_down(self):
60 vol = self.sound.get_volume()
61 self.sound.set_volume(vol - 0.1)
62 print(f"Volume: {self.sound.get_volume()}")
63
64 def stream_position(self):
65 print(f"Current position: {self.sound.get_stream_position()}")
66
67
68class MyGame(arcade.Window):
69 """
70 Main application class.
71
72 NOTE: Go ahead and delete the methods you don't need.
73 If you do need a method, delete the 'pass' and replace it
74 with your own code. Don't leave 'pass' in this program.
75 """
76
77 def __init__(self, width, height, title):
78 super().__init__(width, height, title)
79
80 arcade.set_background_color(arcade.color.AMAZON)
81
82 self.button_sprites = None
83
84 def setup(self):
85 self.button_sprites = arcade.SpriteList()
86
87 y = SCREEN_HEIGHT / 2 + 150
88 volume = 0.1
89 button = AudioStreamButton(
90 ":resources:music/funkyrobot.mp3", pan=-1.0, volume=volume
91 )
92 button.center_x = BUTTON_SIZE
93 button.center_y = y
94 self.button_sprites.append(button)
95
96 y = SCREEN_HEIGHT / 2 + 50
97 volume = 0.1
98 button = SoundButton(":resources:sounds/upgrade4.wav", pan=-1.0, volume=volume)
99 button.center_x = BUTTON_SIZE
100 button.center_y = y
101 self.button_sprites.append(button)
102
103 button = SoundButton(":resources:sounds/upgrade4.wav", pan=-0.5, volume=volume)
104 button.center_x = SCREEN_WIDTH / 4
105 button.center_y = y
106 self.button_sprites.append(button)
107
108 button = SoundButton(":resources:sounds/upgrade4.wav", pan=0, volume=volume)
109 button.center_x = SCREEN_WIDTH / 2
110 button.center_y = y
111 self.button_sprites.append(button)
112
113 button = SoundButton(":resources:sounds/upgrade4.wav", pan=0.5, volume=volume)
114 button.center_x = SCREEN_WIDTH / 4 * 3
115 button.center_y = y
116 self.button_sprites.append(button)
117
118 button = SoundButton(":resources:sounds/upgrade4.wav", pan=1, volume=volume)
119 button.center_x = SCREEN_WIDTH - BUTTON_SIZE
120 button.center_y = y
121 self.button_sprites.append(button)
122
123 y = SCREEN_HEIGHT / 2
124 volume = 0.5
125 button = SoundButton(":resources:sounds/upgrade4.wav", pan=-1.0, volume=volume)
126 button.center_x = BUTTON_SIZE
127 button.center_y = y
128 self.button_sprites.append(button)
129
130 button = SoundButton(":resources:sounds/upgrade4.wav", pan=-0.5, volume=volume)
131 button.center_x = SCREEN_WIDTH / 4
132 button.center_y = y
133 self.button_sprites.append(button)
134
135 button = SoundButton(":resources:sounds/upgrade4.wav", pan=0, volume=volume)
136 button.center_x = SCREEN_WIDTH / 2
137 button.center_y = y
138 self.button_sprites.append(button)
139
140 button = SoundButton(":resources:sounds/upgrade4.wav", pan=0.5, volume=volume)
141 button.center_x = SCREEN_WIDTH / 4 * 3
142 button.center_y = y
143 self.button_sprites.append(button)
144
145 button = SoundButton(":resources:sounds/upgrade4.wav", pan=1, volume=volume)
146 button.center_x = SCREEN_WIDTH - BUTTON_SIZE
147 button.center_y = y
148 self.button_sprites.append(button)
149
150 y = SCREEN_HEIGHT / 2 - 50
151 volume = 1
152 button = SoundButton(":resources:sounds/upgrade4.wav", pan=-1.0, volume=volume)
153 button.center_x = BUTTON_SIZE
154 button.center_y = y
155 self.button_sprites.append(button)
156
157 button = SoundButton(":resources:sounds/upgrade4.wav", pan=-0.5, volume=volume)
158 button.center_x = SCREEN_WIDTH / 4
159 button.center_y = y
160 self.button_sprites.append(button)
161
162 button = SoundButton(":resources:sounds/upgrade4.wav", pan=0, volume=volume)
163 button.center_x = SCREEN_WIDTH / 2
164 button.center_y = y
165 self.button_sprites.append(button)
166
167 button = SoundButton(":resources:sounds/upgrade4.wav", pan=0.5, volume=volume)
168 button.center_x = SCREEN_WIDTH / 4 * 3
169 button.center_y = y
170 self.button_sprites.append(button)
171
172 button = SoundButton(":resources:sounds/upgrade4.wav", pan=1, volume=volume)
173 button.center_x = SCREEN_WIDTH - BUTTON_SIZE
174 button.center_y = y
175 self.button_sprites.append(button)
176
177 def on_draw(self):
178 """
179 Render the screen.
180 """
181
182 # This command should happen before we start drawing. It will clear
183 # the screen to the background color, and erase what we drew last frame.
184 arcade.start_render()
185
186 # Call draw() on all your sprite lists below
187 self.button_sprites.draw()
188
189 def on_update(self, delta_time):
190 """
191 All the logic to move, and the game logic goes here.
192 Normally, you'll call update() on the sprite lists that
193 need it.
194 """
195 self.button_sprites.update()
196
197 def on_key_press(self, key, key_modifiers):
198 """
199 Called whenever a key on the keyboard is pressed.
200
201 For a full list of keys, see:
202 http://arcade.academy/arcade.key.html
203 """
204 pass
205
206 def on_key_release(self, key, key_modifiers):
207 """
208 Called whenever the user lets off a previously pressed key.
209 """
210 pass
211
212 def on_mouse_motion(self, x, y, delta_x, delta_y):
213 """
214 Called whenever the mouse moves.
215 """
216 pass
217
218 def on_mouse_press(self, x, y, button, key_modifiers):
219 """
220 Called when the user presses a mouse button.
221 """
222 hit_sprites = arcade.get_sprites_at_point((x, y), self.button_sprites)
223 for sprite in hit_sprites:
224 button_sprite = typing.cast(SoundButton, sprite)
225 if button == arcade.MOUSE_BUTTON_LEFT:
226 button_sprite.play()
227 elif (
228 button == arcade.MOUSE_BUTTON_RIGHT
229 ): # right click to increase volume on currently playing sound
230 if not button_sprite.sound.is_complete():
231 button_sprite.volume_up()
232 button_sprite.stream_position()
233 elif button == arcade.MOUSE_BUTTON_MIDDLE:
234 if not button_sprite.sound.is_complete():
235 button_sprite.volume_down()
236 button_sprite.stream_position()
237
238 def on_mouse_release(self, x, y, button, key_modifiers):
239 """
240 Called when a user releases a mouse button.
241 """
242 pass
243
244
245def main():
246 """ Main method """
247 game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
248 game.setup()
249 arcade.run()
250
251
252if __name__ == "__main__":
253 main()