37481aaab41c2f94088815ffebe602a3e738b873
[shapeshift.git] / shapeshift.js
1 var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
2 var ground;
3 var platforms;
4 var guards;
5 var guard1, guard2;
6 var birdcage;
7 var helptext;
8 var cursors;
9 var lastkeytime = 0;
10 var keyboard_handler;
11 var interaction_handler;
12 var actual_dialogue = null;
13
14 var WAIT_KEY = 500;
15
16 var SHAPE_GIRL = 0;
17 var SHAPE_GOAT = 1;
18 var SHAPE_BIRD = 2;
19
20 var dialogue_guard1_girl =
21 [ { actor: 'player', text: "Hello! May I enter this town?" },
22 { actor: 'guard', text: "Sorry, I don't know you.\nI can't let you in." } ];
23 var dialogue_guard1_girl_retry =
24 [ { actor: 'player', text: "But I'm a goddess!" },
25 { actor: 'guard', text: "I'm a feminist.\nI don't put women on pedestals." } ];
26 var dialogue_guard1_goat =
27 [ { actor: 'guard', text: "Hmm, it must be Coralie's lost goat.\nI'd better let it in." } ];
28 var dialogue_guard2_girl =
29 [ { actor: 'player', text: "Hi there! I'm a goddess and can transform into a goat!" },
30 { actor: 'guard', text: "Hey, that's really cool!\nI'm Coralie." },
31 { actor: 'player', text: "Nice bird you have there.\nCan I have it?" },
32 { actor: 'guard', text: "Yeah, it's yours. Just take it." },
33 { actor: 'guard', text: "Don't mind that it took me days to catch it." },
34 { actor: 'player', text: "Observing this bird, I will be able to shapeshift into a bird too!" } ];
35 var dialogue_guard2_goat =
36 [ { actor: 'guard', text: "This is not my goat. Strange to see random\ngoats wandering here while mine is still missing." } ];
37 var dialogue_guard3_girl =
38 [ { actor: 'player', text: "Hi! I'd like to leave the town." },
39 { actor: 'guard', text: "Sorry, we have a report of a missing goat.\nIt may have been stolen. We can't let anyone out\nuntil we find the thief." },
40 { actor: 'player', text: "I just came here before the goat went missing. The other guard can support this." },
41 { actor: 'player', text: "And the goat may have just wandered away.\nYou know they tend to escape, they require lots of space." },
42 { actor: 'guard', text: "Maybe, but we can't be sure. Sorry." } ];
43 var dialogue_guard3_girl_retry =
44 [ { actor: 'player', text: "But I'm a girl! I wouldn't steal anything!" },
45 { actor: 'guard', text: "I'm a feminist.\nI don't give advantages to people based on their genders." } ];
46 var dialogue_guard3_goat =
47 [ { actor: 'guard', text: "Another goat is trying to escape...\nGood that I'm on guard!" } ];
48 var dialogue_guard3_bird =
49 [ { actor: 'guard', text: "Hi birdie! Don't fly at me, please!" } ];
50 var dialogue_guard4_girl =
51 [ { actor: 'guard', text: "You are at home!\nYou don't have to pretend anymore." } ];
52 var dialogue_guard4_goat =
53 [ { actor: 'guard', text: "Welcome home!\nGlad you shapeshifted back to your true form!" },
54 { actor: 'guard', text: "Yes, your true form is goat.\nDidn't you suspect it all along?" } ];
55 var dialogue_guard4_goat_retry =
56 [ { actor: 'guard', text: "(By the way, this is the end of the game.\nYou really can't do anything more.\nThanks for playing!)" } ];
57
58
59 window.addEventListener("keydown", function(e) {
60 // Prevent default browser action for arrows and spacebar
61 if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
62 e.preventDefault();
63 }
64 }, false);
65
66 class Player extends Phaser.Sprite {
67 constructor(x, y, sprite) {
68 super(game, x, y, sprite);
69 this.anchor.setTo(.4,.5);
70 this.scale.x = 0.5;
71 this.scale.y = this.scale.x;
72 this.pushed = 0;
73 this.shape = SHAPE_GIRL;
74 this.learnedBird = false;
75 }
76
77 enablePhysics() {
78 game.physics.arcade.enable(this);
79 this.body.bounce.y = 0.2;
80 this.body.bounce.x = 0.2;
81 this.body.gravity.y = 300;
82 this.body.collideWorldBounds = true;
83 }
84 }
85
86 class Guard extends Phaser.Sprite {
87 constructor(x, y, sprite, dialogues) {
88 //var guard = game.add.sprite(x, y, sprite);
89 super(game, x, y, sprite);
90 this.anchor.setTo(.5,.5);
91 this.scale.x = 0.5;
92 this.scale.y = this.scale.x;
93 this.dialogues = dialogues;
94 guards.add(this);
95 }
96
97 enablePhysics() {
98 game.physics.arcade.enable(this);
99 this.body.bounce.y = 0.2;
100 this.body.bounce.x = 0.2;
101 this.body.gravity.y = 300;
102 this.body.collideWorldBounds = true;
103 }
104 }
105
106 function sign(n) {
107 if (n >= 0) { return 1 } else { return -1 };
108 }
109
110 function preload () {
111
112 game.load.image('ground', 'ground.png');
113 game.load.image('player_girl', 'csaj.png');
114 game.load.image('player_goat', 'kecskecsaj.png');
115 game.load.image('player_bird', 'bird.png');
116 game.load.image('guard', 'guard.png');
117 game.load.image('birdcage', 'birdcage.png');
118
119 }
120
121 function create () {
122
123 game.world.setBounds(0, 0, 2800, 600);
124 game.stage.backgroundColor = 0xffffff;
125 game.physics.startSystem(Phaser.Physics.ARCADE);
126
127 platforms = game.add.group();
128 platforms.classType = Phaser.TileSprite;
129 platforms.enableBody = true;
130
131
132 ground = game.add.tileSprite(0, game.world.height - 80, game.world.width, 200, 'ground');
133 platforms.add(ground);
134 ground.body.immovable = true;
135
136
137 //player = game.add.sprite(64, game.world.height - 200, 'player_girl');
138 player = new Player(64, game.world.height - 200, 'player_girl');
139 player.enablePhysics();
140 game.add.existing(player);
141 game.camera.follow(player);
142
143 guards = game.add.group();
144 guard1 = new Guard(600, game.world.height - 200, 'guard',
145 { girl: dialogue_guard1_girl, goat: dialogue_guard1_goat });
146 guard2 = new Guard(1000, game.world.height - 200, 'player_girl',
147 { girl: dialogue_guard2_girl, goat: dialogue_guard2_goat });
148 guard2.scale.x = -guard2.scale.x;
149 guard3 = new Guard(1400, game.world.height - 200, 'guard',
150 { girl: dialogue_guard3_girl, goat: dialogue_guard3_goat, bird: dialogue_guard3_bird });
151 guard4 = new Guard(2400, game.world.height - 200, 'player_goat',
152 { girl: dialogue_guard4_girl, goat: dialogue_guard4_goat, bird: dialogue_guard4_girl });
153 guard4.scale.x = -guard4.scale.x;
154 guards.children.forEach(function(guard) { guard.enablePhysics(); });
155
156 birdcage = game.add.sprite(1100, game.world.height - 300, 'birdcage');
157 birdcage.scale.x = 0.5;
158 birdcage.scale.y = birdcage.scale.x;
159
160 cursors = game.input.keyboard.createCursorKeys();
161
162 keyboard_handler = keyPress_default;
163 interaction_handler = interaction;
164
165 helptext = game.add.text(80, 30, "Press ARROWS to move.", { align: 'left', fill: '#000000', fontSize: 14 });
166 helptext.font = "Ubuntu Mono";
167
168 }
169
170 function update () {
171
172 game.physics.arcade.collide(player, platforms);
173 game.physics.arcade.collide(guards, platforms);
174 game.physics.arcade.collide(player, guards, interaction_handler);
175
176 if (player.pushed)
177 {
178 if ((game.time.now - player.pushed) > 1000)
179 player.pushed = 0;
180 }
181 else
182 {
183 player.body.velocity.x = 0;
184 }
185
186 if (keyboard_handler) keyboard_handler();
187
188 }
189
190 function keyPress_default() {
191
192 if (cursors.left.isDown)
193 {
194 player.body.velocity.x = -150;
195 player.scale.x = - Math.abs(player.scale.x);
196 }
197 else if (cursors.right.isDown)
198 {
199 player.body.velocity.x = 150;
200 player.scale.x = Math.abs(player.scale.x);
201 }
202 else if (game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR) && ((game.time.now - lastkeytime) > WAIT_KEY))
203 {
204 if (player.shape == SHAPE_GIRL)
205 {
206 player.shape = SHAPE_GOAT;
207 player.loadTexture('player_goat');
208 }
209 else if ((player.shape == SHAPE_GOAT) && (player.learnedBird))
210 {
211 player.shape = SHAPE_BIRD;
212 player.loadTexture('player_bird');
213 }
214 else
215 {
216 player.shape = SHAPE_GIRL;
217 player.loadTexture('player_girl');
218 }
219
220 player.body.setSize(player.texture.width, player.texture.height);
221 if ((ground.y - player.y) < player.body.halfHeight)
222 player.y = ground.y - player.body.halfHeight;
223
224 lastkeytime = game.time.now;
225 }
226
227 if ((cursors.up.isDown) && (player.shape == SHAPE_BIRD))
228 {
229 player.body.velocity.y = -200;
230 }
231
232 }
233
234 function keyPress_indialogue() {
235
236 if (game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR) && ((game.time.now - lastkeytime) > WAIT_KEY))
237 {
238 var dialogue = actual_dialogue.dialogue;
239 if (dialogue[actual_dialogue.state + 1])
240 {
241 var nextState = ++actual_dialogue.state;
242 var actor = null;
243 if (dialogue[nextState].actor == 'player') actor = actual_dialogue.player;
244 else if (dialogue[nextState].actor == 'guard') actor = actual_dialogue.guard;
245
246 actual_dialogue.lastText.kill();
247 actual_dialogue.lastText = putText(actor, dialogue[nextState].text);
248 lastkeytime = game.time.now;
249 }
250 else
251 {
252 leaveDialogue();
253 lastkeytime = game.time.now;
254 }
255 }
256
257 }
258
259 function putText(entity, text) {
260 var textObject = game.add.text(entity.x, entity.y - (entity.height / 2) - 30, text, { align: 'center', fontSize: 14 });
261 textObject.font = 'Ubuntu Mono';
262 textObject.anchor.setTo(.5,.5);
263 return textObject;
264 }
265
266 function interaction(player, guard) {
267
268 console.log('Interaction with ' + guard.key);
269 player.body.velocity.x = -100;
270 player.pushed = game.time.now;
271 guard.body.velocity.x = 0;
272
273 if (player.shape == SHAPE_GIRL)
274 {
275 if ((guard == guard1) && (guard.dialogues.girl == dialogue_guard1_girl))
276 helptext.text = helptext.text + "\nPress SPACE to progress dialogue.";
277 enterDialogue(player, guard, guard.dialogues.girl);
278 }
279 else if (player.shape == SHAPE_GOAT)
280 {
281 enterDialogue(player, guard, guard.dialogues.goat);
282 }
283 else if (player.shape == SHAPE_BIRD)
284 {
285 enterDialogue(player, guard, guard.dialogues.bird);
286 }
287
288 }
289
290 function enterDialogue(player, guard, dialogue) {
291
292 var actor = null;
293 if (dialogue[0].actor == 'player') actor = player;
294 else if (dialogue[0].actor == 'guard') actor = guard;
295
296 var lastText = putText(actor, dialogue[0].text);
297 actual_dialogue = { player: player, guard: guard, dialogue: dialogue, state: 0 , lastText: lastText };
298 keyboard_handler = keyPress_indialogue;
299 interaction_handler = null;
300
301 }
302
303 function leaveDialogue() {
304
305 actual_dialogue.lastText.kill();
306 if (actual_dialogue.dialogue == dialogue_guard1_girl)
307 {
308 helptext.text = helptext.text + "\nPress SPACE to shapeshift.";
309 guard1.dialogues.girl = dialogue_guard1_girl_retry;
310 }
311 else if (actual_dialogue.dialogue == dialogue_guard1_goat)
312 {
313 guard1.kill();
314 }
315 else if (actual_dialogue.dialogue == dialogue_guard2_girl)
316 {
317 guard2.kill();
318 birdcage.kill();
319 player.learnedBird = true;
320 }
321 else if (actual_dialogue.dialogue == dialogue_guard3_girl)
322 {
323 guard3.dialogues.girl = dialogue_guard3_girl_retry;
324 }
325 else if (actual_dialogue.dialogue == dialogue_guard4_goat)
326 {
327 guard4.dialogues.goat = dialogue_guard4_goat_retry;
328 guard4.dialogues.girl = dialogue_guard4_goat_retry;
329 guard4.dialogues.bird = dialogue_guard4_goat_retry;
330 }
331
332 actual_dialogue = null;
333 keyboard_handler = keyPress_default;
334 interaction_handler = interaction;
335
336 }