Imgflip Logo Icon
Welcome to MS_memer_group. Earn your PhD in shitposting during your spare time, feel free to use this handy study guide: imgflip.com/i/9v4nax | MSmg archives: imgflip.com/i/8u9dsa | Copypasta Microwave: imgflip.com/i/6u6sek | Stream Mood: AYMY wins in all categories, even in ones xe is not present in.

Imgflip Pro

  • AI creation tools & better GIFs
  • No ads
  • Custom 6x6 profile icon and new colors
  • Your images jump to the top of approval queues
Go Pro
Check the NSFW checkbox to enable not-safe-for-work images
NSFW
38 views, 1 upvote, 4 comments
Check the NSFW checkbox to enable not-safe-for-work images
NSFW
74 views, 2 upvotes, 1 comment

my hand hurts fr

my hand hurts fr | <!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>gd</title>
    <meta name="description" content="yuh">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body {
            margin: 0;
            background: #111;
            overflow: hidden;
        }

        canvas {
            display: block;
            margin: auto;
            background: #000099;
        }
    </style>
</head>

<body>
    <canvas id="game"></canvas>

    <script>
        /* Canvas Setup */
        const canvas = document.getElementById("game");
        const ctx = canvas.getContext("2d");
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        window.addEventListener("resize", () => {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });

        /* Global Variables */
        const TILE_SIZE = 40;
        const SPIKE_HITBOX_SIZE = TILE_SIZE / 2;

        let cameraX = 0;

        let paused = false;
        let input = { pressed: false };
        let wasPressed = false;
        let jumpBuffered = false;
        let activatedPads = new Set();
        let activatedOrbs = new Set();
        let activatedPortals = new Set();
        let levelCompleted = false;

        let player = {
            x: 0,
            y: 0,
            prevX: 0,
            width: TILE_SIZE,
            height: TILE_SIZE,
            velY: 0,
            gravity: 0.6,
            gravityState: 1, // 1 = normal, -1 = inverted
            jumpForce: -10.5,
            grounded: false,
            speed: 5.5,
            rotation: 0,
            rotationSpeed: Math.PI / 30,
            gamemode: "cube"
        };

        /* Level Data */
        const TILE_TYPES = {
            "#": { solid: true },

            "A": { hazard: true },
            "^": { hazard: true },
            "V": { hazard: true },
            "v": { hazard: true },
            "X": { hazard: true },

            "y": { orb: true },
            "m": { orb: true },
            "r": { orb: true },
            "b": { orb: true },

            "Y": { pad: true },
            "M": { pad: true },
            "R": { pad: true },
            "B": { pad: true },

            ")": { portal: true, gravity: -1 },
            "(": { portal: true, gravity: 1 },
            "]": { portal: true, gamemode: "cube" },
            "[": { portal: true, gamemode: "ship" },
            "}": { portal: true, gamemode: "ball" },
            "{": { portal: true, gamemode: "ufo" },

            "E": { levelEnd: true }
        };

        const levelData = {
            level1: [
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#........#...................",
                "..............................#...........#.................#..........#............................",
                "..............................#...........#............................#............................",
                "..............................#############............................#............................",
                "................................................................................#...................",
                "........................}...........................{.......#...................#...................",
                "......................#...........^.......y....y.....Y......#...................#...................",
                "..................#...#..##########..................#......#..........#........#...................",
                "*......^A.....#...#...#..#........#AAAAAAAAAAAAAAAAAA#......#..........#........#...................",
                "###############XXX#XXX##############################################################################",
                "####################################################################################################"
            ]
        };

        const music = new Audio("SuperUltraMDK.mp3");
        music.loop = true;
        music.volume = 0.5;

        /* Level Helpers */
        function getTile(col, row) {
            if (
                row < 0 ||
                row >= levelData.level1.length ||
                col < 0 ||
                col >= levelData.level1[0].length
            ) return null;

            return levelData.level1[row][col];
        }

        function tileKey(col, row) {
            return col + "," + row;
        }

        function findStart() {
            for (let row = 0; row < levelData.level1.length; row++) {
                for (let col = 0; col < levelData.level1[row].length; col++) {
                    if (levelData.level1[row][col] === "*") {
                        player.x = col * TILE_SIZE;
                        player.y = row * TILE_SIZE;
                    }
                }
            }
        }

        function isSolid(tile) {
            return TILE_TYPES[tile]?.solid;
        }

        function isHazard(tile) {
            return TILE_TYPES[tile]?.hazard;
        }

        function isOrb(tile) {
            return TILE_TYPES[tile]?.orb;
        }

        function isPad(tile) {
            return TILE_TYPES[tile]?.pad;
        }

        function isPortal(tile) {
            return TILE_TYPES[tile]?.portal;
        }

        function isLevelEnd(tile) {
            return TILE_TYPES[tile]?.levelEnd;
        }

        /* Input Handling */
        function setupInput() {
            window.addEventListener("keydown", (e) => {
                if (e.code === "Space" || e.code === "ArrowUp") {
                    input.pressed = true;
                }
            });

            window.addEventListener("keyup", (e) => {
                if (e.code === "Space" || e.code === "ArrowUp") {
                    input.pressed = false;
                }
            });

            window.addEventListener("mousedown", () => input.pressed = true);
            window.addEventListener("mouseup", () => input.pressed = false);

            window.addEventListener("touchstart", (e) => {
                e.preventDefault();
                input.pressed = true;
            }, { passive: false });

            window.addEventListener("touchend", () => input.pressed = false);

            window.addEventListener("keydown", (e) => {

                if (e.code === "KeyP" || e.code === "Escape") {
                    togglePause();
                }

                if (e.code === "Space" || e.code === "ArrowUp") {
                    input.pressed = true;
                    music.play().catch(() => { });
                }
            });
        }

        /* Physics and Movement */
        function applyPhysics() {
            const justPressed = input.pressed && !wasPressed;
            wasPressed = input.pressed;

            if (justPressed && !player.grounded) {
                jumpBuffered = true;
            }

            if (player.gamemode === "cube") {
                if (player.grounded && input.pressed) {
                    player.velY = player.jumpForce * player.gravityState;
                    jumpBuffered = false;
                }
            } else if (player.gamemode === "ball") {
                if (justPressed && player.grounded) {
                    player.gravityState *= -1;
                    player.velY = 0;
                }
            } else if (player.gamemode === "ufo") {
                if (justPressed) {
                    player.velY = player.jumpForce * player.gravityState;
                    jumpBuffered = false;
                    player.grounded = false;
                }
            }

            player.prevX = player.x;
            player.x += player.speed;

            player.velY += player.gravity * player.gravityState;
            player.y += player.velY;

            player.grounded = false;

            if (player.gamemode === "cube") {
                if (!player.grounded) {
                    player.rotation += player.rotationSpeed * player.gravityState;
                }
            } else if (player.gamemode === "ball") {
                player.rotation += (player.speed / TILE_SIZE) * 2 * Math.PI * player.gravityState;
            } else if (player.gamemode === "ufo") {
                player.rotation = 0;
            }
        }

        /* Collision Handling */
        function handleCollisions() {

            const leftCol = Math.floor(player.x / TILE_SIZE);
            const rightCol = Math.floor((player.x + player.width - 1) / TILE_SIZE);
            const topRow = Math.floor(player.y / TILE_SIZE);
            const bottomRow = Math.floor((player.y + player.height) / TILE_SIZE);

            for (let row = topRow; row <= bottomRow; row++) {
                for (let col = leftCol; col <= rightCol; col++) {

                    const tile = getTile(col, row);
                    if (!tile) continue;

                    const tileX = col * TILE_SIZE;
                    const tileY = row * TILE_SIZE;

                    if (isSolid(tile)) {

                        if (player.gravityState === 1) {

                            // landing on floor
                            if (player.velY > 0 && player.y + player.height > tileY && player.y < tileY) {
                                player.y = tileY - player.height;
                                player.velY = 0;
                                player.grounded = true;

                                if (player.gamemode === "cube") {
                                    player.rotation = Math.round(player.rotation / (Math.PI / 2)) * (Math.PI / 2);
                                }
                            }

                            // hitting ceiling
                            else if (player.velY < 0 && player.y < tileY + TILE_SIZE) {
                                player.y = tileY + TILE_SIZE;
                                player.velY = 0;
                            }

                        } else {

                            // landing on ceiling
                            if (player.velY < 0 && player.y < tileY + TILE_SIZE && player.y + player.height > tileY + TILE_SIZE) {
                                player.y = tileY + TILE_SIZE;
                                player.velY = 0;
                                player.grounded = true;

                                if (player.gamemode === "cube") {
                                    player.rotation = Math.round(player.rotation / (Math.PI / 2)) * (Math.PI / 2);
                                }
                            }

                            // hitting floor
                            else if (player.velY > 0 && player.y + player.height > tileY) {
                                player.y = tileY - player.height;
                                player.velY = 0;
                            }
                        }
                    }

                    if (isHazard(tile) && checkSpikeCollision(tileX, tileY)) {
                        resetPlayer();
                        console.log("Hit hazard at (" + col + ", " + row + ")");
                    }

                    if (isPad(tile)) {

                        const key = tileKey(col, row);

                        const padHeight = TILE_SIZE / 3;
                        const padX = tileX;
                        const padY = tileY + TILE_SIZE - padHeight;

                        const touching =
                            player.x < padX + TILE_SIZE &&
                            player.x + player.width > padX &&
                            player.y + player.height > padY &&
                            player.y < padY + padHeight;

                        if (touching && !activatedPads.has(key)) {

                            activatedPads.add(key);

                            if (tile === "Y") {
                                player.velY = -15 * player.gravityState;
                            } else if (tile === "M") {
                                player.velY = -10 * player.gravityState;
                            } else if (tile === "R") {
                                player.velY = -20 * player.gravityState;
                            } else if (tile === "B") {
                                player.velY = -5 * player.gravityState;
                                player.gravityState *= -1;
                            }

                            player.grounded = false;
                            return;
                        }

                        if (!touching) {
                            activatedPads.delete(key);
                        }
                    }

                    if (isOrb(tile)) {

                        const key = tileKey(col, row);

                        if (isCollidingWithTile(tileX, tileY, TILE_SIZE)) {

                            if ((input.pressed || jumpBuffered) && !activatedOrbs.has(key)) {

                                activatedOrbs.add(key);

                                if (tile === "y") {
                                    player.velY = player.jumpForce * player.gravityState;
                                } else if (tile === "m") {
                                    player.velY = player.jumpForce * player.gravityState + 5;
                                } else if (tile === "r") {
                                    player.velY = player.jumpForce * player.gravityState - 5;
                                } else if (tile === "b") {
                                    player.velY = -5 * player.gravityState;
                                    player.gravityState *= -1;
                                }

                                jumpBuffered = false;
                            }
                        } else {
                            activatedOrbs.delete(key);
                        }
                    }

                    if (isPortal(tile)) {
                        const key = tileKey(col, row);

                        if (isCollidingWithTile(tileX, tileY, TILE_SIZE)) {
                            if (!activatedPortals.has(key)) {
                                activatedPortals.add(key);
                                const portal = TILE_TYPES[tile];

                                if (portal.gravity !== undefined) {
                                    player.gravityState = portal.gravity;
                                }

                                if (portal.gamemode) {
                                    player.gamemode = portal.gamemode;
                                }
                            }
                        } else {
                            activatedPortals.delete(key);
                        }
                    }

                    if (isLevelEnd(tile)) {
                        const key = tileKey(col, row);

                        if (isCollidingWithTile(tileX, tileY, TILE_SIZE)) {

                            if ((input.pressed || jumpBuffered) && !activatedOrbs.has(key)) {
                                jumpBuffered = false;
                                completeLevel();
                            }
                        } else {
                            activatedOrbs.delete(key);
                        }
                    }
                }
            }
        }

        function checkSpikeCollision(tileX, tileY) {
            const hitboxX = tileX + (TILE_SIZE - SPIKE_HITBOX_SIZE) / 2;
            const hitboxY = tileY + (TILE_SIZE - SPIKE_HITBOX_SIZE) / 2;

            return player.x < hitboxX + SPIKE_HITBOX_SIZE &&
                player.x + player.width > hitboxX &&
                player.y < hitboxY + SPIKE_HITBOX_SIZE &&
                player.y + player.height > hitboxY;
        }

        function isCollidingWithTile(tileX, tileY, tileSize) {
            return player.x < tileX + tileSize &&
                player.x + player.width > tileX &&
                player.y < tileY + tileSize &&
                player.y + player.height > tileY;
        }

        function checkBlockCrush() {

            const col = Math.floor((player.x + player.width / 2) / TILE_SIZE);
            const row = Math.floor((player.y + player.height / 2) / TILE_SIZE);

            const tile = getTile(col, row);

            if (isSolid(tile)) {
                resetPlayer();
                console.log("Crushed inside block at (" + col + ", " + row + ")");
            }
        }

        /* Camera, Progress Bar, & Rendering*/
        function updateCamera() {
            const targetX = player.x - canvas.width / 4;
            if (targetX > cameraX) {
                cameraX += (targetX - cameraX) * 0.1;
            }
        }

        function getProgress() {
            const levelWidth = levelData.level1[0].length * TILE_SIZE;
            return Math.min(player.x / levelWidth, 1);
        }

        function drawProgressBar() {
            const progress = getProgress();

            const barWidth = canvas.width * 0.6;
            const barHeight = 10;

            const x = (canvas.width - barWidth) / 2;
            const y = 20;

            // Background
            ctx.fillStyle = "rgba(255,255,255,0.2)";
            ctx.fillRect(x, y, barWidth, barHeight);

            // Fill
            ctx.fillStyle = "lime";
            ctx.fillRect(x, y, barWidth * progress, barHeight);

            // Outline
            ctx.strokeStyle = "white";
            ctx.lineWidth = 2;
            ctx.strokeRect(x, y, barWidth, barHeight);

            ctx.fillStyle = "white";
            ctx.font = "16px Arial";
            ctx.textAlign = "center";
            ctx.fillText(Math.floor(progress * 100) + "%", canvas.width / 2, y + 25);
        }

        function render() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            drawProgressBar();
            drawLevel();
            drawPlayer();

            if (levelCompleted) {
                ctx.fillStyle = "rgba(0,0,0,0.5)";
                ctx.fillRect(0, 0, canvas.width, canvas.height);

                ctx.fillStyle = "lime";
                ctx.font = "60px Arial";
                ctx.textAlign = "center";

                ctx.fillText("Level Complete!", canvas.width / 2, canvas.height / 2);
            }

            if (paused && !levelCompleted) {

                ctx.fillStyle = "rgba(0,0,0,0.5)";
                ctx.fillRect(0, 0, canvas.width, canvas.height);

                ctx.fillStyle = "white";
                ctx.font = "48px Arial";
                ctx.textAlign = "center";

                ctx.fillText("Game Paused", canvas.width / 2, canvas.height / 2);
            }
        }

        /* Drawing Functions */
        function drawLevel() {

            const startCol = Math.floor(cameraX / TILE_SIZE);
            const endCol = startCol + Math.ceil(canvas.width / TILE_SIZE) + 1;

            for (let row = 0; row < levelData.level1.length; row++) {

                for (let col = startCol; col < endCol; col++) {

                    const tile = getTile(col, row);
                    if (!tile) continue;

                    const x = col * TILE_SIZE - cameraX;
                    const y = row * TILE_SIZE;

                    if (isSolid(tile)) {
                        drawSolid(tile, x, y);
                    }

                    if (isHazard(tile)) {
                        drawHazard(tile, x, y);
                    }

                    if (isOrb(tile)) {
                        drawOrb(tile, x, y);
                    }

                    if (isPad(tile)) {
                        drawPad(tile, x, y);
                    }

                    if (isPortal(tile)) {
                        drawPortal(tile, x, y);
                    }

                    if (isLevelEnd(tile)) {
                        drawEnd(tile, x, y);
                    }
                }
            }
        }

        function drawPlayer() {
            const drawX = player.x - cameraX + player.width / 2;
            const drawY = player.y + player.height / 2;

            ctx.save();
            ctx.translate(drawX, drawY);
            if (player.gamemode === "cube") {
                ctx.rotate(player.rotation);

                ctx.fillStyle = "lime";
                ctx.fillRect(-player.width / 2, -player.height / 2, player.width, player.height);
            } else if (player.gamemode === "ball") {
                ctx.rotate(player.rotation);

                ctx.fillStyle = "red";
                ctx.beginPath();
                const size = TILE_SIZE / 2;
                ctx.moveTo(0, size);
                ctx.lineTo(0, size / 2);
                ctx.lineTo(size / 1.5, size / 1.5);
                ctx.lineTo(size / 3, size / 3);
                ctx.lineTo(size, 0);
                ctx.lineTo(size / 2, 0);
                ctx.lineTo(size / 1.5, -size / 1.5);
                ctx.lineTo(size / 3, -size / 3);
                ctx.lineTo(0, -size);
                ctx.lineTo(0, -size / 2);
                ctx.lineTo(-size / 1.5, -size / 1.5);
                ctx.lineTo(-size / 3, -size / 3);
                ctx.lineTo(-size, 0);
                ctx.lineTo(-size / 2, 0);
                ctx.lineTo(-size / 1.5, size / 1.5);
                ctx.lineTo(-size / 3, size / 3);
                ctx.closePath();
                ctx.fill();
            } else if (player.gamemode === "ufo") {
                ctx.fillStyle = "orange";

                // simple UFO shape
                ctx.beginPath();
                ctx.ellipse(0, 0, TILE_SIZE / 2, TILE_SIZE / 3, 0, 0, Math.PI * 2);
                ctx.fill();

                ctx.fillStyle = "white";
                ctx.beginPath();
                ctx.arc(0, -TILE_SIZE / 6, TILE_SIZE / 6, 0, Math.PI * 2);
                ctx.fill();
            }

            ctx.restore();
        }

        function drawSolid(tile, x, y) {
            ctx.save();
            ctx.fillStyle = "grey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;
            ctx.fillRect(x, y, TILE_SIZE, TILE_SIZE);
            ctx.strokeRect(x, y, TILE_SIZE, TILE_SIZE);
            ctx.restore();
        }

        function drawHazard(tile, x, y) {
            ctx.save();
            ctx.fillStyle = "red";
            ctx.beginPath();

            if (tile === "A") {
                // Full spike pointing up
                ctx.moveTo(x, y + TILE_SIZE);
                ctx.lineTo(x + TILE_SIZE / 2, y);
                ctx.lineTo(x + TILE_SIZE, y + TILE_SIZE);
            } else if (tile === "^") {
                // Half spike pointing up
                ctx.moveTo(x, y + TILE_SIZE);
                ctx.lineTo(x + TILE_SIZE / 2, y + TILE_SIZE / 2);
                ctx.lineTo(x + TILE_SIZE, y + TILE_SIZE);
            } else if (tile === "V") {
                // Full spike pointing down
                ctx.moveTo(x, y);
                ctx.lineTo(x + TILE_SIZE / 2, y + TILE_SIZE);
                ctx.lineTo(x + TILE_SIZE, y);
            } else if (tile === "v") {
                // Half spike pointing down
                ctx.moveTo(x, y);
                ctx.lineTo(x + TILE_SIZE / 2, y + TILE_SIZE / 2);
                ctx.lineTo(x + TILE_SIZE, y);
            } else if (tile === "X") {
                ctx.moveTo(x, y + TILE_SIZE);
                ctx.lineTo(x + TILE_SIZE, y + TILE_SIZE);
                ctx.lineTo(x + TILE_SIZE, y);
                ctx.lineTo(x, y);
            }

            ctx.fill();
            ctx.restore();
        }

        function drawOrb(tile, x, y) {
            ctx.save();
            if (tile === "y") {
                ctx.fillStyle = "yellow";
            } else if (tile === "m") {
                ctx.fillStyle = "magenta";
            } else if (tile === "r") {
                ctx.fillStyle = "red";
            } else if (tile === "b") {
                ctx.fillStyle = "cyan"
            }
            ctx.beginPath();
            ctx.arc(x + TILE_SIZE / 2, y + TILE_SIZE / 2, TILE_SIZE / 3, 0, 2 * Math.PI);
            ctx.fill();

            ctx.beginPath();
            ctx.strokeStyle = "white";
            ctx.lineWidth = 3;
            ctx.arc(x + TILE_SIZE / 2, y + TILE_SIZE / 2, TILE_SIZE / 2, 0, 2 * Math.PI);
            ctx.stroke();
            ctx.restore();
        }

        function drawPad(tile, x, y) {
            ctx.save();
            if (tile === "Y") {
                ctx.fillStyle = "yellow"
            } else if (tile === "M") {
                ctx.fillStyle = "magenta"
            } else if (tile === "R") {
                ctx.fillStyle = "red"
            } else if (tile === "B") {
                ctx.fillStyle = "cyan"
            }
            const padHeight = TILE_SIZE / 3;
            ctx.fillRect(x, y + TILE_SIZE - padHeight, TILE_SIZE, padHeight);
            ctx.restore();
        }

        function drawPortal(tile, x, y) {
            ctx.save();

            let color = "";
            if (tile === ")") {
                color = "yellow";
            } else if (tile === "(") {
                color = "blue";
            } else if (tile === "]") {
                color = "lime";
            } else if (tile === "[") {
                color = "magenta";
            } else if (tile === "}") {
                color = "red";
            } else if (tile === "{") {
                color = "orange";
            }

            // Glow
            const gradient = ctx.createRadialGradient(
                x + TILE_SIZE / 2,
                y,
                5,
                x + TILE_SIZE / 2,
                y,
                TILE_SIZE
            );

            gradient.addColorStop(0, color);
            gradient.addColorStop(1, "transparent");

            ctx.fillStyle = gradient;
            ctx.fillRect(x - TILE_SIZE / 2, y - TILE_SIZE, TILE_SIZE * 2, TILE_SIZE * 3);

            // Core
            ctx.fillStyle = color;
            ctx.fillRect(x, y - TILE_SIZE / 2, TILE_SIZE, TILE_SIZE * 2);

            ctx.restore();
        }

        function drawEnd(tile, x, y) {
            ctx.save();
            // Glow
            const gradient = ctx.createRadialGradient(
                x + TILE_SIZE / 2,
                y + TILE_SIZE / 2,
                5,
                x + TILE_SIZE / 2,
                y + TILE_SIZE / 2,
                TILE_SIZE
            );

            gradient.addColorStop(0, "orange");
            gradient.addColorStop(1, "transparent");

            ctx.fillStyle = gradient;
            ctx.beginPath();
            ctx.arc(x + TILE_SIZE / 2, y + TILE_SIZE / 2, TILE_SIZE, 0, 2 * Math.PI);
            ctx.fill();

            // Core circle
            ctx.fillStyle = "orange";
            ctx.beginPath();
            ctx.arc(x + TILE_SIZE / 2, y + TILE_SIZE / 2, TILE_SIZE / 3, 0, 2 * Math.PI);
            ctx.fill();

            // Ring
            ctx.strokeStyle = "white";
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.arc(x + TILE_SIZE / 2, y + TILE_SIZE / 2, TILE_SIZE / 2, 0, 2 * Math.PI);
            ctx.stroke();

            ctx.restore();
        }

        function update() {
            if (paused) return;

            applyPhysics();
            handleCollisions();
            checkBlockCrush();
            updateCamera();
            checkLevelComplete();
        }

        /* Reset, Loop, Check for Complete, Pause, Init */
        function resetPlayer() {
            player.gamemode = "cube";
            levelCompleted = false;
            findStart();
            music.currentTime = 0;
            cameraX = 0;
            player.velY = 0;
            player.gravityState = 1;
            jumpBuffered = false;

            activatedPads.clear();
            activatedOrbs.clear();
            activatedPortals.clear();

            console.log("Player reset");
        }

        function gameLoop() {
            update();
            render();
            requestAnimationFrame(gameLoop);
        }

        function checkLevelComplete() {
            const levelWidth = levelData.level1[0].length * TILE_SIZE;

            if (player.x > levelWidth - TILE_SIZE / 2) {
                completeLevel();
            }
        }

        function completeLevel() {
            if (levelCompleted) return;

            levelCompleted = true;
            paused = true;

            music.pause();

            console.log("Level Complete!");
        }

        function togglePause() {

            paused = !paused;

            if (paused) {
                music.pause();
                console.log("Game paused");
            } else {
                music.play().catch(() => { });
                console.log("Game unpaused");
            }

        }

        function init() {
            setupInput();
            findStart();
            gameLoop();
            music.play().catch(() => { });
            console.log("Game initialized");
        }

        init();
    </script>
</body>

</html> | image tagged in my hand hurts fr | made w/ Imgflip meme maker
50 views, 1 upvote
made w/ Imgflip meme maker
37 views, 3 upvotes
made w/ Imgflip meme maker
41 views, 3 upvotes
37 views, 3 upvotes, 1 comment
36 views, 2 upvotes
45 views, 3 upvotes
38 views, 3 upvotes
44 views, 5 upvotes

Doctor and Maddox - space temp

45 views, 4 upvotes, 9 comments
49 views, 3 upvotes
42 views, 3 upvotes
58 views, 7 upvotes, 1 comment