[Day28]用Canvas打造自己的游乐场-labyrinth 收尾

今天要来把迷宫游戏做个收尾,其实也就检查一下有没有哪里有问题,那因为後来觉得55块砖的范围还有有点大,所以改成33.
另外就是在checkMapBrick有写错,所以有穿墙的bug.对此做了修正
那这边做为结尾,附上整饿由戏的整段code

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Second Game</title>
    <meta name="description" content="第三个游戏">
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
</head>

<body>
    <canvas id="playground" width="120" height="120"></canvas>
    <script>
        // 地图设定
        const MAP_BRICKS = 40;
        const BRICK_SPACING = 1;
        const BRICK_COLS = 33;
        const BRICK_ROWS = 22;

        // 视线范围
        var map_x = 0.0;
        var map_y = 0.0;

        // 移动速度
        const MOVE_SPEED = 2.5;

        // 玩家
        var player_x;
        var player_y;
        const PLAYER_R = 5;
        const KEY_LEFT_ARROW = 37;
        const KEY_UP_ARROW = 38;
        const KEY_RIGHT_ARROW = 39;
        const KEY_DOWN_ARROW = 40;
        var keyLeft = false;
        var keyRight = false;
        var keyTop = false;
        var keyDown = false;

        var map = [
            0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,
            1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1,
            1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1,
            1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
            1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1,
            1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1,
            1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
            1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1,
            1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1,
            1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
            1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
            1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
            1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
            1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
            1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1,
            1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1,
            1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1,
            1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1,
            1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1,
            1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

        ];

        window.onload = () => {
            canvas = document.getElementById('playground');
            canvasContext = canvas.getContext('2d');

            initInput();

            //一秒更新几次画面
            var timesPerSec = 30;
            setInterval(drawAll, 1000 / timesPerSec);

            resetPlayer();
        }

        // 负责更新画面
        drawAll = () => {
            console.log(keyTop,keyDown,keyLeft,keyRight);
            move();
            draw();
        }

        // 负责画画
        draw = () => {
            // background
            drawRectangle(0, 0, canvas.width, canvas.height, 'black');

            canvasContext.save();

            canvasContext.translate(-map_x, -map_y);

            // 小画面的地图
            drawMapInShadow();

            drawCircle(player_x, player_y, PLAYER_R, 'red');

            canvasContext.restore();
        }

        // 负责处理动作
        move = () => {
            map_x = player_x - canvas.width / 2;
            map_y = player_y - canvas.height / 2;

            playerMove();
        }

        // 小画面地图
        drawMapInShadow = () => {
            var mapLeftCol = Math.floor(map_x / MAP_BRICKS);
            var mapTopRow = Math.floor(map_y / MAP_BRICKS);

            var colFitOnScreen = Math.floor(canvas.width / MAP_BRICKS);
            var rowFitOnScreen = Math.floor(canvas.height / MAP_BRICKS);

            var mapRightCol = mapLeftCol + colFitOnScreen + 1;
            var mapBottomRow = mapTopRow + rowFitOnScreen + 1;

            for (var col = mapLeftCol; col < mapRightCol; col++) {
                for (var row = mapTopRow; row < mapBottomRow; row++) {
                    if (mapBrick(col, row)) {
                        drawRectangle(
                            col * MAP_BRICKS,
                            row * MAP_BRICKS,
                            MAP_BRICKS - BRICK_SPACING,
                            MAP_BRICKS - BRICK_SPACING,
                            'gray'
                        )
                    }
                }
            }
        }

        brickToIndex = (col, row) => {
            return (col + BRICK_COLS * row);
        }

        mapBrick = (col, row) => {
            var index = brickToIndex(col, row);
            return (map[index] == 1);
        }

        resetPlayer = () => {
            player_x = 660;
            player_y = 440;
        }

        initInput = () => {
            document.addEventListener("keydown", keyPressed);
            document.addEventListener("keyup", keyReleased);
        }

        keyPressed = (evt) => {
            setKeyState(evt.keyCode, true);
            evt.preventDefault();
        }

        keyReleased = (evt) => {
            setKeyState(evt.keyCode, false);
        }

        setKeyState = (key, to) => {
            if (key == KEY_LEFT_ARROW) {
                keyLeft = to;
            }
            if (key == KEY_RIGHT_ARROW) {
                keyRight = to;
            }
            if (key == KEY_UP_ARROW) {
                keyTop = to;
            }
            if (key == KEY_DOWN_ARROW) {
                keyDown = to;
            }
        }

        playerMove = () => {
            var next_x = player_x;
            var next_y = player_y;

            if (keyLeft) {
                next_x -= MOVE_SPEED;
            }
            if (keyRight) {
                next_x += MOVE_SPEED;
            }
            if (keyTop) {
                next_y -= MOVE_SPEED;
            }
            if (keyDown) {
                next_y += MOVE_SPEED;
            }

            if (checkMapBrick(next_x, next_y) == false) {
                player_x = next_x;
                player_y = next_y;
            }
        }

        checkMapBrick = (x, y) => {
            var col = Math.floor(x / MAP_BRICKS);
            var row = Math.floor(y / MAP_BRICKS);
            
            if (col < 0 || col >= MAP_BRICKS || row < 0 || row >= MAP_BRICKS) {
                return false;
            }

            var index = brickToIndex(col, row);
        
            return (map[index] == 1);
        }

        // 矩形元件
        drawRectangle = (topLeftX, topLeftY, boxWidth, boxHeight, color) => {
            canvasContext.fillStyle = color;
            canvasContext.fillRect(topLeftX, topLeftY, boxWidth, boxHeight);
        }

        // 圆形元件
        drawCircle = (centerX, centerY, r, color) => {
            canvasContext.fillStyle = color;
            canvasContext.beginPath();
            canvasContext.arc(centerX, centerY, r, 0, Math.PI * 2);
            canvasContext.fill();
        }

        // 画线
        drawLine = (beginX, beginY, endX, endY, color) => {
            canvasContext.strokeStyle = color;
            canvasContext.beginPath();
            canvasContext.moveTo(beginX, beginY);
            canvasContext.lineTo(endX, endY);
            canvasContext.stroke();
        }

        // 画生命
        drawLife = (lifeX, lifeY, size, color) => {
            canvasContext.fillStyle = color;
            canvasContext.beginPath();
            canvasContext.arc(lifeX + size / 4, lifeY + size / 4, size / 4, Math.PI * 1, Math.PI * 0);
            canvasContext.arc(lifeX + size * 3 / 4, lifeY + size / 4, size / 4, Math.PI * 1, Math.PI * 0);
            canvasContext.moveTo(lifeX + size, lifeY + size / 4);
            canvasContext.lineTo(lifeX + size / 2, lifeY + size);
            canvasContext.lineTo(lifeX, lifeY + size / 4);
            canvasContext.fill();
        }

        // 画出生命
        showLife = (num) => {
            for (let life_count = 0; life_count < num; life_count++) {
                drawLife(LIFE_SIZE * life_count, 0, LIFE_SIZE, 'red');
            }
        }

    </script>
</body>

</html>

<<:  Day 26. F2E-完善选择帐户

>>:  [铁人12:Day 29] 「AI 的未来十年」摘要 5:固有知识框架

Day05_客倌~要不要来一块小叮当的翻译蒟蒻XD"

阿~今天的笔记,真心觉得,给我来一口翻译蒟蒻吧,很多硬梆邦的东西,记不起来XD" ▉条文是...

[Lesson16] Data Binding

使用DataBinding,首先在build.gradle (Module: app)里增加 and...

# Day 19 Physical Memory Model (Summary)

一样先来个简单的总结吧! 这份文件 Physical Memory Model 是在描述 Linux...

Day12 [实作] 使用浏览器来拍照并加上滤镜

上一篇尝试了 WebRTC 的切换设备并显示自己的影像,今天我们将通过上一次的程序码来做拍照的功能并...