🎮ArcadeLab

贪吃蛇(带方向按钮)

by MysticMaker96
203 lines5.9 KB
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1">
    <title>贪吃蛇(带方向按钮)</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: Arial, sans-serif;
        }
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #1a1a1a;
            color: #fff;
            padding:15px;
        }
        #gameBox {
            border: 3px solid #4CAF50;
            background-color: #000;
            max-width:100%;
        }
        .info {
            margin-bottom: 10px;
            font-size: 20px;
        }
        .btn-start{
            margin: 8px;
            padding: 8px 16px;
            font-size: 16px;
            border: none;
            border-radius: 6px;
            background: #4CAF50;
            color: white;
            cursor: pointer;
        }
        .control-box{
            margin-top:15px;
            display:grid;
            grid-template-columns: repeat(3, 70px);
            gap:8px;
        }
        .dir-btn{
            width:70px;
            height:70px;
            font-size:28px;
            border:none;
            border-radius:12px;
            background:#333;
            color:#fff;
        }
        .empty{
            visibility:hidden;
        }
    </style>
</head>
<body>
    <div class="info">得分:<span id="score">0</span></div>
    <canvas id="gameBox" width="360" height="360"></canvas>
    <button class="btn-start" id="startBtn">开始 / 重新开始</button>

    <!-- 虚拟方向按钮 -->
    <div class="control-box">
        <div class="empty"></div>
        <button class="dir-btn" data-dir="up">↑</button>
        <div class="empty"></div>

        <button class="dir-btn" data-dir="left">←</button>
        <div class="empty"></div>
        <button class="dir-btn" data-dir="right">→</button>

        <div class="empty"></div>
        <button class="dir-btn" data-dir="down">↓</button>
        <div class="empty"></div>
    </div>

    <div style="margin-top:10px;color:#aaa;font-size:14px;">
        电脑:方向键|手机:点上面箭头按钮
    </div>

    <script>
        const canvas = document.getElementById('gameBox');
        const ctx = canvas.getContext('2d');
        const scoreDom = document.getElementById('score');
        const startBtn = document.getElementById('startBtn');
        const dirBtns = document.querySelectorAll('.dir-btn');

        const size = 20;
        const count = canvas.width / size;
        let snake = [];
        let food = {};
        let dir = {x:1, y:0};
        let nextDir = {x:1, y:0};
        let score = 0;
        let timer = null;
        let isRun = false;

        function initSnake(){
            snake = [
                {x:5, y:5},
                {x:4, y:5},
                {x:3, y:5}
            ];
            dir = {x:1, y:0};
            nextDir = {x:1, y:0};
            score = 0;
            scoreDom.innerText = score;
            createFood();
        }

        function createFood(){
            let ok = false;
            while(!ok){
                food = {
                    x: Math.floor(Math.random()*count),
                    y: Math.floor(Math.random()*count)
                }
                ok = !snake.some(s=>s.x===food.x && s.y===food.y)
            }
        }

        function draw(){
            ctx.fillStyle="#000";
            ctx.fillRect(0,0,canvas.width,canvas.height);
            ctx.fillStyle="#4CAF50";
            snake.forEach((s,idx)=>{
                if(idx===0) ctx.fillStyle="#8BC34A";
                else ctx.fillStyle="#4CAF50";
                ctx.fillRect(s.x*size, s.y*size, size-1, size-1);
            })
            ctx.fillStyle="#f44336";
            ctx.fillRect(food.x*size, food.y*size, size-1, size-1);
        }

        function update(){
            dir = {...nextDir};
            const head = {x: snake[0].x + dir.x, y: snake[0].y + dir.y};
            if(head.x<0 || head.x>=count || head.y<0 || head.y>=count){
                gameOver();
                return;
            }
            if(snake.some(s=>s.x===head.x && s.y===head.y)){
                gameOver();
                return;
            }
            snake.unshift(head);
            if(head.x === food.x && head.y === food.y){
                score +=10;
                scoreDom.innerText = score;
                createFood();
            }else{
                snake.pop();
            }
            draw();
        }

        function gameOver(){
            clearInterval(timer);
            isRun = false;
            alert(`游戏结束!得分:${score}`);
        }

        function startGame(){
            clearInterval(timer);
            initSnake();
            draw();
            isRun = true;
            timer = setInterval(update,130);
        }

        // 键盘监听(电脑)
        document.addEventListener('keydown',(e)=>{
            if(!isRun) return;
            switch(e.key){
                case 'ArrowUp': if(dir.y!==1) nextDir={x:0,y:-1};break;
                case 'ArrowDown': if(dir.y!==-1) nextDir={x:0,y:1};break;
                case 'ArrowLeft': if(dir.x!==1) nextDir={x:-1,y:0};break;
                case 'ArrowRight': if(dir.x!==-1) nextDir={x:1,y:0};break;
            }
        })

        // 虚拟按钮监听(手机)
        dirBtns.forEach(btn=>{
            btn.onclick = ()=>{
                if(!isRun) return;
                const d = btn.dataset.dir;
                if(d==='up' && dir.y!==1) nextDir={x:0,y:-1};
                if(d==='down' && dir.y!==-1) nextDir={x:0,y:1};
                if(d==='left' && dir.x!==1) nextDir={x:-1,y:0};
                if(d==='right' && dir.x!==-1) nextDir={x:1,y:0};
            }
        })

        startBtn.onclick = startGame;
        draw();
    </script>
</body>
</html>

Game Source: 贪吃蛇(带方向按钮)

Creator: MysticMaker96

Libraries: none

Complexity: complex (203 lines, 5.9 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-mysticmaker96-mw5sfabm" to link back to the original. Then publish at arcadelab.ai/publish.