-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathminiGame_raphael.js
266 lines (210 loc) · 9.18 KB
/
miniGame_raphael.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
// This is the real version of the mini game that goes with the game
dojo.declare('miniGame', [ ], {
width: 500, // dimensions of the canvas
height: 500,
isSuccess: false, // keeps track if the player has crossed the street or not
isSafe: false, // keeps track if the player can cross the street
isActive: false, // whether the game is active (ie, whether the player can press 'up' to cross the street)
isOver: false, // whether the miniGame is over, used for Street Crosser
misses: 0, // keps track of the number of misses the player has had
audio_info: null, // the object that the JSON file becomes
audio_url: null, // the URL for the traffic clip
audio_file_number: 3, // number of available traffic clips (mp3/ogg with adjoining JSON file)
// the constructor gets called when we create the object
constructor: function(paper, whichSide) {
// initilize the Raphael canvas
this.raph = paper;
// save the side of the person that the road is on (default is the right side)
if (whichSide == 'L'){
this.whichSide = 'L';
} else {
this.whichSide = 'R';
}
this.link = dojo.connect(window, 'keydown', this, 'keyDown');
// get the cross walk pictures
this.goPic = this.raph.image("images/go.png", 100, 30, 300, 400).hide();
this.stopPic = this.raph.image("images/stop.png", 100, 30, 300, 400).hide();
this.status_holder = this.raph.rect(100, 350, 300, 100).attr({fill: '#ccf', stroke: '#00f'});
// a queue for the traffic statuses (first-in-first-out)
this.status_queue = ["", "", "", ""];
this.traffic_status = this.raph.text(250, 400, "");
this.traffic_status.attr({
'font-size': 18,
'text-anchor': 'middle'
});
this.raph.rect(1,1,this.width-2,this.height-2); // draw the border
// write the instructions on the screen
this.raph.text(this.width/2, 50, "Listen to the street sounds and").attr('font-size', 20);
this.raph.text(this.width/2, 75, "press up when you want to cross the street.").attr('font-size', 20);
// initialize audio
uow.getAudio({ defaultCaching: true }).then(dojo.hitch(this, function(a) {
this.audio = a; // save the audio object for later use
this.importFiles();
}));
},
importFiles: function() {
var self = this;
var rnd = Math.floor(Math.random()*this.audio_file_number) + 1; // the radomization of the audio file
dojo.byId('form1').value = rnd;
// get the url for the sound file
this.audio_url = 'sounds/traffic/' + rnd + this.whichSide;
var json_url = "sounds/traffic/" + rnd + ".json";
// "import" the appropriate JSON file
dojo.xhrGet({
url : json_url,
handleAs : "json",
load : function(response) {
self.audio_info = response;
self.newGame();
},
error : function(error) {
alert("Couldn't fetch your data: " + error);
}
});
},
newGame: function() {
var self = this;
var v = this.audio.say({text: "Listen to the street sounds and press up when you want to cross the street."});
// We want to put the traffic sound on the audio queue so it will start as soon the directions end
this.playAudio();
v.callAfter(function() {
self.isActive = true;
self.goPic.hide();
self.stopPic.show();
});
},
playAudio: function(){
this.audio.setProperty({name : 'volume', value : 1.0});
this.updateTrafficStatus();
var self = this;
var a = this.audio.play({url: this.audio_url});
a.errBefore( function() {
alert("Couldn't fetch the audio clip!");
})
a.callBefore( function() {
self.trafficStatus(0);
});
},
// This is a recursive call that displays the traffic statuses as they occur according to the JSON file
trafficStatus: function(index){
// base step
if (index == this.audio_info.length){
return;
}
this.addToQueue(this.audio_info[index].state);
this.updateTrafficStatus();
if (this.audio_info[index].state == 'sidesurging' || this.audio_info[index].state == 'sidetraffic'){
this.isSafe = true;
this.goPic.show();
this.stopPic.hide();
} else {
this.isSafe = false;
this.goPic.hide();
this.stopPic.show();
}
var self = this;
// recursive step
this.timer1 = setTimeout(function() {
self.trafficStatus(index+1);
}, (this.audio_info[index+1].time-this.audio_info[index].time)*1000);
},
// An object which is used in the updateTrafficStatus to display some text
statusToText: {
'': '',
'crosstraffic': "Cross traffic is active",
'crossstopping': "Cross traffic is stopping",
'sidesurging': "Side traffic is surging",
'sidetraffic': "Side traffic is active",
'sidestopping': "Side traffic is stopping",
'crosssurging': "Cross traffic is surging",
},
updateTrafficStatus: function(){
this.traffic_status.attr('text',
this.statusToText[this.status_queue[0]] + "...\n|||||||||||\n" +
this.statusToText[this.status_queue[1]] + ".\n" +
this.statusToText[this.status_queue[2]] + ".\n" +
this.statusToText[this.status_queue[3]] + "."
);
},
// adds the value to the status queue
addToQueue: function(value) {
this.status_queue[3] = this.status_queue[2];
this.status_queue[2] = this.status_queue[1];
this.status_queue[1] = this.status_queue[0];
if (value){
this.status_queue[0] = value;
} else {
this.status_queue[0] = "";
}
},
// the event handlers for button presses
keyDown: function(e) {
var self = this
if (e.keyCode == dojo.keys.UP_ARROW) {
if (this.isActive == false){
return;
}
// stop the audio from playing
this.isActive = false;
this.audio.stop();
if (this.timer1){
window.clearTimeout(this.timer1);
}
// walked at the wrong time, so you try again
if (this.isSafe == false) {
//this.audio.play({url: 'sounds/miss/miss1'});
this.misses++;
var a;
if (this.status_queue[0] == 'crosstraffic'){
a = this.audio.say({text: "You walked too early into the perpendicular traffic. " +
" Wait until the parallel traffic surges on your side."});
}
else if (this.status_queue[0] == 'crossstopping'){
a = this.audio.say({text: "You walked too early. " +
" Wait until you hear the perpendicular traffic completely stop and the parallel traffic surge"});
}
else if (this.status_queue[0] == 'sidestopping'){
a = this.audio.say({text: "You walked too late. " +
" The parallel was stopping and did not have enough time to cross. " +
" Try to cross as soon as you hear the parallel traffic surging."});
}
else if (this.status_queue[0] == 'crosssurging'){
a = this.audio.say({text: "You walked too late. " +
" The parallel traffic was surging, so you walked into traffic. " +
" Take your time and wait for the parallel traffic to start again."});
}
a.callAfter( function(){
self.status_queue = ["", "", "", ""];
self.newGame();
});
}
// the player walked at the right time, so the game ends
else {
this.isSuccess = true;
this.audio.play({url: 'sounds/hit/hit3'});
this.audio.say({text: "You made it safely across. Good Job!"}).callAfter( function(){
self.endGame();
});
}
}
if (e.keyCode == dojo.keys.LEFT_ARROW) {
}
if (e.keyCode == dojo.keys.SHIFT) {
this.isSuccess = true;
this.endGame();
}
if (e.keyCode == dojo.keys.DOWN_ARROW) {
this.endGame();
}
},
endGame: function(){
if (this.timer1){
window.clearTimeout(this.timer1);
window.clearTimeout(this.timer1);
}
this.raph.clear();
this.audio.stop();
dojo.disconnect(this.link);
this.isOver = true;
},
});