diff options
author | sanine <sanine.not@pm.me> | 2024-07-05 22:58:00 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2024-07-05 22:58:00 -0500 |
commit | ad5e699c810e448dc24d06dec201b7867b9f5e06 (patch) | |
tree | 745d92be7232e9a6139430cf9a392bfaaf5514ad /main.js | |
parent | 827c3a594b5138fb7e934791bdf66159ad80d5ec (diff) |
add level.js
Diffstat (limited to 'main.js')
-rw-r--r-- | main.js | 187 |
1 files changed, 40 insertions, 147 deletions
@@ -1,153 +1,46 @@ -const X_START = '8*cos(t)'; -const Y_START = '8*sin(t)'; -const equations = { - x: math.compile(X_START), - y: math.compile(Y_START), -} +import { setupLevel, setupLevelUi } from './level.js'; window.onload = () => { - const root = document.getElementById('root'); - - const launchButton = document.createElement('input'); - launchButton.type = 'button'; - launchButton.value = 'Launch'; - const xeq = document.createElement('input'); - xeq.value = X_START; - xeq.onchange = (e) => { - equations.x = math.compile(e.target.value); - running = false; - path = computePath(equations, 0, 100, 0.1); - render(ctx, path, 0); - }; - xeq.onkeydown = xeq.onchange; - xeq.onkeyup = xeq.onchange; - const yeq = document.createElement('input'); - yeq.value = Y_START; - yeq.onchange = (e) => { - equations.y = math.compile(e.target.value); - running = false; - path = computePath(equations, 0, 100, 0.1); - render(ctx, path, 0); - }; - yeq.onkeydown = yeq.onchange; - yeq.onkeyup = yeq.onchange; - - root.appendChild(xeq); - root.appendChild(yeq); - root.appendChild(launchButton); - const canvas = document.createElement('canvas'); - canvas.width = 600; - canvas.height = 600; - root.appendChild(canvas); - - const ctx = canvas.getContext('2d'); - ctx.translate(canvas.width/2, canvas.height/2) - ctx.scale(canvas.width/20, -canvas.height/20); - let path = computePath(equations, 0, 100, 0.1); + const root = document.getElementById('root'); - let running = false; - const step = (index) => { - render(ctx, path, index); - if (running && index < path.length-1) { - setTimeout(() => step(index+1), 10); - } else { - running = false; - render(ctx, path, 0); + const start = document.createElement('input'); + start.type = 'button'; + start.value = 'Start'; + start.onclick = () => { + const audio = new AudioContext(); + root.removeChild(start); + + const rocketThrustAudio = document.getElementById('sfx-rocket-thrust'); + const rocketThrustSource = audio.createMediaElementSource(rocketThrustAudio); + const rocketGain = audio.createGain(); + rocketThrustSource.connect(rocketGain).connect(audio.destination); + + const musicGain = audio.createGain(); + const addMusic = (music, id) => { + const element = document.getElementById(id); + const source = audio.createMediaElementSource(element); + source.connect(musicGain).connect(audio.destination); + return [ ...music, { element, source } ]; } - } - launchButton.onclick = () => { - running = false; - setTimeout(() => { running=true; step(0); }, 20); - } - render(ctx, path, 0); -} - - -function render(ctx, path, index) { - const { width, height } = ctx.canvas; - ctx.fillStyle = 'black'; - ctx.fillRect(-width, -height, 2*width, 2*height); - const [x0, y0] = path[index]; - const [x1, y1] = path[index+1] || path[index]; - const angle = Math.atan2(y1-y0, x1-x0); - drawGrid(ctx); - drawPath(ctx, path); - drawShip(ctx, [x0, y0], angle); -} - - -function drawShip(ctx, pos, angle) { - const transform = ctx.getTransform(); - const { width, height } = ctx.canvas; - const [x, y] = pos; - ctx.translate(x, y); - ctx.rotate(angle); - ctx.fillStyle = 'white'; - const STEP = 120/Math.min(width,height); - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(-STEP, -STEP); - ctx.lineTo(2*STEP, 0); - ctx.lineTo(-STEP, STEP); - ctx.lineTo(0, 0); - ctx.fill(); - ctx.setTransform(transform); -} - - -function computePath(equations, start, end, step) { - const ts = [...Array(Math.floor((end-start)/step)).keys()].map(k => step * (start+k)) - return ts.map(t => [ equations.x.eval({t}), equations.y.eval({t}) ]); -} - -function drawGrid(ctx) { - ctx.scale(1, -1); - ctx.strokeStyle = 'white'; - ctx.fillStyle = 'white'; - const { width, height } = ctx.canvas; - ctx.font = `${200/Math.max(width, height)}px serif`; - ctx.lineWidth = 4 / Math.max(width, height); - const drawLine = (start, end) => { - ctx.beginPath(); - ctx.moveTo(start[0], start[1]); - ctx.lineTo(end[0], end[1]); - ctx.stroke(); - } - const drawXLabel = (x, y) => { - ctx.textAlign = 'right'; - ctx.textBaseline = 'bottom'; - ctx.fillText(`${x} `, x, y); - } - - const drawYLabel = (x, y) => { - ctx.rotate(Math.PI/2); - ctx.textAlign = 'right'; - ctx.textBaseline = 'bottom'; - ctx.fillText(`${y} `, y, x); - ctx.rotate(-Math.PI/2); - } - - const drawGrid = (start, end, step) => { - [...Array(1+Math.floor((end-start)/step)).keys()].forEach(z => { - z = (step*z)+start; - drawLine([z, start], [z, end]); - drawLine([start, z], [end, z]); - drawXLabel(z, end); - drawYLabel(end, z); - }); - } - drawGrid(-10, 10, 2); - ctx.scale(1, -1); -} - -function drawPath(ctx, path) { - const [ start, ...line ] = path; - const { width, height } = ctx.canvas; - ctx.strokeStyle = 'white'; - ctx.lineWidth = 8 / Math.max(width, height); - ctx.beginPath(); - ctx.moveTo(start[0], start[1]); - line.forEach(p => ctx.lineTo(p[0], p[1])); - ctx.stroke(); + musicGain.gain.value = 0.5; + const musicList = [ + 'music-minute', + 'music-starboard', + 'music-cribwhistling', + 'music-swish', + 'music-aeroplane', + ].reduce(addMusic, []); + musicList.forEach( + ({ element }, i) => element.addEventListener( + 'ended', + () => musicList[(i+1) % musicList.length].element.play(), + ) + ) + musicList[0].element.play(); + + const level = setupLevel([], []); + const ui = setupLevelUi(level, root, audio); + }; + root.appendChild(start); } |