1
1
Music and Bass Shake[[music]]
2
2
-----------------------------
3
3
4
- In Hexagon, the music is an important element of the game. It is even part of the game mechanics:
4
+ In Hexagon, the music is an important element of the game. It is even part of the physical game mechanics:
5
5
Whenever there is a bass sequence, the whole stage is shaking.
6
6
7
7
The original game music is copyrighted. Therefore we provide an alternative track
8
8
for this tutorial that has a Creative Commons license.
9
9
10
- There is an issue with Safari, so use a different Browser for this.
10
+ There is also an issue with Safari, so use a different browser for this like Google Chrome or the newest Internet Explorer .
11
11
12
12
## Download the Music
13
13
The track that we are going to use is called "Shiny Tech" by Kevin MacLeod.
14
- Download it from the
15
- http://incompetech.com/music/royalty-free/index.html?collection=12&page=1[Incompetech] website.
14
+ Download it here:
15
+ http://incompetech.com/music/royalty-free/index.html?collection=12&page=1[Incompetech]
16
16
17
- Rename it to `shinytech.mp3` and copy it into a `src/music` folder.
17
+ Rename it `shinytech.mp3` and copy it into a `src/music` folder.
18
18
19
19
---
20
20
@@ -30,9 +30,10 @@ Rename the downloaded file to "music.mp3" and copy it into the music folder.
30
30
31
31
32
32
## Install the audio library
33
+
33
34
The audio library abstracts the HTML5 Audio tag for the elm language. It uses native bindings.
34
35
Unfortunately Elm discourages the use of native bindings for 3rd party libraries. But until audio
35
- support is available in core we have to use one.
36
+ support is available in core, we have to use one.
36
37
37
38
It is not possible to install such libraries through elm-package. So we have to use git
38
39
or download it ourselves. We copy the `elm-audio` library in a folder called `lib/elm-audio`.
@@ -46,16 +47,16 @@ If you are already using git for this tutorial, then you can add it as a submodu
46
47
47
48
git submodule add https://github.com/xarvh/elm-audio.git lib/elm-audio
48
49
49
- This is not enogh though. Elm expects the native module to be named after the package.
50
+ This is not enough information though. Elm expects the native module to be named after the package.
50
51
So open the file `elm-audio/src/Native/Audio.js` and change the name of the global function
51
52
to match the name that you gave your project in `elm-package.json` in the `repository` field.
52
- It uses the syntax `_<username>$<project>$Native_Audio` so if you left it at the default the first
53
+ It uses the syntax `_<username>$<project>$Native_Audio`, so if you left it at the default setting the first
53
54
line of the module is:
54
55
55
56
var _sbaechler$polygon$Native_Audio = function() {
56
57
57
58
While we are here, we can add a few strategic console.log statements for debugging:
58
- * Inside the `oncanplaythrough()` method which fires when the audio has been loaded completely
59
+ * Inside the `oncanplaythrough()` method that fires when the audio has been completely loaded
59
60
* Inside the `playSound` and `stopSound` method.
60
61
61
62
@@ -85,9 +86,9 @@ Add a `hasBass : Bool` property as well.
85
86
The music property is initialized with the value `Nothing` in the `init` method. `hasBass` is set to
86
87
`False`.
87
88
88
- The loading of the music file is a Task as well. It sends of the message `MusicLoaded` when the
89
- mp3 has been downloaded (When the browser has fired the `canplaythrough` event).
90
- The task could also fail, therefore we add an `Error` message. A `Noop`
89
+ The loading of the music file is a task as well. It sends the message `MusicLoaded` when the
90
+ mp3 has been downloaded (when the browser has fired the `canplaythrough` event).
91
+ The task could also fail, therefore we need to add an `Error` message. A `Noop`
91
92
message is needed as well as a callback for the stop command.
92
93
93
94
// type Msg
@@ -98,8 +99,8 @@ We curry the `loadSound` method with the file name for the audio file:
98
99
// loadSound
99
100
{% codesnippet "https://raw.githubusercontent.com/macrozone/elm-hexagon-tutorial/chapter/music/src/Hexagon.elm", lines="120:121" %}{% endcodesnippet %}
100
101
101
- The audio library exposes a `Sound` type wich is a reference to a HTML5 Audio tag. The
102
- `PlaybackOptions` object has three attributes: Volume , start and loop.
102
+ The audio library exposes a `Sound` type, which is a reference to a HTML5 Audio tag. The
103
+ `PlaybackOptions` object has three attributes: volume , start and loop.
103
104
104
105
We set loop to True and startAt to Nothing, which means that it continues playing from its current
105
106
position.
@@ -108,7 +109,7 @@ position.
108
109
{% codesnippet "https://raw.githubusercontent.com/macrozone/elm-hexagon-tutorial/chapter/music/src/Hexagon.elm", lines="124:125" %}{% endcodesnippet %}
109
110
110
111
The `playSound` and `stopSound` functions start and stop the music. They take a reference to the
111
- sound object and an options object and return a command of type message.
112
+ sound object and an options object, then returning a command of type message.
112
113
113
114
They are tasks because playing audio is a side-effect. In case of an error, the Error message is
114
115
sent. In case of success (the audio is done playing) the Noop message is sent.
@@ -120,13 +121,13 @@ We use anonymous functions to define the callbacks.
120
121
With all the new states the update methods become a bit more complex. However, they are still
121
122
easily readable and understandable.
122
123
123
- We add the new intermediate helper states. In the `onUserInput` function, update the `nextState`
124
+ We now add the new intermediate helper states. In the `onUserInput` function, update the `nextState`
124
125
assignment so it uses the new states.
125
126
126
127
In the `onFrame` function we are going to output new commands as well, so we assign those in the
127
- `let` block. At first we have to make sure, that the music is not `Nothing`. (It won't compile if
128
+ `let` block. At first we have to make sure that the music is not `Nothing`. (It won't compile if
128
129
this check was missing.) +
129
- In the `Starting` state the music is played from the beginning. The `startAt` value is a `Maybe` as
130
+ In the `Starting` state, the music is played from the beginning. The `startAt` value is a `Maybe` as
130
131
well so we have to use `Just 0` here.
131
132
The other states should be self-explanatory.
132
133
@@ -135,7 +136,7 @@ The other states should be self-explanatory.
135
136
136
137
The update method needs to handle the new states. When the `MusicLoaded` message arrives,
137
138
the game state is set to `NewGame` and the music is stored in the model. +
138
- In case of an error we just throw it .
139
+ In case of an error, we add another line of programming .
139
140
140
141
// update
141
142
{% codesnippet "https://raw.githubusercontent.com/macrozone/elm-hexagon-tutorial/chapter/music/src/Hexagon.elm", lines="302:314" %}{% endcodesnippet %}
@@ -149,7 +150,7 @@ commands.
149
150
150
151
151
152
## Bass pump
152
- The playing field should pump in sync with the beat. Therefore we have to define
153
+ The playing field should pump in sync with the beat. Therefore, we have to define
153
154
the speed of the track and the sections where there is a bass part.
154
155
155
156
Add three variables for beat, amplitude and phase:
@@ -198,7 +199,7 @@ hasBass time =
198
199
else False
199
200
----
200
201
201
- For the original track use those values:
202
+ For the original track use these values:
202
203
203
204
[source,elm]
204
205
----
@@ -236,15 +237,15 @@ The `beatPhase` value is used to adjust the timing so it matches with the music.
236
237
{% codesnippet "https://raw.githubusercontent.com/macrozone/elm-hexagon-tutorial/chapter/music/src/Hexagon.elm", lines="103:105" %}{% endcodesnippet %}
237
238
238
239
The center hole is always pulsating but it should be in sync with the rest of the
239
- stage during a bass sequence. For that we adjust the `makeCenterHole` function.
240
- Whenever there is a bass sequence the radius of the center piece should remain constant
240
+ stage during a bass sequence. For that effect we adjust the `makeCenterHole` function.
241
+ Whenever there is a bass sequence the radius of the center hole should remain constant, or
241
242
otherwise it should be pumping.
242
243
243
244
// makeCenterHole
244
245
{% codesnippet "https://raw.githubusercontent.com/macrozone/elm-hexagon-tutorial/chapter/music/src/Hexagon.elm", lines="389:404" %}{% endcodesnippet %}
245
246
246
247
That was the last piece of the puzzle. Now it is time to test it out. The music should start
247
- playing when the game starts. The stage starts pumping after 21 around seconds.
248
+ playing when the game starts. The stage starts pumping after 21 seconds.
248
249
249
250
If something is not working, compare your code with the full source code
250
251
https://github.com/macrozone/elm-hexagon-tutorial/blob/chapter/music/src/Hexagon.elm[here].
0 commit comments