In game menu settings

This commit is contained in:
Daniel Maixner 2022-12-17 16:17:18 +01:00
parent c2edb4cae9
commit de5edb6313
9 changed files with 149 additions and 26 deletions

View File

@ -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;

View File

@ -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())) {

View File

@ -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',

View File

@ -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 {
<div id="scoreboard-detail"></div>
</div>
<div id="buy-menu" class="hidden"></div>
<div id="game-menu" class="hidden"></div>
<section>
<div class="left">
<div class="top">
@ -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'))

View File

@ -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)
}

View File

@ -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
}

View File

@ -0,0 +1,65 @@
export class GameMenu {
#element
#setting
constructor(element, setting) {
this.#setting = setting
this.#init(element)
}
#init(element) {
element.innerHTML = `
<div data-setting></div>
<div>
<button data-save>Save settings</button>
</div>
<hr>
<div class="flex">
<button onclick="window.location.reload()">Disconnect</button>
<span>&nbsp;</span>
<button onclick="window.close()">Quit game</button>
</div>
`;
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 = `
<div>
<p>Mouse sensitivity:</p>
<p><input name="sensitivity" type="number" min="0.1" max="99" step="0.1" value="${this.#setting.getSensitivity()}"></p>
</div>
<div>
<p>Master volume:</p>
<p><input name="volume" type="number" min="0" max="100" step="1" value="${this.#setting.getMasterVolume()}"></p>
</div>
<div>
<p>Crosshair color:</p>
<p><input name="crosshair-color" type="color" value="#${this.#setting.getCrosshairColor()}"></p>
</div>
`;
}
close() {
this.#element.innerHTML = ''
}
}

View File

@ -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)
}

View File

@ -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)
}
</script>
<script>