声音演示#

sound_demo.py#
1"""
2Sound Panning Demo
3
4If Python and Arcade are installed, this example can be run from the
5command line with:
6python -m arcade.examples.sound_demo
7
8Each button plays a sound when clicked.
9
10The top left button plays a streaming music track when pressed. If you
11click it while it's already playing, it will intentionally crash the
12demo to demonstrate how you shouldn't try to play a streaming sound
13that's already playing.
14
15The lower 3 rows of buttons play a non-streaming (static) sound with
16different panning and volume. Going from left to right changes the
17panning, which is how much the sound plays in the left speaker vs the
18right speaker. Lower rows play the sound louder than the higher ones.
19"""
20
21import typing
22
23import arcade
24
25SCREEN_WIDTH = 800
26SCREEN_HEIGHT = 600
27SCREEN_TITLE = "Sound Panning Demo"
28BUTTON_SIZE = 30
29
30
31SOUND_PANNING = [-1.0, -0.5, 0.0, 0.5, 1.0]
32BUTTON_X_POSITIONS = [
33 BUTTON_SIZE,
34 SCREEN_WIDTH / 4,
35 SCREEN_WIDTH / 2,
36 SCREEN_WIDTH / 4 * 3,
37 SCREEN_WIDTH - BUTTON_SIZE,
38]
39
40
41VOLUME_VARIATION = [0.1, 0.5, 1]
42Y_OFFSETS = [50, 0, -50]
43
44
45class SoundButton(arcade.SpriteSolidColor):
46 """
47 A sprite that stores settings about how to play a sound.
48
49 This class can load a sound as either a static sound or a streaming
50 sound. Streaming should be used for long files that will only have
51 one instance playing, such as music or ambiance tracks.
52
53 If you try to play a sound created with streaming=True while it is
54 already playing, it will raise an exception! Non-streaming (static)
55 sounds are fine with it, and can have play() called on them as many
56 times as you want.
57 """
58
59 def __init__(
60 self,
61 sound_file,
62 pan=0.5,
63 volume=0.5,
64 center_x=0,
65 center_y=0,
66 streaming=False
67 ):
68 super().__init__(BUTTON_SIZE, BUTTON_SIZE, color=arcade.color.WHITE)
69 self.sound = arcade.Sound(sound_file, streaming=streaming)
70 self.pan = pan
71 self.volume = volume
72 self.center_x = center_x
73 self.center_y = center_y
74
75 def play(self):
76 self.sound.play(pan=self.pan, volume=self.volume)
77
78
79class MyGame(arcade.Window):
80 def __init__(self, width, height, title):
81 super().__init__(width, height, title)
82 self.background_color = arcade.color.AMAZON
83 self.button_sprites = None
84
85 def setup(self):
86 self.button_sprites = arcade.SpriteList()
87
88 # create the streaming button at the top left
89 self.button_sprites.append(
90 SoundButton(
91 ":resources:music/funkyrobot.mp3",
92 pan=-1.0,
93 volume=0.1,
94 center_x=BUTTON_SIZE,
95 center_y=SCREEN_HEIGHT / 2 + 150,
96 streaming=True
97 )
98 )
99
100 # Position the grid of buttons
101 # The zip function takes pieces from iterables and returns them
102 # as tuples. For more information, see the python doc:
103 # https://docs.python.org/3/library/functions.html#zip
104 for vol, y_offset in zip(VOLUME_VARIATION, Y_OFFSETS):
105 for pan_setting, x_pos in zip(SOUND_PANNING, BUTTON_X_POSITIONS):
106 self.button_sprites.append(
107 SoundButton(
108 ":resources:sounds/upgrade4.wav",
109 pan_setting,
110 vol,
111 x_pos,
112 SCREEN_HEIGHT / 2 + y_offset,
113 )
114 )
115
116 def on_draw(self):
117 self.clear()
118 self.button_sprites.draw()
119
120 def on_update(self, delta_time):
121 self.button_sprites.update()
122
123 def on_mouse_press(self, x, y, button, key_modifiers):
124 hit_sprites = arcade.get_sprites_at_point((x, y), self.button_sprites)
125 for sprite in hit_sprites:
126 button_sprite = typing.cast(SoundButton, sprite)
127 if button == arcade.MOUSE_BUTTON_LEFT:
128 button_sprite.play()
129
130
131def main():
132 game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
133 game.setup()
134 arcade.run()
135
136
137if __name__ == "__main__":
138 main()