Skip to content

Commit bc9bb0a

Browse files
authored
Merge pull request #80 from colinkiama/67-add-controls-menu-option-to-main-menu
Add controls menu option to main menu
2 parents a32bd40 + 9d1efeb commit bc9bb0a

File tree

10 files changed

+206
-13
lines changed

10 files changed

+206
-13
lines changed

src/constants/menu.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,52 @@ export const CREDITS_LIST_ITEMS = [
3636
],
3737
},
3838
];
39+
40+
export const CONTROLS_LIST_ITEMS = [
41+
{
42+
title: 'Keyboard',
43+
controls: [
44+
{
45+
input: 'W',
46+
action: 'Move forward',
47+
},
48+
{
49+
input: 'A',
50+
action: 'Rotate left',
51+
},
52+
{
53+
input: 'S',
54+
action: 'Move backwards',
55+
},
56+
{
57+
input: 'D',
58+
action: 'Rotate right',
59+
},
60+
{
61+
input: 'J',
62+
action: 'Fire laser beam',
63+
},
64+
{
65+
input: 'P',
66+
action: 'Pause',
67+
},
68+
],
69+
},
70+
{
71+
title: 'Touch',
72+
controls: [
73+
{
74+
input: 'Left Joystick Up',
75+
action: 'Move forward',
76+
},
77+
{
78+
input: 'Left Joystick Down',
79+
action: 'Move backwards',
80+
},
81+
{
82+
input: 'Right Joystick',
83+
action: 'Rotate ship and fire laser beam',
84+
},
85+
],
86+
},
87+
];

