about summary refs log tree commit diff stats
path: root/js/mountain/game.js
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-07-03 07:14:37 -0400
committerelioat <elioat@tilde.institute>2024-07-03 07:14:37 -0400
commit729b918b593618bc0e74b5e98ef6273eb0e52f8c (patch)
treec8cc0a913fef7e70556e08c6608a7ca40b3f6e02 /js/mountain/game.js
parent822824c79ec0da595001c4448ae98d89ea8a4745 (diff)
downloadtour-729b918b593618bc0e74b5e98ef6273eb0e52f8c.tar.gz
*
Diffstat (limited to 'js/mountain/game.js')
-rw-r--r--js/mountain/game.js235
1 files changed, 233 insertions, 2 deletions
diff --git a/js/mountain/game.js b/js/mountain/game.js
index 3c96005..5601d94 100644
--- a/js/mountain/game.js
+++ b/js/mountain/game.js
@@ -1,3 +1,234 @@
-// a 2d platformer game, where the character can jump, double jump, move left and right.
-// That character can avoid spikes and obstacles.
+// TODO: if there are no more levels show a "game win" message
 
+// Game constants
+const canvas = document.getElementById('gameCanvas');
+const ctx = canvas.getContext('2d');
+canvas.width = 800;
+canvas.height = 600;
+
+const GRAVITY = 0.5;
+const JUMP_STRENGTH = -12;
+const MOVE_SPEED = 5;
+
+let keys = { left: false, right: false, up: false, down: false, space: false };
+
+let levels = [
+    [
+        [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
+    ],
+    [
+        // Next level example
+        [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5],
+        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
+    ]
+    // Add more levels as needed
+];
+
+let currentLevel = 0;
+
+class Player {
+    constructor(x, y) {
+        this.x = x;
+        this.y = y;
+        this.width = 30;
+        this.height = 30;
+        this.velocityX = 0;
+        this.velocityY = 0;
+        this.jumping = false;
+        this.doubleJumping = false;
+    }
+
+    update() {
+        if (keys.left) this.velocityX = -MOVE_SPEED;
+        if (keys.right) this.velocityX = MOVE_SPEED;
+        if (!keys.left && !keys.right) this.velocityX = 0;
+
+        this.velocityY += GRAVITY;
+        this.x += this.velocityX;
+        this.y += this.velocityY;
+
+        // Collision detection
+        this.checkCollision();
+
+        // Limit falling speed
+        if (this.velocityY > 10) this.velocityY = 10;
+    }
+
+    jump() {
+        if (!this.jumping) {
+            this.velocityY = JUMP_STRENGTH;
+            this.jumping = true;
+        } else if (!this.doubleJumping) {
+            this.velocityY = JUMP_STRENGTH;
+            this.doubleJumping = true;
+        }
+    }
+
+    checkCollision() {
+        let row, col, belowRow, aboveRow, leftCol, rightCol;
+
+        // Check collision with ground from below
+        row = Math.floor(this.y / 30);
+        col = Math.floor(this.x / 30);
+        belowRow = Math.floor((this.y + this.height) / 30);
+
+        if (levels[currentLevel][belowRow] && levels[currentLevel][belowRow][col] === 1) {
+            if (this.velocityY > 0) {
+                this.y = belowRow * 30 - this.height;
+                this.velocityY = 0;
+                this.jumping = false;
+                this.doubleJumping = false;
+            }
+        }
+
+        // Check collision with ground from above
+        aboveRow = Math.floor((this.y - 1) / 30);
+        if (levels[currentLevel][aboveRow] && levels[currentLevel][aboveRow][col] === 1) {
+            if (this.velocityY < 0) {
+                this.y = (aboveRow + 1) * 30;
+                this.velocityY = 0;
+            }
+        }
+
+        // Check collision with ground from the left
+        leftCol = Math.floor(this.x / 30);
+        if (levels[currentLevel][row] && levels[currentLevel][row][leftCol] === 1) {
+            if (this.velocityX < 0) {
+                this.x = (leftCol + 1) * 30;
+                this.velocityX = 0;
+            }
+        }
+
+        // Check collision with ground from the right
+        rightCol = Math.floor((this.x + this.width) / 30);
+        if (levels[currentLevel][row] && levels[currentLevel][row][rightCol] === 1) {
+            if (this.velocityX > 0) {
+                this.x = rightCol * 30 - this.width;
+                this.velocityX = 0;
+            }
+        }
+
+        // Collision with lava
+        if (levels[currentLevel][row] && levels[currentLevel][row][col] === 2) {
+            this.reset();
+        }
+
+        // Collision with save point
+        if (levels[currentLevel][row] && levels[currentLevel][row][col] === 3) {
+            localStorage.setItem('savePoint', JSON.stringify({ x: this.x, y: this.y, level: currentLevel }));
+        }
+
+        // Collision with goal
+        if (levels[currentLevel][row] && levels[currentLevel][row][col] === 5) {
+            alert('Level Complete!');
+            loadNextLevel();
+        }
+    }
+
+    reset() {
+        let savePoint = JSON.parse(localStorage.getItem('savePoint')) || { x: 30, y: 30, level: 0 };
+        this.x = savePoint.x;
+        this.y = savePoint.y;
+        currentLevel = savePoint.level;
+        this.velocityY = 0;
+    }
+
+    render() {
+        ctx.fillStyle = 'blue';
+        ctx.fillRect(this.x, this.y, this.width, this.height);
+    }
+}
+
+function findPlayerStartPosition(level) {
+    for (let row = 0; row < levels[level].length; row++) {
+        for (let col = 0; col < levels[level][row].length; col++) {
+            if (levels[level][row][col] === 4) {
+                return { x: col * 30, y: row * 30 };
+            }
+        }
+    }
+    // Default position if no start point found
+    return { x: 30, y: 570 };
+}
+
+function renderLevel() {
+    for (let row = 0; row < levels[currentLevel].length; row++) {
+        for (let col = 0; col < levels[currentLevel][row].length; col++) {
+            if (levels[currentLevel][row][col] === 1) {
+                ctx.fillStyle = 'brown';
+                ctx.fillRect(col * 30, row * 30, 30, 30);
+            } else if (levels[currentLevel][row][col] === 2) {
+                ctx.fillStyle = 'red';
+                ctx.fillRect(col * 30, row * 30, 30, 30);
+            } else if (levels[currentLevel][row][col] === 3) {
+                ctx.fillStyle = 'green';
+                ctx.fillRect(col * 30, row * 30, 30, 30);
+            } else if (levels[currentLevel][row][col] === 5) {
+                ctx.fillStyle = 'gold';
+                ctx.fillRect(col * 30, row * 30, 30, 30);
+            }
+        }
+    }
+}
+
+function loadNextLevel() {
+    currentLevel++;
+    if (currentLevel >= levels.length) {
+        alert("You've completed all levels!");
+        currentLevel = 0;
+    }
+    let startPosition = findPlayerStartPosition(currentLevel);
+    player.x = startPosition.x;
+    player.y = startPosition.y;
+    player.velocityY = 0;
+    localStorage.setItem('savePoint', JSON.stringify({ x: player.x, y: player.y, level: currentLevel }));
+}
+
+let startPosition = findPlayerStartPosition(currentLevel);
+let player = new Player(startPosition.x, startPosition.y);
+
+function gameLoop() {
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+    renderLevel();
+    player.update();
+    player.render();
+
+    requestAnimationFrame(gameLoop);
+}
+
+document.addEventListener('keydown', (e) => {
+    if (e.code === 'ArrowLeft') keys.left = true;
+    if (e.code === 'ArrowRight') keys.right = true;
+    if (e.code === 'ArrowUp') keys.up = true;
+    if (e.code === 'ArrowDown') keys.down = true;
+    if (e.code === 'Space') player.jump();
+});
+
+document.addEventListener('keyup', (e) => {
+    if (e.code === 'ArrowLeft') keys.left = false;
+    if (e.code === 'ArrowRight') keys.right = false;
+    if (e.code === 'ArrowUp') keys.up = false;
+    if (e.code === 'ArrowDown') keys.down = false;
+});
+
+gameLoop();