This commit is contained in:
2026-05-03 22:40:42 +02:00
parent a02592120e
commit 2d33810f83

View File

@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Frugger</title> <title>Frugg</title>
<style> <style>
body { margin: 0; background: #222; overflow: hidden; } body { margin: 0; background: #222; overflow: hidden; }
canvas { display: block; margin: auto; background: #4aa3d8; } canvas { display: block; margin: auto; background: #4aa3d8; }
@ -11,6 +11,8 @@
<body> <body>
<canvas id="game"></canvas> <canvas id="game"></canvas>
<audio id="jumpSound" src="./burp.mp3" preload="auto"></audio>
<script> <script>
const canvas = document.getElementById("game"); const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
@ -28,11 +30,14 @@ let score = 0;
// --- Camera --- // --- Camera ---
let camera = { x: 0, y: 0 }; let camera = { x: 0, y: 0 };
// --- Settings (adjusted) --- // --- Settings (more arc + slower) ---
const GRAVITY = 0.3; // lower gravity = slower fall const GRAVITY = 0.25;
const MAX_CHARGE = 20; const MAX_CHARGE = 25;
const JUMP_POWER = 0.8; // higher arc const JUMP_POWER = 0.5; // higher jump
const HORIZONTAL_SCALE = 0.012; // slower forward movement const HORIZONTAL_SCALE = 0.0010;
// --- Sound ---
const jumpSound = document.getElementById("jumpSound");
// --- Create lily pads --- // --- Create lily pads ---
function generatePads() { function generatePads() {
@ -52,7 +57,6 @@ function resetFrog() {
frog.y = pads[currentPad].y; frog.y = pads[currentPad].y;
frog.z = 0; frog.z = 0;
// center camera on current pad
camera.x = frog.x; camera.x = frog.x;
camera.y = frog.y; camera.y = frog.y;
} }
@ -89,6 +93,10 @@ function jump() {
jumping = true; jumping = true;
charge = 0; charge = 0;
// play sound
jumpSound.currentTime = 0.25;
jumpSound.play();
} }
// --- Update --- // --- Update ---
@ -108,7 +116,6 @@ function update() {
if (frog.z <= 0) { if (frog.z <= 0) {
frog.z = 0; frog.z = 0;
jumping = false; jumping = false;
checkLanding(); checkLanding();
} }
} }
@ -135,7 +142,7 @@ function checkLanding() {
resetFrog(); resetFrog();
} }
// --- Isometric projection with camera --- // --- Isometric projection ---
function iso(x, y, z = 0) { function iso(x, y, z = 0) {
const sx = x - camera.x; const sx = x - camera.x;
const sy = y - camera.y; const sy = y - camera.y;
@ -151,6 +158,13 @@ function drawPads() {
for (let i = 0; i < pads.length; i++) { for (let i = 0; i < pads.length; i++) {
const p = iso(pads[i].x, pads[i].y); const p = iso(pads[i].x, pads[i].y);
// shadow
ctx.fillStyle = "rgba(0,0,0,0.2)";
ctx.beginPath();
ctx.ellipse(p.x + 5, p.y + 5, 50, 25, 0, 0, Math.PI * 2);
ctx.fill();
// pad
ctx.fillStyle = i === currentPad ? "#2ecc71" : "#27ae60"; ctx.fillStyle = i === currentPad ? "#2ecc71" : "#27ae60";
ctx.beginPath(); ctx.beginPath();
ctx.ellipse(p.x, p.y, 50, 25, 0, 0, Math.PI * 2); ctx.ellipse(p.x, p.y, 50, 25, 0, 0, Math.PI * 2);
@ -160,15 +174,25 @@ function drawPads() {
// --- Draw frog --- // --- Draw frog ---
function drawFrog() { function drawFrog() {
const base = iso(frog.x, frog.y, 0);
const p = iso(frog.x, frog.y, frog.z); const p = iso(frog.x, frog.y, frog.z);
// shadow (shrinks when higher)
const scale = Math.max(0.3, 1 - frog.z / 200);
ctx.fillStyle = "rgba(0,0,0,0.3)";
ctx.beginPath();
ctx.ellipse(base.x, base.y, 15 * scale, 8 * scale, 0, 0, Math.PI * 2);
ctx.fill();
// frog
ctx.fillStyle = "lime"; ctx.fillStyle = "lime";
ctx.beginPath(); ctx.beginPath();
ctx.arc(p.x, p.y - 10, 15, 0, Math.PI * 2); ctx.arc(p.x, p.y - 10, 15, 0, Math.PI * 2);
ctx.fill(); ctx.fill();
} }
// --- Trajectory preview --- // --- Trajectory preview (red dashed, higher arc) ---
function drawTrajectory() { function drawTrajectory() {
if (!charging || jumping) return; if (!charging || jumping) return;
@ -180,16 +204,17 @@ function drawTrajectory() {
let vx = dx * charge * HORIZONTAL_SCALE; let vx = dx * charge * HORIZONTAL_SCALE;
let vy = dy * charge * HORIZONTAL_SCALE; let vy = dy * charge * HORIZONTAL_SCALE;
let vz = charge * JUMP_POWER; let vz = charge * JUMP_POWER * 1.3; // boosted arc preview
let tx = frog.x; let tx = frog.x;
let ty = frog.y; let ty = frog.y;
let tz = frog.z; let tz = frog.z;
ctx.strokeStyle = "rgba(255,255,255,0.5)"; ctx.strokeStyle = "red";
ctx.setLineDash([5, 5]);
ctx.beginPath(); ctx.beginPath();
for (let i = 0; i < 40; i++) { for (let i = 0; i < 50; i++) {
tx += vx; tx += vx;
ty += vy; ty += vy;
tz += vz; tz += vz;
@ -202,9 +227,56 @@ function drawTrajectory() {
} }
ctx.stroke(); ctx.stroke();
ctx.setLineDash([]);
} }
// --- Draw score --- // --- Depth sorting ---
function drawScene() {
// Combine pads + frog into one list
let objects = [];
pads.forEach((pad, i) => {
objects.push({
type: "pad",
x: pad.x,
y: pad.y,
index: i
});
});
objects.push({
type: "frog",
x: frog.x,
y: frog.y
});
// Sort by depth (important!)
objects.sort((a, b) => (a.x + a.y) - (b.x + b.y));
for (let obj of objects) {
if (obj.type === "pad") {
const i = obj.index;
const p = iso(pads[i].x, pads[i].y);
// shadow
ctx.fillStyle = "rgba(0,0,0,0.2)";
ctx.beginPath();
ctx.ellipse(p.x + 5, p.y + 5, 50, 25, 0, 0, Math.PI * 2);
ctx.fill();
// pad
ctx.fillStyle = i === currentPad ? "#2ecc71" : "#27ae60";
ctx.beginPath();
ctx.ellipse(p.x, p.y, 50, 25, 0, 0, Math.PI * 2);
ctx.fill();
} else if (obj.type === "frog") {
drawFrog();
}
}
}
// --- UI ---
function drawUI() { function drawUI() {
ctx.fillStyle = "white"; ctx.fillStyle = "white";
ctx.font = "20px Arial"; ctx.font = "20px Arial";
@ -216,9 +288,8 @@ function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
update(); update();
drawPads(); drawScene();
drawTrajectory(); drawTrajectory();
drawFrog();
drawUI(); drawUI();
requestAnimationFrame(loop); requestAnimationFrame(loop);