Reorganized code: created Entity base class
[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 Entity extends Phaser.Sprite {
67 constructor(x, y, sprite) {
68 super(game, x, y, sprite);
69 this.anchor.setTo(.5,.5);
70 this.scale.x = 0.5;
71 this.scale.y = this.scale.x;
72 }
73
74 enablePhysics() {
75 game.physics.arcade.enable(this);
76 this.body.bounce.y = 0.2;
77 this.body.bounce.x = 0.2;
78 this.body.gravity.y = 300;
79 this.body.collideWorldBounds = true;
80 }
81 }
82
83 class Player extends Entity {
84 constructor(x, y, sprite) {
85 super(x, y, sprite);
86 this.anchor.setTo(.4,.5);
87 this.pushed = 0;
88 this.shape = SHAPE_GIRL;
89 this.learnedBird = false;
90 }
91 }
92
93 class Guard extends Entity {
94 constructor(x, y, sprite, dialogues) {
95 //var guard = game.add.sprite(x, y, sprite);
96 super(x, y, sprite);
97 this.dialogues = dialogues;
98 guards.add(this);
99 }
100 }
101
102 function sign(n) {
103 if (n >= 0) { return 1 } else { return -1 };
104 }
105
106 function preload () {
107
108 game.load.image('ground', 'ground.png');
109 game.load.image('player_girl', 'csaj.png');
110 game.load.image('player_goat', 'kecskecsaj.png');
111 game.load.image('player_bird', 'bird.png');
112 game.load.image('guard', 'guard.png');
113 game.load.image('birdcage', 'birdcage.png');
114
115 }
116
117 function create () {
118
119 game.world.setBounds(0, 0, 2800, 600);
120 game.stage.backgroundColor = 0xffffff;
121 game.physics.startSystem(Phaser.Physics.ARCADE);
122
123 platforms = game.add.group();
124 platforms.classType = Phaser.TileSprite;
125 platforms.enableBody = true;
126
127
128 ground = game.add.tileSprite(0, game.world.height - 80, game.world.width, 200, 'ground');
129 platforms.add(ground);
130 ground.body.immovable = true;
131
132
133 //player = game.add.sprite(64, game.world.height - 200, 'player_girl');
134 player = new Player(64, game.world.height - 200, 'player_girl');
135 player.enablePhysics();
136 game.add.existing(player);
137 game.camera.follow(player);
138
139 guards = game.add.group();
140 guard1 = new Guard(600, game.world.height - 200, 'guard',
141 { girl: dialogue_guard1_girl, goat: dialogue_guard1_goat });
142 guard2 = new Guard(1000, game.world.height - 200, 'player_girl',
143 { girl: dialogue_guard2_girl, goat: dialogue_guard2_goat });
144 guard2.scale.x = -guard2.scale.x;
145 guard3 = new Guard(1400, game.world.height - 200, 'guard',
146 { girl: dialogue_guard3_girl, goat: dialogue_guard3_goat, bird: dialogue_guard3_bird });
147 guard4 = new Guard(2400, game.world.height - 200, 'player_goat',
148 { girl: dialogue_guard4_girl, goat: dialogue_guard4_goat, bird: dialogue_guard4_girl });
149 guard4.scale.x = -guard4.scale.x;
150 guards.children.forEach(function(guard) { guard.enablePhysics(); });
151
152 birdcage = game.add.sprite(1100, game.world.height - 300, 'birdcage');
153 birdcage.scale.x = 0.5;
154 birdcage.scale.y = birdcage.scale.x;
155
156 cursors = game.input.keyboard.createCursorKeys();
157
158 keyboard_handler = keyPress_default;
159 interaction_handler = interaction;
160
161 helptext = game.add.text(80, 30, "Press ARROWS to move.", { align: 'left', fill: '#000000', fontSize: 14 });
162 helptext.font = "Ubuntu Mono";
163
164 }
165
166 function update () {
167
168 game.physics.arcade.collide(player, platforms);
169 game.physics.arcade.collide(guards, platforms);
170 game.physics.arcade.collide(player, guards, interaction_handler);
171
172 if (player.pushed)
173 {
174 if ((game.time.now - player.pushed) > 1000)
175 player.pushed = 0;
176 }
177 else
178 {
179 player.body.velocity.x = 0;
180 }
181
182 if (keyboard_handler) keyboard_handler();
183
184 }
185
186 function keyPress_default() {
187
188 if (cursors.left.isDown)
189 {
190 player.body.velocity.x = -150;
191 player.scale.x = - Math.abs(player.scale.x);
192 }
193 else if (cursors.right.isDown)
194 {
195 player.body.velocity.x = 150;
196 player.scale.x = Math.abs(player.scale.x);
197 }
198 else if (game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR) && ((game.time.now - lastkeytime) > WAIT_KEY))
199 {
200 if (player.shape == SHAPE_GIRL)
201 {
202 player.shape = SHAPE_GOAT;
203 player.loadTexture('player_goat');
204 }
205 else if ((player.shape == SHAPE_GOAT) && (player.learnedBird))
206 {
207 player.shape = SHAPE_BIRD;
208 player.loadTexture('player_bird');
209 }
210 else
211 {
212 player.shape = SHAPE_GIRL;
213 player.loadTexture('player_girl');
214 }
215
216 player.body.setSize(player.texture.width, player.texture.height);
217 if ((ground.y - player.y) < player.body.halfHeight)
218 player.y = ground.y - player.body.halfHeight;
219
220 lastkeytime = game.time.now;
221 }
222
223 if ((cursors.up.isDown) && (player.shape == SHAPE_BIRD))
224 {
225 player.body.velocity.y = -200;
226 }
227
228 }
229
230 function keyPress_indialogue() {
231
232 if (game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR) && ((game.time.now - lastkeytime) > WAIT_KEY))
233 {
234 var dialogue = actual_dialogue.dialogue;
235 if (dialogue[actual_dialogue.state + 1])
236 {
237 var nextState = ++actual_dialogue.state;
238 var actor = null;
239 if (dialogue[nextState].actor == 'player') actor = actual_dialogue.player;
240 else if (dialogue[nextState].actor == 'guard') actor = actual_dialogue.guard;
241
242 actual_dialogue.lastText.kill();
243 actual_dialogue.lastText = putText(actor, dialogue[nextState].text);
244 lastkeytime = game.time.now;
245 }
246 else
247 {
248 leaveDialogue();
249 lastkeytime = game.time.now;
250 }
251 }
252
253 }
254
255 function putText(entity, text) {
256 var textObject = game.add.text(entity.x, entity.y - (entity.height / 2) - 30, text, { align: 'center', fontSize: 14 });
257 textObject.font = 'Ubuntu Mono';
258 textObject.anchor.setTo(.5,.5);
259 return textObject;
260 }
261
262 function interaction(player, guard) {
263
264 console.log('Interaction with ' + guard.key);
265 player.body.velocity.x = -100;
266 player.pushed = game.time.now;
267 guard.body.velocity.x = 0;
268
269 if (player.shape == SHAPE_GIRL)
270 {
271 if ((guard == guard1) && (guard.dialogues.girl == dialogue_guard1_girl))
272 helptext.text = helptext.text + "\nPress SPACE to progress dialogue.";
273 enterDialogue(player, guard, guard.dialogues.girl);
274 }
275 else if (player.shape == SHAPE_GOAT)
276 {
277 enterDialogue(player, guard, guard.dialogues.goat);
278 }
279 else if (player.shape == SHAPE_BIRD)
280 {
281 enterDialogue(player, guard, guard.dialogues.bird);
282 }
283
284 }
285
286 function enterDialogue(player, guard, dialogue) {
287
288 var actor = null;
289 if (dialogue[0].actor == 'player') actor = player;
290 else if (dialogue[0].actor == 'guard') actor = guard;
291
292 var lastText = putText(actor, dialogue[0].text);
293 actual_dialogue = { player: player, guard: guard, dialogue: dialogue, state: 0 , lastText: lastText };
294 keyboard_handler = keyPress_indialogue;
295 interaction_handler = null;
296
297 }
298
299 function leaveDialogue() {
300
301 actual_dialogue.lastText.kill();
302 if (actual_dialogue.dialogue == dialogue_guard1_girl)
303 {
304 helptext.text = helptext.text + "\nPress SPACE to shapeshift.";
305 guard1.dialogues.girl = dialogue_guard1_girl_retry;
306 }
307 else if (actual_dialogue.dialogue == dialogue_guard1_goat)
308 {
309 guard1.kill();
310 }
311 else if (actual_dialogue.dialogue == dialogue_guard2_girl)
312 {
313 guard2.kill();
314 birdcage.kill();
315 player.learnedBird = true;
316 }
317 else if (actual_dialogue.dialogue == dialogue_guard3_girl)
318 {
319 guard3.dialogues.girl = dialogue_guard3_girl_retry;
320 }
321 else if (actual_dialogue.dialogue == dialogue_guard4_goat)
322 {
323 guard4.dialogues.goat = dialogue_guard4_goat_retry;
324 guard4.dialogues.girl = dialogue_guard4_goat_retry;
325 guard4.dialogues.bird = dialogue_guard4_goat_retry;
326 }
327
328 actual_dialogue = null;
329 keyboard_handler = keyPress_default;
330 interaction_handler = interaction;
331
332 }