about summary refs log tree commit diff stats
path: root/js/mountain/game.js
diff options
context:
space:
mode:
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();
a id='n520' href='#n520'>520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603