From de5edb631312107e0ad4b98662f50c5a89bc9078 Mon Sep 17 00:00:00 2001 From: Daniel Maixner Date: Sat, 17 Dec 2022 16:17:18 +0100 Subject: [PATCH] In game menu settings --- www/assets/css/hud.css | 17 ++++++++- www/assets/js/Control.js | 20 +++++------ www/assets/js/Enums.js | 1 + www/assets/js/Hud.js | 26 ++++++++++++-- www/assets/js/PlayerAction.js | 1 + www/assets/js/Setting.js | 25 ++++++++++++-- www/assets/js/hud/GameMenu.js | 65 +++++++++++++++++++++++++++++++++++ www/assets/js/start.js | 14 ++++---- www/index.html | 6 ++-- 9 files changed, 149 insertions(+), 26 deletions(-) create mode 100644 www/assets/js/hud/GameMenu.js diff --git a/www/assets/css/hud.css b/www/assets/css/hud.css index 91193b8..abb94a0 100644 --- a/www/assets/css/hud.css +++ b/www/assets/css/hud.css @@ -91,6 +91,7 @@ } #hud #scoreboard, +#hud #game-menu, #hud #buy-menu { font-size: 16px; padding: 1rem; @@ -106,10 +107,24 @@ overflow-y: auto; } -#hud #buy-menu { +#hud #buy-menu, #hud #game-menu { pointer-events: initial; } +#hud #game-menu div[data-setting] > div { + margin: 0 2px 12px 2px; +} + +#hud #game-menu div[data-setting] input { + display: block; + width: 100%; + padding: 4px 10px; +} + +#hud #game-menu button { + font-size: 1rem; +} + #hud #buy-menu p.disabled { pointer-events: none; text-decoration: line-through; diff --git a/www/assets/js/Control.js b/www/assets/js/Control.js index dac501d..c8d135e 100644 --- a/www/assets/js/Control.js +++ b/www/assets/js/Control.js @@ -10,21 +10,20 @@ export class Control { this.#action = action } - init(pointer, setting) { + init(element, pointer, setting) { this.#setting = setting const self = this const action = this.#action const game = this.#game const sprayEnableSlots = [InventorySlot.SLOT_KNIFE, InventorySlot.SLOT_PRIMARY, InventorySlot.SLOT_BOMB] - document.addEventListener("mouseup", function (event) { - event.preventDefault() - + element.addEventListener("mouseup", function (event) { + if (pointer.isLocked) { + event.preventDefault() + } action.sprayingDisable() }) - document.addEventListener("mousedown", function (event) { - event.preventDefault() - + element.addEventListener("mousedown", function (event) { action.sprayingDisable() if (!game.isPlaying() || game.isPaused()) { return @@ -36,6 +35,7 @@ export class Control { if (!pointer.isLocked) { return; } + event.preventDefault() if (event.buttons === 2) { action.attack2() @@ -49,7 +49,7 @@ export class Control { } } }) - document.addEventListener('wheel', (event) => { + element.addEventListener('wheel', (event) => { if (!game.isPlaying() || !game.meIsAlive()) { return } @@ -68,7 +68,7 @@ export class Control { } } }) - document.addEventListener('keydown', function (event) { + element.addEventListener('keydown', function (event) { event.preventDefault() if (!game.isPlaying() || !game.meIsAlive()) { @@ -77,7 +77,7 @@ export class Control { self.#processKeyboardEvent(event, true) }); - document.addEventListener('keyup', function (event) { + element.addEventListener('keyup', function (event) { event.preventDefault() if (!(game.isPlaying() && game.meIsAlive())) { diff --git a/www/assets/js/Enums.js b/www/assets/js/Enums.js index f74b468..1c78517 100644 --- a/www/assets/js/Enums.js +++ b/www/assets/js/Enums.js @@ -196,6 +196,7 @@ const Action = { EQUIP_SECONDARY: 'equip_secondary', EQUIP_BOMB: 'equip_bomb', BUY_MENU: 'buy_menu', + GAME_MENU: 'game_menu', SCORE_BOARD: 'score_board', DROP: 'drop', USE: 'use', diff --git a/www/assets/js/Hud.js b/www/assets/js/Hud.js index 095ed00..9802c56 100644 --- a/www/assets/js/Hud.js +++ b/www/assets/js/Hud.js @@ -4,22 +4,26 @@ import {ScoreBoard} from "./hud/ScoreBoard.js"; import {KillFeed} from "./hud/KillFeed.js"; import {Radar} from "./hud/Radar.js"; import {HitFeedback} from "./hud/HitFeedback.js"; +import {GameMenu} from "./hud/GameMenu.js"; export class HUD { #game #buyMenu = null; #scoreBoard = null; + #gameMenu = null; #killFeed = null; #hitFeedback = null; #radar = null; #showAble = { showScore: false, - showBuyMenu: false + showBuyMenu: false, + showGameMenu: false, } #elements = { score: null, scoreDetail: null, buyMenu: null, + gameMenu: null, canBuyIcon: null, canPlantIcon: null, haveDefuseKit: null, @@ -59,6 +63,10 @@ export class HUD { this.#showAble.showBuyMenu = !this.#showAble.showBuyMenu } + toggleGameMenu() { + this.#showAble.showGameMenu = !this.#showAble.showGameMenu + } + toggleScore(enabled) { this.#showAble.showScore = enabled } @@ -193,6 +201,16 @@ export class HUD { this.#elements.buyMenu.classList.add('hidden'); this.#showAble.showBuyMenu = false } + if (this.#showAble.showGameMenu) { + this.#game.requestPointerUnLock() + this.#gameMenu.show() + this.#elements.gameMenu.classList.remove('hidden'); + } else if (!this.#elements.gameMenu.classList.contains('hidden')) { + this.#game.requestPointerLock() + this.#gameMenu.close() + this.#elements.gameMenu.classList.add('hidden'); + this.#showAble.showGameMenu = false + } this.#elements.money.innerText = player.money this.#elements.health.innerText = player.health @@ -230,6 +248,7 @@ export class HUD {
+
@@ -286,6 +305,7 @@ export class HUD { this.#elements.score = elementHud.querySelector('#scoreboard') this.#elements.buyMenu = elementHud.querySelector('#buy-menu') + this.#elements.gameMenu = elementHud.querySelector('#game-menu') this.#elements.canBuyIcon = elementHud.querySelector('[data-can-buy]') this.#elements.canPlantIcon = elementHud.querySelector('[data-can-plant]') this.#elements.haveDefuseKit = elementHud.querySelector('[data-have-defuse-kit]') @@ -311,11 +331,13 @@ export class HUD { const cross = elementHud.querySelector('#cross') cross.innerText = setting.getCrosshairSymbol() - cross.style.color = '#' + setting.getCrosshairColor() + setting.addUpdateCallback('crosshairColor', (newValue) => cross.style.color = '#' + newValue) + setting.update('crosshairColor', setting.getCrosshairColor()) const game = this.#game this.#buyMenu = new BuyMenu(this.#elements.buyMenu) this.#scoreBoard = new ScoreBoard(game, this.#elements.scoreDetail) + this.#gameMenu = new GameMenu(this.#elements.gameMenu, setting) this.#killFeed = new KillFeed(this.#scoreBoard, this.#elements.killFeed) this.#hitFeedback = new HitFeedback(elementHud.querySelector('#hit-feedback')) diff --git a/www/assets/js/PlayerAction.js b/www/assets/js/PlayerAction.js index ab04a8c..39e4fe9 100644 --- a/www/assets/js/PlayerAction.js +++ b/www/assets/js/PlayerAction.js @@ -44,6 +44,7 @@ export class PlayerAction { this.actionCallback[Action.EQUIP_SECONDARY] = (enabled) => enabled && this.equip(InventorySlot.SLOT_SECONDARY) this.actionCallback[Action.EQUIP_BOMB] = (enabled) => enabled && this.equip(InventorySlot.SLOT_BOMB) this.actionCallback[Action.BUY_MENU] = (enabled) => enabled && hud.toggleBuyMenu() + this.actionCallback[Action.GAME_MENU] = (enabled) => enabled && hud.toggleGameMenu() this.actionCallback[Action.SCORE_BOARD] = (enabled) => hud.toggleScore(enabled) } diff --git a/www/assets/js/Setting.js b/www/assets/js/Setting.js index a6d38d1..c198e37 100644 --- a/www/assets/js/Setting.js +++ b/www/assets/js/Setting.js @@ -1,6 +1,7 @@ import {Action} from "./Enums.js"; export class Setting { + #onUpdate = {} #setting = { base: { fov: 70, @@ -32,23 +33,41 @@ export class Setting { 'Digit5': Action.EQUIP_BOMB, 'KeyB': Action.BUY_MENU, 'Tab': Action.SCORE_BOARD, + 'Backquote': Action.GAME_MENU, }, } constructor(settingString = null) { if (settingString) { - this.loadSettings(JSON.parse(settingString)) + this.loadSettings(settingString) } } - loadSettings(settingObject) { - this.#setting = settingObject + loadSettings(json) { + this.#setting = JSON.parse(json) } getSetting() { return JSON.parse(JSON.stringify(this.#setting)) } + getJson() { + return JSON.stringify(this.#setting) + } + + addUpdateCallback(key, callback) { + this.#onUpdate[key] = callback + } + + update(key, value) { + const callback = this.#onUpdate[key] + if (callback === undefined) { + return + } + callback(value) + this.#setting.base[key] = value + } + getBinds() { return this.#setting.bind } diff --git a/www/assets/js/hud/GameMenu.js b/www/assets/js/hud/GameMenu.js new file mode 100644 index 0000000..833fdce --- /dev/null +++ b/www/assets/js/hud/GameMenu.js @@ -0,0 +1,65 @@ +export class GameMenu { + #element + #setting + + constructor(element, setting) { + this.#setting = setting + this.#init(element) + } + + #init(element) { + element.innerHTML = ` +
+
+ +
+
+
+ +   + +
+ `; + this.#element = element.querySelector('[data-setting]') + element.addEventListener('keydown', (e) => e.target.matches('input,textarea') && e.stopPropagation()) + element.addEventListener('keyup', (e) => e.target.matches('input,textarea') && e.stopPropagation()) + element.querySelector('[data-save]').addEventListener('click', () => this.#saveSetting()) + } + + #saveSetting() { + const setting = this.#setting + setting.update('sensitivity', parseFloat(this.#element.querySelector('input[name="sensitivity"]').value)) + setting.update('volume', parseFloat(this.#element.querySelector('input[name="volume"]').value)) + setting.update('crosshairColor', this.#element.querySelector('input[name="crosshair-color"]').value.substring(1)) + + const json = setting.getJson() + setting.loadSettings(json) + window.localStorage.setItem('setting', json) + } + + show() { + if (this.#element.innerHTML !== '') { + return; + } + + this.#element.innerHTML = ` +
+

Mouse sensitivity:

+

+
+
+

Master volume:

+

+
+
+

Crosshair color:

+

+
+ `; + } + + close() { + this.#element.innerHTML = '' + } + +} diff --git a/www/assets/js/start.js b/www/assets/js/start.js index ed90e62..ee7afff 100644 --- a/www/assets/js/start.js +++ b/www/assets/js/start.js @@ -52,17 +52,13 @@ let launchGame const setting = new Setting(settingString) const canvas = await world.init(map, setting) - const pointerLock = new THREE.PointerLockControls(world.getCamera(), document.body) + const pointerLock = new THREE.PointerLockControls(world.getCamera(), canvasParent) pointerLock.pointerSpeed = setting.getSensitivity() + hud.createHud(elementHud, map, setting) - control.init(pointerLock, setting) + control.init(canvasParent, pointerLock, setting) game.setDependency(pointerLock, setting.shouldMatchServerFps()) - document.addEventListener("click", function (e) { - if (e.target.classList.contains('hud-action')) { - return - } - game.requestPointerLock() - }, {capture: true}) + canvas.addEventListener("click", () => game.requestPointerLock()) canvasParent.appendChild(canvas) stats.dom.style.position = 'inherit' elementHud.querySelector('#fps-stats').appendChild(stats.dom) @@ -83,6 +79,8 @@ let launchGame } }) + setting.addUpdateCallback('sensitivity', (newValue) => pointerLock.pointerSpeed = parseFloat(newValue)) + setting.addUpdateCallback('volume', (newValue) => world.volume = parseFloat(newValue)) connector.connect(url.hostname, url.port, loginCode) } diff --git a/www/index.html b/www/index.html index 7ddaf30..353121c 100644 --- a/www/index.html +++ b/www/index.html @@ -58,13 +58,15 @@ const settingElement = document.getElementById('setting-form') if (settingElement) { + let userSettingObject const userSettings = localStorage.getItem('setting') if (userSettings === null || userSettings === '') { const setting = new Setting() - settingElement.value = JSON.stringify(setting.getSetting(), null, 2) + userSettingObject = setting.getSetting() } else { - settingElement.value = userSettings + userSettingObject = JSON.parse(userSettings) } + settingElement.value = JSON.stringify(userSettingObject, null, 2) }