diff --git a/src/en/replay/index.html b/src/en/replay/index.html index bae376a7..122bd1f6 100644 --- a/src/en/replay/index.html +++ b/src/en/replay/index.html @@ -68,6 +68,22 @@ +
+
+ +
+ + diff --git a/src/ko/replay/index.html b/src/ko/replay/index.html index 1d5a502c..12590fc9 100644 --- a/src/ko/replay/index.html +++ b/src/ko/replay/index.html @@ -65,6 +65,22 @@ +
+
+ +
+ + diff --git a/src/resources/js/replay/pikavolley_replay.js b/src/resources/js/replay/pikavolley_replay.js index 5a2ffaaa..93a1ae9e 100644 --- a/src/resources/js/replay/pikavolley_replay.js +++ b/src/resources/js/replay/pikavolley_replay.js @@ -9,7 +9,11 @@ import { import { Cloud, Wave } from '../offline_version_js/cloud_and_wave.js'; import { PikaPhysics } from '../offline_version_js/physics.js'; import { convert5bitNumberToUserInput } from '../utils/input_conversion.js'; -import { noticeEndOfReplay, moveScrubberTo } from './ui_replay.js'; +import { + noticeEndOfReplay, + moveScrubberTo, + showKeyboardInputs, +} from './ui_replay.js'; import { setTickerMaxFPSAccordingToNormalFPS } from './replay_player.js'; /** @typedef GameState @type {function():void} */ @@ -236,6 +240,7 @@ export class PikachuVolleyballReplay extends PikachuVolleyball { this.player2Keyboard.xDirection = player2Input.xDirection; this.player2Keyboard.yDirection = player2Input.yDirection; this.player2Keyboard.powerHit = player2Input.powerHit; + showKeyboardInputs(player1Input, player2Input); let options = this.options[this.optionsCounter]; while (options && options[0] === this.replayFrameCounter) { diff --git a/src/resources/js/replay/ui_replay.js b/src/resources/js/replay/ui_replay.js index dd2fb441..73bfd9e0 100644 --- a/src/resources/js/replay/ui_replay.js +++ b/src/resources/js/replay/ui_replay.js @@ -1,6 +1,8 @@ import { replayPlayer } from './replay_player.js'; import '../../style.css'; +/** @typedef {import('../offline_version_js/physics.js').PikaUserInput} PikaUserInput */ + let pausedByBtn = false; const scrubberRangeInput = document.getElementById('scrubber-range-input'); @@ -189,6 +191,23 @@ export function setUpUI() { noticeBoxFileErrorOKBtn.addEventListener('click', () => { location.reload(); }); + + const keyboardContainer = document.getElementById('keyboard-container'); + const showHideKeyboardBtn = document.getElementById('show-hide-keyboard-btn'); + const showOrHideSpan = document.getElementById('show-or-hide-span'); + showHideKeyboardBtn.addEventListener('click', () => { + if (!keyboardContainer.classList.contains('hidden')) { + keyboardContainer.classList.add('hidden'); + showOrHideSpan.textContent = document.getElementById( + 'show-text' + ).textContent; + } else { + keyboardContainer.classList.remove('hidden'); + showOrHideSpan.textContent = document.getElementById( + 'hide-text' + ).textContent; + } + }); } export function adjustPlayPauseBtnIcon() { @@ -255,6 +274,109 @@ export function showTotalTimeDuration(timeDuration) { ); } +/** + * Show Keyboard inputs + * @param {PikaUserInput} player1Input + * @param {PikaUserInput} player2Input + */ +export function showKeyboardInputs(player1Input, player2Input) { + const zKey = document.getElementById('z-key'); + const rKey = document.getElementById('r-key'); + const vKey = document.getElementById('v-key'); + const dKey = document.getElementById('d-key'); + const gKey = document.getElementById('g-key'); + + const enterKey = document.getElementById('enter-key'); + const upKey = document.getElementById('up-key'); + const downKey = document.getElementById('down-key'); + const leftKey = document.getElementById('left-key'); + const rightKey = document.getElementById('right-key'); + + function pressKeyElm(keyElm) { + if (!keyElm.classList.contains('pressed')) { + keyElm.classList.add('pressed'); + } + } + + function unpressKeyElm(keyElm) { + keyElm.classList.remove('pressed'); + } + + switch (player1Input.xDirection) { + case 0: + unpressKeyElm(dKey); + unpressKeyElm(gKey); + break; + case -1: + pressKeyElm(dKey); + unpressKeyElm(gKey); + break; + case 1: + unpressKeyElm(dKey); + pressKeyElm(gKey); + break; + } + switch (player1Input.yDirection) { + case 0: + unpressKeyElm(rKey); + unpressKeyElm(vKey); + break; + case -1: + pressKeyElm(rKey); + unpressKeyElm(vKey); + break; + case 1: + unpressKeyElm(rKey); + pressKeyElm(vKey); + break; + } + switch (player1Input.powerHit) { + case 0: + unpressKeyElm(zKey); + break; + case 1: + pressKeyElm(zKey); + break; + } + + switch (player2Input.xDirection) { + case 0: + unpressKeyElm(leftKey); + unpressKeyElm(rightKey); + break; + case -1: + pressKeyElm(leftKey); + unpressKeyElm(rightKey); + break; + case 1: + unpressKeyElm(leftKey); + pressKeyElm(rightKey); + break; + } + switch (player2Input.yDirection) { + case 0: + unpressKeyElm(upKey); + unpressKeyElm(downKey); + break; + case -1: + pressKeyElm(upKey); + unpressKeyElm(downKey); + break; + case 1: + unpressKeyElm(upKey); + pressKeyElm(downKey); + break; + } + switch (player2Input.powerHit) { + case 0: + unpressKeyElm(enterKey); + break; + case 1: + pressKeyElm(enterKey); + break; + } +} + export function enableReplayScrubberAndBtns() { // @ts-ignore scrubberRangeInput.disabled = false; diff --git a/src/resources/style.css b/src/resources/style.css index b1351b67..6fa2d367 100644 --- a/src/resources/style.css +++ b/src/resources/style.css @@ -601,3 +601,56 @@ label.custom-file-upload { .disable-dbl-tap-zoom { touch-action: manipulation; } +.flex-for-keyboard { + display: flex; + flex-direction: row; + justify-content: space-around; + margin-top: 10px; +} +.grid-for-keyboard { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr; + gap: 5px; + width: calc(5 * var(--btn-height)); + height: calc(2.3 * var(--btn-height)); +} +#z-key, +#enter-key { + grid-row-start: 1; + grid-column-start: 1; +} +#r-key, +#up-key { + grid-row-start: 1; + grid-column-start: 3; +} +#d-key, +#left-key { + grid-row-start: 2; + grid-column-start: 2; +} +#v-key, +#down-key { + grid-row-start: 2; + grid-column-start: 3; +} +#g-key, +#right-key { + grid-row-start: 2; + grid-column-start: 4; +} +.keyboard-key { + display: flex; + justify-content: center; + align-items: center; + border: 2px solid rgb(50, 50, 50); +} +.keyboard-key.pressed { + background-color: rgb(255, 0, 0); + color: white; +} +#show-hide-keyboard-btn { + font-size: calc(var(--font-size) / 1.3); + width: var(--btn-width); +}