diff --git a/static/graphics/jumpscare.jpg b/static/graphics/jumpscare.jpg new file mode 100644 index 0000000..909bed9 Binary files /dev/null and b/static/graphics/jumpscare.jpg differ diff --git a/static/js/game.js b/static/js/game.js index ccedfa2..fb4a395 100644 --- a/static/js/game.js +++ b/static/js/game.js @@ -1,5 +1,16 @@ const WIDTH = 1280; const HEIGHT = 720; +let music_played = false; + +function jumpscare() { + play("jumpscare", { + volume: 1.5 + }) + const jumpscare_sprite = create_sprite(0, 0, "jumpscare"); + setTimeout(() => { + destroy(jumpscare_sprite); + }, 1500); +} function change_setting(category, setting, value, GAME_TITLE) { localStorage.setItem(`${GAME_TITLE} ${setting}`, value); @@ -10,15 +21,9 @@ function show_settings(category, GAME_TITLE, SETTINGS) { const x = 400; const label_x = 50; const space_between = 100; - let y; + let y = 130 + space_between; - if (category == "Graphics") { - y = 130 + space_between; - create_label(label_x, y - space_between, "These settings need a page reload to take effect!", 32); - } - else { - y = 130; - } + create_label(label_x, y - space_between, "All settings require a page reload to take effect!", 32); for (let key in SETTINGS[category]) { const settings_dict = SETTINGS[category][key]; @@ -65,6 +70,37 @@ function show_settings(category, GAME_TITLE, SETTINGS) { } } +function create_start_overlay(GAME_TITLE) { + const overlay = add([ + rect(WIDTH, HEIGHT), + color(0, 0, 0), + opacity(0.6), + pos(0, 0), + area(), + z(1000), + "overlay" + ]) + + const text_label = add([ + text("Click to Start", { size: 48 }), + pos(WIDTH / 2, HEIGHT / 2), + anchor("center"), + color(255, 255, 255), + z(1001) + ]) + + onClick("overlay", () => { + const bgm = play("music", { + volume: Number(localStorage.getItem(`${GAME_TITLE} Music Volume`) || 50) / 100, + loop: true + }); + + destroy(overlay); + destroy(text_label); + }) +} + + function start_game() { const [GAME_TITLE, SETTINGS] = game_info(); @@ -79,21 +115,15 @@ function start_game() { maxFPS: Number(localStorage.getItem(`${GAME_TITLE} FPS Limit`)), font: "New Rocker", background: "#e18888", - buttons: { - up: { - keyboard: "up", - gamepad: "south", - }, - jump: { - keyboard: "space", - gamepad: "a" - } - } } ); setup_game(); + loadSprite("jumpscare", "/static/graphics/jumpscare.jpg"); + loadSound("jumpscare", "/static/sound/jumpscare.mp3"); + loadSound("music", "/static/sound/music.mp3"); + scene("settings", (setting_category) => { let generated_button_lists = Object.entries(SETTINGS).map(([key, value]) => [key, color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("settings", key)]); generated_button_lists = [["Back", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("main_menu")]].concat(generated_button_lists); @@ -111,6 +141,10 @@ function start_game() { scene("main_menu", () => { create_label(WIDTH / 2 - 16 * GAME_TITLE.length, HEIGHT / 4, GAME_TITLE, 56); vertical_buttons(WIDTH / 4, HEIGHT / 2.25, [["Play", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("play")], ["Settings", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("settings")]], WIDTH / 2, HEIGHT / 8, HEIGHT / 50) + if (!music_played) { + create_start_overlay(GAME_TITLE); + music_played = true; + } }); go("main_menu"); diff --git a/static/js/pumpkin_memory.js b/static/js/pumpkin_memory.js index 3be5b40..3dce6e0 100644 --- a/static/js/pumpkin_memory.js +++ b/static/js/pumpkin_memory.js @@ -7,10 +7,11 @@ function game_info() { }, "Sound": { "Music": {"type": "bool", "default": "true"}, - "SFX": {"type": "bool", "default": "true"}, "Music Volume": {"type": "slider", "min": 0, "max": 100, "default": 50}, - "SFX Volume": {"type": "slider", "min": 0, "max": 100, "default": 50}, }, + "Spooky": { + "Jumpscares": {"type": "bool", "default": "true"} + } }; return ["Pumpkin Memory", SETTINGS]; @@ -20,8 +21,6 @@ function setup_game() { loadSprite("pumpkin", "/static/graphics/pumpkin.png"); scene("game", (difficulty, pumpkin_array, revealed, found_pairs, start) => { - create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("main_menu")) - let cols; switch (difficulty) { case "easy": pumpkin_pairs = 5; cols = 5; break; @@ -87,6 +86,24 @@ function setup_game() { timer_label.text = `Time spent: ${(elapsed / 1000).toFixed(1)}s Best Time: ${best_time}s` }, 100); + let jumpscare_interval_id; + if (localStorage.getItem("Pumpkin Memory Jumpscares") == "true") { + jumpscare_interval_id = setInterval(() => { + if (Math.random() < 0.035) { + jumpscare(); + } + }, 1000); + } + + create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), () => { + if (localStorage.getItem("Pumpkin Memory Jumpscares") == "true") { + clearInterval(jumpscare_interval_id); + } + clearInterval(timer_interval_id); + go("main_menu"); + }) + + if (pumpkin_pairs == found_pairs.length - 1) { const elapsed = performance.now() - start; if ((elapsed / 1000).toFixed(1) < best_time) { @@ -113,6 +130,7 @@ function setup_game() { wait(0.5, () => { if (found_pair == null) { clearInterval(timer_interval_id); + clearInterval(jumpscare_interval_id); go("game", difficulty, arr, [], found_pairs, start); } else { @@ -130,6 +148,7 @@ function setup_game() { btn.scale = 1.1; tween(btn.scale, 1, 0.2, (val) => btn.scale = val); clearInterval(timer_interval_id); + clearInterval(jumpscare_interval_id); go("game", difficulty, arr, revealed.concat([index]), found_pairs, start); }) } diff --git a/static/js/pumpkin_roll.js b/static/js/pumpkin_roll.js index 01b45bc..ac47037 100644 --- a/static/js/pumpkin_roll.js +++ b/static/js/pumpkin_roll.js @@ -7,12 +7,13 @@ function game_info() { }, "Sound": { "Music": {"type": "bool", "default": "true"}, - "SFX": {"type": "bool", "default": "true"}, "Music Volume": {"type": "slider", "min": 0, "max": 100, "default": 50}, - "SFX Volume": {"type": "slider", "min": 0, "max": 100, "default": 50}, }, "Input": { "Controller Enabled": {"type": "bool", "default": "true"} + }, + "Spooky": { + "Jumpscares": {"type": "bool", "default": "true"} } }; @@ -83,7 +84,21 @@ function setup_game() { pumpkin_sprite.isJumping = false; - create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("main_menu")) + let jumpscare_interval_id; + if (localStorage.getItem("Pumpkin Roll Jumpscares") == "true") { + jumpscare_interval_id = setInterval(() => { + if (Math.random() < 0.035) { + jumpscare(); + } + }, 1000); + } + + create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), () => { + if (localStorage.getItem("Pumpkin Roll Jumpscares") == "true") { + clearInterval(jumpscare_interval_id); + } + go("main_menu"); + }) onCollide("pumpkin", "enemy", () => { if (game_over) return; @@ -94,6 +109,10 @@ function setup_game() { } create_label(520, 320, `Game Over!\nScore: ${Math.floor(score)}\nHigh Score: ${high_score}`, 48); + + if (localStorage.getItem("Pumpkin Roll Jumpscares") == "true") { + setTimeout(jumpscare, 500); + } }) enemy_spawn_with_check = (count) => { @@ -136,7 +155,7 @@ function setup_game() { } } - if (isKeyDown("space") && !pumpkin_sprite.isJumping) { + if ((isKeyDown("space") || (localStorage.getItem("Pumpkin Roll Controller Enabled") === "true" && isGamepadButtonDown("south"))) && !pumpkin_sprite.isJumping) { pumpkin_sprite.vy = JUMP_VELOCITY; pumpkin_sprite.isJumping = true; } diff --git a/static/js/whack_a_pumpkin.js b/static/js/whack_a_pumpkin.js index 5ba2392..3b5739f 100644 --- a/static/js/whack_a_pumpkin.js +++ b/static/js/whack_a_pumpkin.js @@ -7,9 +7,10 @@ function game_info() { }, "Sound": { "Music": {"type": "bool", "default": "true"}, - "SFX": {"type": "bool", "default": "true"}, "Music Volume": {"type": "slider", "min": 0, "max": 100, "default": 50}, - "SFX Volume": {"type": "slider", "min": 0, "max": 100, "default": 50}, + }, + "Spooky": { + "Jumpscares": {"type": "bool", "default": "true"} } }; @@ -68,7 +69,24 @@ function setup_game() { scale(0.85) ]); - create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), scene_lambda("main_menu")) + let jumpscare_interval_id; + if (localStorage.getItem("Whack a Pumpkin Jumpscares") == "true") { + jumpscare_interval_id = setInterval(() => { + if (Math.random() < 0.035) { + jumpscare(); + } + }, 1000); + } + + create_button(5, 5, 150, 75, "Back", color(127, 127, 127), color(0, 0, 0, 0), () => { + game_over = true; + if (localStorage.getItem("Whack a Pumpkin Jumpscares") == "true") { + clearInterval(jumpscare_interval_id); + } + go("main_menu"); + }) + + const info_label = create_label(525, 50, `Time left: 120s\nScore: ${score}\nHigh Score: ${high_score}`); function spawn_pumpkins() { @@ -104,6 +122,9 @@ function setup_game() { destroy(bg); destroy(info_label); + if (localStorage.getItem("Whack a Pumpkin Jumpscares") == "true") { + setTimeout(jumpscare, 500); + } } else { info_label.text = `Time left: ${(120 - (elapsed / 1000)).toFixed(1)}s\nScore: ${score}\nHigh Score: ${high_score}`; diff --git a/static/sound/jumpscare.mp3 b/static/sound/jumpscare.mp3 new file mode 100644 index 0000000..08a2c7c Binary files /dev/null and b/static/sound/jumpscare.mp3 differ diff --git a/static/sound/music.mp3 b/static/sound/music.mp3 new file mode 100644 index 0000000..1f1cb31 Binary files /dev/null and b/static/sound/music.mp3 differ diff --git a/templates/gamebase.jinja2 b/templates/gamebase.jinja2 index c00f68b..1152946 100644 --- a/templates/gamebase.jinja2 +++ b/templates/gamebase.jinja2 @@ -18,7 +18,6 @@ {% block body %}