DotDashPit/game.js
2025-06-06 16:14:28 +02:00

290 lines
12 KiB
JavaScript

// title: MorsePit
// author: He4eT@oddsquat.org
// desc: Defeat endless waves of enemies using Morse code.
// site: https://github.com/He4eT/MorsePit
// license: MIT License
// version: 0.1
// script: js
// api: https://github.com/nesbox/TIC-80/wiki/API
function TIC() {
gameStages[currentStage]()
}
// Stages
const gameStages = {
mainMenu,
gameover,
gameplay,
}
let currentStage = 'mainMenu'
// State
let arena = {
// Screen position
x: 7,
y: 7,
// Bounds
top: 0,
right: 225,
bottom: 89,
left: 0,
// Sprite size
spriteSize: 7,
spriteHalfSize: 3,
}
let player = {
sprite: 64,
speed: 1,
x: 0,
y: 0,
}
let enemies = []
let effects = []
// Main Menu
function mainMenu() {
if ([BTN_A, BTN_B, BTN_X, BTN_Y].map(btn).some(Boolean)) {
currentStage = 'gameplay'
}
cls(0)
const title = 'Morse Pit'
print(title, 12, 12, 3, false, 2)
const instruction = 'Press any key to start'
print(instruction, 12, 30, 4)
}
// Gameover
function gameover() {
cls(0)
drawEnemies()
drawPlayer()
const title = 'Game Over'
print(title, 12, 12, 10, false, 2)
}
// Gameplay
function gameplay() {
checkColisions()
handleMoves()
handleMorse()
spawn()
// moveEnemies()
drawInterface()
drawArena()
drawFX()
drawEnemies()
drawPlayer()
}
function handleMoves() {
player.speed = btn(BTN_A) ? 2 : 1
let dx = 0
if (btn(BTN_L)) dx -= 1
if (btn(BTN_R)) dx += 1
let dy = 0
if (btn(BTN_U)) dy -= 1
if (btn(BTN_D)) dy += 1
const norm = player.speed / ([dx, dy].every((d) => d !== 0) ? Math.SQRT2 : 1)
player.x = Math.max(arena.left, Math.min(arena.right, player.x + dx * norm))
player.y = Math.max(arena.top, Math.min(arena.bottom, player.y + dy * norm))
}
function handleMorse() {
player.sprite = btn(BTN_B) ? 65 : 64
if (btnp(BTN_B, 100, 100)) {
if (enemies.length > 0) {
effects.unshift({
type: 'laser',
from: {
x: player.x,
y: player.y,
},
to: {
x: enemies[0].x[0],
y: enemies[0].y[0],
},
frames: [1, 2, 3, 4, 7, 7, 7, 6, 5, 4, 3, 2, 1],
})
enemies.shift()
trace(enemies.length)
}
}
}
// Enemies
function spawn() {
if (enemies.length === 0) {
enemies = [
{
x: [Math.random() * arena.right],
y: [Math.random() * arena.bottom],
type: 'zombie',
dangerZone: 8,
},
]
}
}
function checkColisions() {
if (
enemies
.map((enemy) => [
enemy,
Math.hypot(player.x - enemy.x[0], player.y - enemy.y[0]),
])
.some(([enemy, distance]) => distance < enemy.dangerZone)
) {
currentStage = 'gameover'
}
}
// Draw
function arenaToScreen({ x, y }) {
return {
x: x + arena.x,
y: y + arena.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 drawInterface() {
cls(0)
}
function drawArena() {
map(0, 0, 30, 15)
}
function drawFX() {
effects
.map((effect) => ({
...effect,
from: arenaToScreen(effect.from),
to: arenaToScreen(effect.to),
}))
.forEach((effect) =>
({
laser: ({ from, to, frames }) => {
// frames: [1, 2, 3, 4, 7, 7, 7, 6, 5, 4, 3, 2, 1],
const color = frames.shift()
line(from.x, from.y, to.x, to.y, color)
circ(from.x, from.y, frames.length / 3, color)
circ(to.x, to.y, frames.length / 2, color)
circb(to.x, to.y, frames.length, color + 3)
},
nuke: ({ to, frames }) => {
// frames: [6, 5, 4, 3, 2],
const color = frames.shift()
circ(to.x, to.y, Math.pow(frames.length, 5), color)
},
})[effect.type](effect),
)
effects = effects.filter(({ frames }) => frames.length > 0)
}
function drawEnemies() {
enemies
.map((enemy) => [80, enemy.x[0], enemy.y[0]])
.forEach((spriteData) => drawSprite(...spriteData))
}
function drawPlayer() {
drawSprite(player.sprite, player.x, player.y)
}
// Constants
// Buttons
const [BTN_U, BTN_D, BTN_L, BTN_R, BTN_A, BTN_B, BTN_X, BTN_Y] = [
...Array(8).keys(),
]
// <TILES>
// 001:1111110012222100123321001233210012222100111111000000000000000000
// 002:1111111112222221123333211233332112222221111111110000000000000000
// 016:0000000000000000000000000000000000000000000001110000012200000123
// 017:0000000000000000000000000000000000000000111111112222222233333333
// 018:0000000000000000000000000000000000000000111000002210000032100000
// 032:0000012300000123000001230000012300000123000001230000012300000123
// 033:2111111211111111111111111111111111111111111111111111111121111112
// 034:3210000032100000321000003210000032100000321000003210000032100000
// 048:0000012300000122000001110000000000000000000000000000000000000000
// 049:3333333322222222111111110000000000000000000000000000000000000000
// 050:3210000022100000111000000000000000000000000000000000000000000000
// 064:8800088080000080008880000088800000888000800000808800088000000000
// 065:0000000008808800080008000008000008000800088088000000000000000000
// 080:aaaaaaa0aaaaaaa0aa000aa0aa000aa0aa000aa0aaaaaaa0aaaaaaa000000000
// </TILES>
// <MAP>
// 000:011111111111111111111111111111111111111111111111111111111121000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 001:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 002:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 003:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 004:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 005:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 006:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 007:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 008:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 009:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 010:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 011:021212121212121212121212121212121212121212121212121212121222000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 012:031313131313131313131313131313131313131313131313131313131323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// </MAP>
// <WAVES>
// 000:00000000ffffffff00000000ffffffff
// 001:0123456789abcdeffedcba9876543210
// 002:0123456789abcdef0123456789abcdef
// </WAVES>
// <SFX>
// 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
// </SFX>
// <TRACKS>
// 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// </TRACKS>
// <PALETTE>
// 000:000000002b36073642586e75657b8383949693a1a1ffffffb58900cb4b16dc322fd336826c71c4268bd22aa198859900
// </PALETTE>