game: cleanup

This commit is contained in:
He4eT 2025-06-10 01:19:42 +02:00
commit 0f2fba693f

114
game.js
View file

@ -37,26 +37,27 @@ const morseCode = [
['Z', ' --.. '], ['Z', ' --.. '],
].map(([letter, code]) => [letter, code.trim()]) ].map(([letter, code]) => [letter, code.trim()])
const alphabet = morseCode.map(([letter]) => letter)
const letterToMorse = Object.fromEntries(morseCode) const letterToMorse = Object.fromEntries(morseCode)
const morseToLetter = Object.fromEntries( const morseToLetter = Object.fromEntries(
morseCode.map((pair) => pair.reverse()), morseCode.map((pair) => pair.reverse()),
) )
/* Screens */
function TIC() { function TIC() {
gameStages[currentStage]() gameScreens[currentScreen]()
} }
/* Stages */ /** @type {keyof typeof gameScreens} */
let currentScreen = 'startScreen'
const gameStages = { const gameScreens = {
startScreen, startScreen,
gameScreen, gameScreen,
gameoverScreen, gameoverScreen,
} }
/** @type {keyof typeof gameStages} */
let currentStage = 'startScreen'
/* State */ /* State */
/** @type {Arena} */ /** @type {Arena} */
@ -113,6 +114,7 @@ let effects = []
function startScreen() { function startScreen() {
cls() cls()
const title = 'Morse Pit' const title = 'Morse Pit'
print(title, 12, 12, 3, false, 2) print(title, 12, 12, 3, false, 2)
@ -120,7 +122,7 @@ function startScreen() {
print(instruction, 12, 30, 4) print(instruction, 12, 30, 4)
if (anyKeyPressed()) { if (anyKeyPressed()) {
currentStage = 'gameScreen' currentScreen = 'gameScreen'
} }
} }
@ -148,26 +150,26 @@ function gameover() {
frames: '7777777777654321000000000000000000'.split(''), frames: '7777777777654321000000000000000000'.split(''),
}, },
] ]
currentStage = 'gameoverScreen' currentScreen = 'gameoverScreen'
} }
/* Gameplay */ /* Gameplay */
function gameScreen() { function gameScreen() {
checkColisions() checkColisions()
spawnEnemies() spawnEnemies()
handleMoves()
moveEnemies() moveEnemies()
handleMorse()
drawInterface() drawInterface()
drawArena() drawArena()
drawFX() drawFX()
drawEnemies() drawEnemies()
drawPlayer() drawPlayer()
drawLetters() drawLetters()
handleMoves()
handleMorse()
} }
/* Interface */ /* Interface */
@ -176,31 +178,12 @@ function drawInterface() {
cls(0) cls(0)
} }
function drawSprite(spriteIndex, x, y) {
const colorkey = 0
const center = arenaToScreen({ x, y })
spr(
spriteIndex,
center.x - arena.spriteHalfSize,
center.y - arena.spriteHalfSize,
colorkey,
)
}
/* Arena */ /* Arena */
function drawArena() { function drawArena() {
map(0, 0, 30, 15) map(0, 0, 30, 15)
} }
function arenaToScreen({ x, y }) {
return {
x: x + arena.screenPosition.x,
y: y + arena.screenPosition.y,
}
}
/* Player */ /* Player */
function handleMoves() { function handleMoves() {
@ -212,19 +195,20 @@ function handleMoves() {
if (btn(BTN_U)) dy -= 1 if (btn(BTN_U)) dy -= 1
if (btn(BTN_D)) dy += 1 if (btn(BTN_D)) dy += 1
const { speed } = playerStates[player.state] const norm =
playerStates[player.state].speed /
([dx, dy].every((d) => d !== 0) ? Math.SQRT2 : 1)
const norm = speed / ([dx, dy].every((d) => d !== 0) ? Math.SQRT2 : 1) player.position = {
const { bounds } = arena x: Math.max(
arena.bounds.left,
player.position.x = Math.max( Math.min(arena.bounds.right, player.position.x + dx * norm),
bounds.left, ),
Math.min(bounds.right, player.position.x + dx * norm), y: Math.max(
) arena.bounds.top,
player.position.y = Math.max( Math.min(arena.bounds.bottom, player.position.y + dy * norm),
bounds.top, ),
Math.min(bounds.bottom, player.position.y + dy * norm), }
)
} }
function playMorseKey(seed) { function playMorseKey(seed) {
@ -245,34 +229,34 @@ function handleMorse() {
const buttonPressed = [BTN_A, BTN_B, BTN_X, BTN_Y].map(btn).some(Boolean) const buttonPressed = [BTN_A, BTN_B, BTN_X, BTN_Y].map(btn).some(Boolean)
// Down /* Down */
if (buttonPressed && !key.isDown) { if (buttonPressed && !key.isDown) {
key.isDown = true key.isDown = true
key.downAt = now key.downAt = now
} }
// Hold /* Hold */
if (buttonPressed && key.isDown) { if (buttonPressed && key.isDown) {
const isDash = now - key.downAt > DOT_DASH_THRESHOLD const isDash = now - key.downAt > DOT_DASH_THRESHOLD
player.state = isDash ? 'dash' : 'dot' player.state = isDash ? 'dash' : 'dot'
playMorseKey(arena.waveSeed) playMorseKey(arena.waveSeed)
} }
// Release /* Release */
if (!buttonPressed && key.isDown) { if (!buttonPressed && key.isDown) {
player.state = 'default' player.state = 'default'
key.isDown = false key.isDown = false
key.upAt = now key.upAt = now
key.buffer += key.upAt - key.downAt < DOT_DASH_THRESHOLD ? '.' : '-' key.buffer += key.upAt - key.downAt < DOT_DASH_THRESHOLD ? '.' : '-'
effects.unshift({ effects.push({
type: 'detection', type: 'detection',
frames: [8], frames: [8],
to: player.position, to: player.position,
}) })
} }
// Flush /* Flush */
if ( if (
!buttonPressed && !buttonPressed &&
key.buffer.length > 0 && key.buffer.length > 0 &&
@ -403,11 +387,6 @@ function spawnEnemies() {
return 8 return 8
} }
const getRandomLetter = () => {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
return alphabet[rnd(0, alphabet.length - 1)]
}
const getSpawnPosition = () => { const getSpawnPosition = () => {
const minDistance = 12 * arena.spriteHalfSize const minDistance = 12 * arena.spriteHalfSize
const b = 4 * arena.spriteHalfSize const b = 4 * arena.spriteHalfSize
@ -426,14 +405,14 @@ function spawnEnemies() {
const type = getType(arena.wave) const type = getType(arena.wave)
return { return {
type, type,
letter: getRandomLetter(), letter: alphabet[rnd(0, alphabet.length - 1)],
positions: [getSpawnPosition(), getSpawnPosition()], positions: [getSpawnPosition(), getSpawnPosition()],
dangerZone: getDangerZone(type), dangerZone: getDangerZone(type),
} }
}) })
enemies.forEach((enemy) => { enemies.forEach((enemy) => {
effects.unshift({ effects.push({
type: 'detection', type: 'detection',
to: enemy.positions[0], to: enemy.positions[0],
frames: arr(10, 4), frames: arr(10, 4),
@ -461,7 +440,7 @@ function destroyEnemiesByLetter(letter) {
const [type, frames] = const [type, frames] =
destructionEffects[rnd(0, destructionEffects.length - 1)] destructionEffects[rnd(0, destructionEffects.length - 1)]
effects.unshift({ effects.push({
type, type,
frames, frames,
from: player.position, from: player.position,
@ -515,7 +494,8 @@ function drawLetters() {
const screenPos = arenaToScreen(letterPos) const screenPos = arenaToScreen(letterPos)
rect(screenPos.x - 7, screenPos.y - 7, 16, 16, 5) rect(screenPos.x - 7, screenPos.y - 7, 16, 16, 4)
rectb(screenPos.x - 7, screenPos.y - 7, 16, 16, 3)
print(enemy.letter, screenPos.x - 4, screenPos.y - 4, 2, false, 2) print(enemy.letter, screenPos.x - 4, screenPos.y - 4, 2, false, 2)
}) })
} }
@ -586,7 +566,6 @@ function arr(n, filler) {
for (let i = 0; i < n; i++) { for (let i = 0; i < n; i++) {
result.push(filler) result.push(filler)
} }
return result return result
} }
@ -605,6 +584,25 @@ function getDirection(from, to) {
} }
} }
function arenaToScreen ({ x, y }) {
return {
x: x + arena.screenPosition.x,
y: y + arena.screenPosition.y,
}
}
function drawSprite(spriteIndex, x, y) {
const colorkey = 0
const center = arenaToScreen({ x, y })
spr(
spriteIndex,
center.x - arena.spriteHalfSize,
center.y - arena.spriteHalfSize,
colorkey,
)
}
function anyKeyPressed() { function anyKeyPressed() {
for (let i = 0; i < 8; i++) { for (let i = 0; i < 8; i++) {
if (btnp(i)) { if (btnp(i)) {