From dbaecc846ceec4f58c544a5a93676882a5a4be2d Mon Sep 17 00:00:00 2001 From: csd4ni3l Date: Sun, 2 Nov 2025 13:34:28 +0100 Subject: [PATCH] Add starting Pumpkin roll game which i will improve, add score and high score counters to both games --- CREDITS | 3 ++ static/graphics/tombstone.png | Bin 0 -> 168603 bytes static/js/pumpkin_memory.js | 21 ++++++-- static/js/pumpkin_roll.js | 94 +++++++++++++++++++++++++++++++--- 4 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 static/graphics/tombstone.png diff --git a/CREDITS b/CREDITS index 3e1875f..7079775 100644 --- a/CREDITS +++ b/CREDITS @@ -1,3 +1,6 @@ +Tombstone image from Scary PNGs by Vecteezy +https://www.vecteezy.com/free-png/scary + Huge Thanks to Python for being the programming language used in this app. https://www.python.org/ diff --git a/static/graphics/tombstone.png b/static/graphics/tombstone.png new file mode 100644 index 0000000000000000000000000000000000000000..81b3ebaededb759cf63e8da17d09e12374760e76 GIT binary patch literal 168603 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 literal 0 HcmV?d00001 diff --git a/static/js/pumpkin_memory.js b/static/js/pumpkin_memory.js index 9f8872c..e8f5645 100644 --- a/static/js/pumpkin_memory.js +++ b/static/js/pumpkin_memory.js @@ -67,15 +67,30 @@ function setup_game() { revealed = []; } + let best_time = Number(localStorage.getItem("pumpkin_memory_best_time")) || 99999; + let first_time = best_time == 99999; + + const best_time_display = (best_time == 99999) ? "None" : `${best_time}s`; const elapsed = performance.now() - start; - const timer_label = create_label(520, 5, `Time spent: ${(elapsed / 1000).toFixed(1)} s`); + const timer_label = create_label(520, 5, `Time spent: ${(elapsed / 1000).toFixed(1)}s Best Time: ${best_time_display}`); + const timer_interval_id = setInterval(() => { const elapsed = performance.now() - start; - timer_label.text = `Time spent: ${(elapsed / 1000).toFixed(1)} s` + if (first_time) { + best_time = (elapsed / 1000).toFixed(1); + } + + timer_label.text = `Time spent: ${(elapsed / 1000).toFixed(1)}s Best Time: ${best_time}s` }, 100); if (pumpkin_pairs == found_pairs.length - 1) { - create_label(520, 320, `You win!\nTime took: ${(elapsed / 1000).toFixed(1)} s`, 48); + const elapsed = performance.now() - start; + if ((elapsed / 1000).toFixed(1) < best_time) { + best_time = (elapsed / 1000).toFixed(1); + } + localStorage.setItem(`memory_best_${pumpkin_pairs}`, best_time); + + create_label(520, 320, `You win!\nTime took: ${(elapsed / 1000).toFixed(1)} s Best Time: ${best_time_display}`, 48); return; } diff --git a/static/js/pumpkin_roll.js b/static/js/pumpkin_roll.js index 8992e7a..b69eb0b 100644 --- a/static/js/pumpkin_roll.js +++ b/static/js/pumpkin_roll.js @@ -1,6 +1,27 @@ +function spawn_tombstone() { + const tombstone_width = 150; + const tombstone_height = 150; + const tombstone_sprite = add([ + sprite("tombstone"), + pos(1280 - tombstone_width, 720 - tombstone_height), + scale(0.05), + area(), + "tombstone" + ]); + + tombstone_sprite.onUpdate(() => { + tombstone_sprite.pos.x -= 300 * dt(); + + if (tombstone_sprite.pos.x <= -tombstone_width) { + destroy(tombstone_sprite); + } + }) + return tombstone_sprite; +} + function setup_game() { loadSprite("pumpkin", "/static/graphics/pumpkin.png"); - loadSprite("gravestone", "/static/gravestone.png") + loadSprite("tombstone", "/static/graphics/tombstone.png"); const SETTINGS = { "Graphics": { "Anti-Aliasing": {"type": "bool", "default": true}, @@ -17,22 +38,81 @@ function setup_game() { "Controller Enabled": {"type": "bool", "default": true} } }; + const GRAVITY = 1500; + const JUMP_VELOCITY = -1300; + const GROUND_Y = 670; scene("play", () => { + let score = 0; + let high_score = localStorage.getItem("pumpkin_roll_highscore"); + let game_over = false; + let tombstones = []; + let last_tombstone_spawn = performance.now(); + + const score_label = create_label(480, 10, `Score: ${score} High Score: ${high_score}`); + + if (high_score == null) { + high_score = 0; + } + let pumpkin_sprite = add([ sprite("pumpkin"), pos(50, 670), anchor("center"), - rotate(0) + rotate(0), + area(), + "pumpkin" ]) - - setInterval(() => { - pumpkin_sprite.angle = (pumpkin_sprite.angle + dt() * 720) % 360; - }, 100) - onKeyPress("jump", () => { + pumpkin_sprite.isJumping = false; + create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("main_menu")) + + onCollide("pumpkin", "tombstone", () => { + if (game_over) return; + game_over = true; + + for (let tombstone of tombstones) { + destroy(tombstone); + } + + create_label(520, 320, `Game Over!\nScore: ${Math.floor(score)}\nHigh Score: ${high_score}`, 48); }) + + pumpkin_sprite.onUpdate(() => { + if (game_over) return; + score += 60 * dt(); + + if (Math.floor(score) > high_score) { + high_score = Math.floor(score); + localStorage.setItem("pumpkin_roll_highscore", high_score); + } + + score_label.text = `Score: ${Math.floor(score)} High Score: ${high_score}`; + + if ((performance.now() - last_tombstone_spawn) >= 2000) { + last_tombstone_spawn = performance.now(); + tombstones.push(spawn_tombstone()); + } + + if (isKeyDown("space") && !pumpkin_sprite.isJumping) { + pumpkin_sprite.vy = JUMP_VELOCITY; + pumpkin_sprite.isJumping = true; + } + + pumpkin_sprite.angle = (pumpkin_sprite.angle + dt() * 270) % 360; + + if (!pumpkin_sprite.isJumping) return; + + pumpkin_sprite.vy += GRAVITY * dt(); + pumpkin_sprite.pos.y += pumpkin_sprite.vy * dt(); + + if (pumpkin_sprite.pos.y >= GROUND_Y) { + pumpkin_sprite.pos.y = GROUND_Y; + pumpkin_sprite.isJumping = false; + pumpkin_sprite.vy = 0; + } + }); }) return ["Pumpkin Roll", SETTINGS];