diff options
| author | LLLL Colonq <llll@colonq> | 2026-08-03 19:36:31 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-08-03 19:36:31 -0400 |
| commit | a75221ab93f59d688f90cd83f0284ff98951fcfa (patch) | |
| tree | 215c9480f5b1bfdf63f9a0141b06a7cbefaab2e8 /2026/games/peetseater/index.html | |
| parent | 9127154100230e8d60ab5139fb1bc626b24068ee (diff) | |
Update
Diffstat (limited to '2026/games/peetseater/index.html')
| -rw-r--r-- | 2026/games/peetseater/index.html | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/2026/games/peetseater/index.html b/2026/games/peetseater/index.html new file mode 100644 index 0000000..2927992 --- /dev/null +++ b/2026/games/peetseater/index.html @@ -0,0 +1,262 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Microgame 2026</title> + <style> + html, body, canvas { + margin: 0; + padding: 0; + text-align: center; + } + canvas { + margin: 1px; + background-color: darkcyan; + min-width: 240px; + min-height: 160px; + width: 97%; + height: 97%; + image-rendering: pixelated; + } + </style> +</head> +<body> + <canvas id="game" width="240" height="160"></canvas> + <img + id="MikuWantsPizza" + src="MikuWantsPizza1.png" + style="display: none;" + /> + <img + id="pizza" + src="pizza.png" + style="display: none; " + /> + <script type="application/javascript"> + + // Click handling + const canvas = document.getElementById("game"); + const miku_sprite = document.getElementById("MikuWantsPizza"); + const pizza_sprite = document.getElementById("pizza"); + const ctx = canvas.getContext("2d"); + ctx.save(); + + // Audio assuming the iframe parent situation works out: + class Sound { + constructor(path) { + this.audio = new Audio(path); + this.canPlay = false; + const ref = this; + this.audio.addEventListener("canplaythrough", (event) => { + ref.canPlay = true; + }); + } + + play() { + if (this.canPlay) { + this.audio.muted = false; + this.audio.play(); + } + } + + mute() { + this.audio.muted = true; + } + } + const pizza_sound = new Sound('pizza.mp3'); + const pasta_sound = new Sound('pasta.mp3'); + const deliverit_sound = new Sound('deliverit.mp3'); + const failure_sound = new Sound('failure.mp3'); + const win_sound = new Sound('jump.mp3'); + const mad_sound = new Sound('explosion.mp3'); + const scream = new Sound('mikuscream.mp3'); + const weeee = new Sound('weeee.mp3'); + const frame_to_sound = { + 0: pizza_sound, + 1: pasta_sound, + 2: deliverit_sound, + 10: failure_sound, + 12: mad_sound, + 13: mad_sound, + 14: mad_sound, + 15: scream, + 7: win_sound, + 8: weeee, + }; + + const game_state = { + game_step: 0, + game_steps: [0, 1, 2, 3], + time_between_steps_ms: 2000, + delivery_attempt: false, + pizza_delivered: false, + play_ending: false, + ok_to_give: [2, 3], + win_frames: [4,5,6,7,8], + time_between_ending_frames_ms: 300, + fail_frames: [9, 10, 11, 12, 13, 14, 15], + state: 'idle', + difficulty: 0, + audio_played: false, + }; + + function reset_game_state() { + game_state.state = 'game'; + game_state.game_step = 0; + game_state.delivery_attempt = false; + game_state.pizza_delivered = false; + game_state.play_ending = false; + game_state.audio_played = false; + + const difficulty_selection = Math.floor(game_state.difficulty / 5); + switch (difficulty_selection) { + case 0: game_state.time_between_steps_ms = 2000; break; + case 1: game_state.time_between_steps_ms = 1800; break; + case 2: game_state.time_between_steps_ms = 1600; break; + case 3: game_state.time_between_steps_ms = 1400; break; + case 4: game_state.time_between_steps_ms = 1200; break; + case 5: game_state.time_between_steps_ms = 1000; break; + case 6: game_state.time_between_steps_ms = 800; break; + case 7: game_state.time_between_steps_ms = 600; break; + default: + game_state.time_between_steps_ms = 400; + break; + } + } + + canvas.addEventListener('click', () => { + game_state.delivery_attempt = true; + }); + + // Actual game code. + let start; + const last_frame_win = game_state.win_frames[game_state.win_frames.length - 1]; + const last_frame_fail = game_state.fail_frames[game_state.fail_frames.length - 1]; + const last_frame_game = game_state.game_steps[game_state.game_steps.length - 1]; + function game_loop(timestamp) { + if (!ctx) { + console.log('No canvas found?'); + // you win, i'm not going to take a life from you + send_game_done(true); + return; + } + + if (start === undefined) { + start = timestamp; + } + const elapsed = timestamp - start; + + let idx = game_state.game_step; + if (elapsed > game_state.time_between_steps_ms) { + game_state.game_step += 1; + game_state.audio_played = false; + start = timestamp; + } + + if (!game_state.audio_played) { + game_state.audio_played = true; + const sound = frame_to_sound[game_state.game_step]; + if (sound) { + frame_to_sound[game_state.game_step - 1]?.mute(); + sound.play(); + } + } + + switch (game_state.state) { + case 'game': + draw_pizza = true; + + if (last_frame_game < game_state.game_step) { + // they failed due to time out + game_state.state = 'failed'; + game_state.game_step = game_state.fail_frames[0]; + game_state.pizza_delivered = false; + game_state.time_between_steps_ms = game_state.time_between_ending_frames_ms; + draw_pizza = false; + } + + if (game_state.delivery_attempt) { + draw_pizza = false; + game_state.time_between_steps_ms = game_state.time_between_ending_frames_ms; + if (game_state.ok_to_give.includes(game_state.game_step)) { + game_state.pizza_delivered = true; + game_state.state = 'victory'; + game_state.game_step = game_state.win_frames[0]; + } else { + game_state.state = 'failed'; + game_state.game_step = game_state.fail_frames[0]; + } + } + + break; + case 'failed': + if (last_frame_fail - 1 < game_state.game_step) { + game_state.time_between_steps_ms = 2000; + } + if (last_frame_fail < game_state.game_step) { + game_state.game_step = last_frame_fail; + send_game_done(false); + } + break; + case 'victory': + if (last_frame_win - 1 < game_state.game_step) { + game_state.time_between_steps_ms = 2000; + } + if (last_frame_win < game_state.game_step) { + game_state.game_step = last_frame_win; + send_game_done(true); + } + break; + case 'idle': + start = undefined; + return; + } + + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.drawImage(miku_sprite, idx * 240, 0, 240, 160, 0, 0, 240, 160); + if (draw_pizza) { + ctx.drawImage(pizza_sprite, 0, 0, 700, 300, idx * 60, 130, 70, 30); + } + requestAnimationFrame(game_loop); + } + + + // CLONQ PROTOCOL AND BOOTSTRAP + function game_ready() { + window.parent.postMessage({op: "ready"}); + } + + function ack_start_event() { + reset_game_state(); + window.parent.postMessage({op: "started", verb: "DELIVER"}); + } + + function is_game_start_event(event) { + return event?.op === 'start' && event?.difficulty > -1; + } + + function send_game_done(player_won) { + window.parent.postMessage({op: "done", win: !!player_won}); + reset_game_state(); + game_state.state = 'idle'; + } + + function message_handler(event) { + if (is_game_start_event(event.data)) { + game_state.difficulty = event?.data?.difficulty || 0; + ack_start_event(); + game_loop(); + } + } + + window.addEventListener("message", message_handler); + window.onload = function() { + game_ready(); + }; + + + + </script> +</body> +</html>
\ No newline at end of file |