src/constants/scene.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const SceneKey = {
44
MAIN_MENU: 'MainMenu',
55
BATTLE: 'Battle',
66
PAUSE_MENU: 'PauseMenu',
7+
CONTROLS: 'Controls',
78
CREDITS: 'Credits',
89
HUD: 'HUD',
910
GAME_OVER: 'GameOver',

src/scenes/Controls.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { Scene } from 'phaser';
2+
import {
3+
COLORS,
4+
WEBSITE_URL,
5+
MENU_ITEM_CONFIG,
6+
HOVER_TWEEN_CONFIG,
7+
CONTROLS_LIST_ITEMS,
8+
} from '../constants/menu.js';
9+
10+
import { SceneKey } from '../constants/scene.js';
11+
import { DependencyKey } from '../constants/injector.js';
12+
import { SoundFXKey } from '../constants/audio.js';
13+
14+
export class Controls extends Scene {
15+
injector;
16+
_audioSystem;
17+
18+
constructor() {
19+
super(SceneKey.CONTROLS);
20+
}
21+
22+
setupDependencies() {
23+
this._audioSystem = this.injector.get(DependencyKey.AUDIO_SYSTEM);
24+
}
25+
26+
create(data) {
27+
this.cameras.main.setBackgroundColor(0x00000000);
28+
29+
const title = this.add
30+
.text(320, 40, 'Controls', {
31+
fontFamily: 'usuzi',
32+
fontSize: 40,
33+
})
34+
.setOrigin(0.5, 0);
35+
36+
this.tweens.add({
37+
targets: title,
38+
...HOVER_TWEEN_CONFIG,
39+
});
40+
41+
// Insert controls text here...
42+
let lastSectionItem = title;
43+
44+
for (let i = 0; i < CONTROLS_LIST_ITEMS.length; i++) {
45+
const section = CONTROLS_LIST_ITEMS[i];
46+
lastSectionItem = this.add
47+
.text(
48+
320,
49+
lastSectionItem.y + lastSectionItem.height + (i === 0 ? 20 : 16),
50+
section.title,
51+
{
52+
fontFamily: 'usuzi',
53+
fontSize: 18,
54+
},
55+
)
56+
.setOrigin(0.5, 0);
57+
58+
let previousListItem = lastSectionItem;
59+
const controls = section.controls;
60+
for (let j = 0; j < controls.length; j++) {
61+
const listItem = controls[j];
62+
previousListItem = this.add
63+
.text(
64+
320,
65+
previousListItem.y + previousListItem.height + (j === 0 ? 8 : 4),
66+
`${listItem.input} - ${listItem.action}`,
67+
{
68+
fontFamily: 'usuzi',
69+
fontSize: 14,
70+
},
71+
)
72+
.setOrigin(0.5, 0);
73+
74+
const href = listItem.href;
75+
if (href) {
76+
previousListItem.setInteractive(MENU_ITEM_CONFIG);
77+
previousListItem.on('pointerover', onButtonHover);
78+
previousListItem.on('pointerover', onButtonHoverForInstance, this);
79+
previousListItem.on('pointerout', onButtonOut);
80+
previousListItem.on('pointerup', () => {
81+
this._audioSystem.playSFX(SoundFXKey.ITEM_SELECTION);
82+
window.open(href, '_blank');
83+
});
84+
}
85+
86+
if (j === controls.length - 1) {
87+
lastSectionItem = previousListItem;
88+
}
89+
}
90+
}
91+
92+
const backButton = this.add
93+
.text(320, 340, 'Go back', {
94+
fontFamily: 'usuzi',
95+
fontSize: 16,
96+
color: COLORS.foreground,
97+
})
98+
.setOrigin(0.5, 1)
99+
.setInteractive(MENU_ITEM_CONFIG);
100+
101+
backButton.on('pointerover', onButtonHover);
102+
backButton.on('pointerover', onButtonHoverForInstance, this);
103+
backButton.on('pointerout', onButtonOut);
104+
backButton.on('pointerup', () => {
105+
this._audioSystem.playSFX(SoundFXKey.ITEM_SELECTION);
106+
this.scene.start(data.returnScene);
107+
});
108+
}
109+
}
110+
111+
function onButtonHoverForInstance() {
112+
this._audioSystem.playSFX(SoundFXKey.ITEM_HOVER);
113+
}
114+
115+
function onButtonHover() {
116+
this.setColor(COLORS.hoverForeground);
117+
}
118+
119+
function onButtonOut() {
120+
this.setColor(COLORS.foreground);
121+
}

src/scenes/Credits.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export class Credits extends Scene {
9999
backButton.on('pointerover', onButtonHoverForInstance, this);
100100
backButton.on('pointerout', onButtonOut);
101101
backButton.on('pointerup', () => {
102-
this._audioSystem.playSFX(SoundFXKey.ITEM_SELECTION)
102+
this._audioSystem.playSFX(SoundFXKey.ITEM_SELECTION);
103103
this.scene.start(SceneKey.MAIN_MENU, { playMusic: false });
104104
});
105105
}

src/scenes/GameOver.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export class GameOver extends Scene {
9595
at: 2750,
9696
run: () => {
9797
this._vfxSystem.shakeScreen(ScreenShakeType.HIGH_SCORE);
98-
crossSceneEventEmitter.emit(CrossSceneEvent.NEW_HIGH_SCORE_REVEAL);
98+
crossSceneEventEmitter.emit(
99+
CrossSceneEvent.NEW_HIGH_SCORE_REVEAL,
100+
);
99101
this._audioSystem.playSFX(SoundFXKey.EXPLOSION);
100102
this.revealStat('highScore', {
101103
showExplosion: true,

src/scenes/MainMenu.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ export class MainMenu extends Scene {
5858
label: 'Sound: On',
5959
action: this.onSoundToggle,
6060
},
61+
{
62+
label: 'Controls',
63+
action: this.showControls,
64+
},
6165
{
6266
label: 'Credits',
6367
action: this.showCredits,
@@ -78,6 +82,13 @@ export class MainMenu extends Scene {
7882
this._menuSystem.shutDownCurrentMenu();
7983
});
8084
}
85+
86+
showControls() {
87+
this.scene.start(SceneKey.CONTROLS, {
88+
returnScene: SceneKey.MAIN_MENU,
89+
});
90+
}
91+
8192
showCredits() {
8293
this.scene.start(SceneKey.CREDITS);
8394
}

src/scenes/PauseMenu.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ export class PauseMenu extends Scene {
3333
},
3434
{
3535
label: 'Toggle Full Screen',
36-
action: this.onFullScreenToggle
36+
action: this.onFullScreenToggle,
37+
},
38+
{
39+
label: 'Controls',
40+
action: this.showControls,
3741
},
3842
{
3943
label: 'Sound: On',
@@ -69,6 +73,12 @@ export class PauseMenu extends Scene {
6973
});
7074
}
7175

76+
showControls() {
77+
this.scene.start(SceneKey.CONTROLS, {
78+
returnScene: SceneKey.PAUSE_MENU,
79+
});
80+
}
81+
7282
resumeGame() {
7383
this._menuSystem.shutDownCurrentMenu();
7484
crossSceneEventEmitter.emit(CrossSceneEvent.RESUME_GAME);

src/scenes/Preloader.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import { Scene } from 'phaser';
22
import { SceneKey } from '../constants/scene.js';
33
import { LocalStorageKey, RegistryKey } from '../constants/data.js';
4-
import { COLORS, MENU_ITEM_CONFIG } from '../constants/menu.js';
5-
import { onButtonHover, onButtonOut } from '../utils/ui.js';
64
import { MenuSystem } from '../systems/menuSystem.js';
75
import { Injector } from '../utils/injector.js';
86
import { DependencyKey } from '../constants/injector.js';
9-
import { AudioSystem } from '../systems/audioSystem.js';
107
import { AudioKey, SoundFXKey } from '../constants/audio.js';
118

129
const PROGRESS_BAR_WIDTH = 300;
@@ -18,6 +15,7 @@ const SCENES_TO_LOAD = [
1815
'PauseMenu',
1916
'GameOver',
2017
'Credits',
18+
'Controls',
2119
];
2220

2321
let dependencyInjector;
@@ -189,7 +187,9 @@ export class Preloader extends Scene {
189187
this.progressBar.setVisible(false);
190188
this.progressBarFill.setVisible(false);
191189

192-
this._menuSystem = new MenuSystem(this, dependencyInjector, { muted: true});
190+
this._menuSystem = new MenuSystem(this, dependencyInjector, {
191+
muted: true,
192+
});
193193
this._menuSystem.start(
194194
[
195195
{

src/systems/audioSystem.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class AudioSystem {
5858
const keys = this._pausedAudio.keys().toArray();
5959
keys.forEach((key) => {
6060
const audio = this._pausedAudio.get(key);
61-
audio.resume()
61+
audio.resume();
6262
this._pausedAudio.delete(key);
6363
});
6464
}

src/systems/menuSystem.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export class MenuSystem {
146146
if (menuItem.isInteractive) {
147147
const menuItemGameObject = this._currentMenuContainer.getAt(i);
148148
menuItemGameObject.off('pointerover', onButtonHover);
149-
menuItemGameObject.off('pointerover', onButtonHoverForInstance, this)
149+
menuItemGameObject.off('pointerover', onButtonHoverForInstance, this);
150150

151151
menuItemGameObject.off('pointerout', onButtonOut);
152152
if (menuItem.action) {
@@ -163,7 +163,7 @@ export class MenuSystem {
163163
if (footerItem.isInteractive) {
164164
const footerItemGameObject = this._currentMenuContainer.getAt(i);
165165
footerItemGameObject.off('pointerover', onButtonHover);
166-
footerItemGameObject.off('pointerover', onButtonHoverForInstance, this)
166+
footerItemGameObject.off('pointerover', onButtonHoverForInstance, this);
167167

168168
footerItemGameObject.off('pointerout', onButtonOut);
169169
if (footerItem.action) {
@@ -172,7 +172,6 @@ export class MenuSystem {
172172
}
173173
}
174174
}
175-
176175
}
177176

178177
async pop() {
@@ -339,7 +338,7 @@ export class MenuSystem {
339338
if (menuItem.isInteractive === undefined || menuItem.isInteractive) {
340339
menuItemGameObject.setInteractive(MENU_ITEM_CONFIG);
341340
menuItemGameObject.on('pointerover', onButtonHover);
342-
menuItemGameObject.on('pointerover', onButtonHoverForInstance, this)
341+
menuItemGameObject.on('pointerover', onButtonHoverForInstance, this);
343342
menuItemGameObject.on('pointerout', onButtonOut);
344343
if (menuItem.action) {
345344
menuItemGameObject.on('pointerup', onButtonUpForInstance, this);
@@ -448,5 +447,5 @@ function recentreMenu(scene, menuContainer) {
448447

449448
function realignFooter(scene, footerContainer) {
450449
const bounds = footerContainer.getBounds();
451-
footerContainer.y = scene.cameras.main.height - bounds.height - 20;
450+
footerContainer.y = scene.cameras.main.height - bounds.height - 12;
452451
}

0 commit comments

Comments
 (0)