🎮ArcadeLab

趣味开车小游戏

by PrismGalaxy54
260 lines8.3 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.0, user-scalable=no">
    <title>趣味开车小游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            touch-action: none;
            -webkit-tap-highlight-color: transparent;
        }
        body {
            overflow: hidden;
            font-family: "微软雅黑", sans-serif;
            background: #f1f1f1;
        }
        /* 游戏画布 */
        #gameBox {
            width: 100vw;
            height: 70vh;
            background: linear-gradient(#87CEEB 8%, #72c247 8%);
            position: relative;
            overflow: hidden;
        }
        /* 树木样式 */
        .tree {
            position: absolute;
            width: 48px;
            height: 75px;
        }
        .tree-crown {
            width: 48px;
            height: 48px;
            background: #249130;
            border-radius: 50%;
            box-shadow: inset -5px -5px 10px #1a6b22;
        }
        .tree-trunk {
            width: 14px;
            height: 30px;
            background: #795548;
            margin: 0 auto;
            border-radius: 2px;
        }
        /* 小车 */
        #car {
            width: 52px;
            height: 30px;
            background: #e53935;
            border-radius: 8px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) rotate(0deg);
            box-shadow: 0 2px 6px rgba(0,0,0,0.3);
            transition: transform 0.03s linear;
        }
        /* 车辆窗户 */
        #car::before {
            content: "";
            position: absolute;
            width: 20px;
            height: 11px;
            background: #bbdefb;
            border-radius: 2px;
            top: 4px;
            left: 16px;
        }
        /* 震动动画 */
        .shake {
            animation: shake 0.2s ease-in-out;
        }
        @keyframes shake {
            0%,100% { transform: translate(-50%, -50%) rotate(var(--angle)); }
            25% { transform: translate(-45%, -50%) rotate(var(--angle)); }
            75% { transform: translate(-55%, -50%) rotate(var(--angle)); }
        }
        /* 信息面板 */
        .panel {
            position: absolute;
            top: 12px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0,0,0,0.5);
            color: #fff;
            padding: 6px 16px;
            border-radius: 20px;
            font-size: 16px;
            z-index: 10;
        }
        /* 控制区域 */
        #controlArea {
            width: 100vw;
            height: 30vh;
            background: #f8f8f8;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .keyBoard {
            display: grid;
            grid-template-columns: 75px 75px 75px;
            grid-template-rows: 75px 75px;
            gap: 15px;
        }
        .dirBtn {
            width: 75px;
            height: 75px;
            font-size: 30px;
            border: none;
            border-radius: 50%;
            background: #2196F3;
            color: #fff;
            box-shadow: 0 5px 0 #1565C0;
        }
        .dirBtn:active {
            transform: translateY(3px);
            box-shadow: 0 2px 0 #1565C0;
            background: #1976D2;
        }
        .btn-up { grid-column: 2; grid-row: 1; }
        .btn-left { grid-column: 1; grid-row: 2; }
        .btn-down { grid-column: 2; grid-row: 2; }
        .btn-right { grid-column: 3; grid-row: 2; }
    </style>
</head>
<body>
    <div id="gameBox">
        <div class="panel">分数:<span id="score">0</span> | 连续行驶加分,撞树扣分+震动</div>
        <div id="car"></div>
    </div>

    <div id="controlArea">
        <div class="keyBoard">
            <button class="dirBtn btn-up">↑</button>
            <button class="dirBtn btn-left">←</button>
            <button class="dirBtn btn-down">↓</button>
            <button class="dirBtn btn-right">→</button>
        </div>
    </div>

    <script>
        const gameBox = document.getElementById('gameBox');
        const car = document.getElementById('car');
        const scoreText = document.getElementById('score');
        const btns = document.querySelectorAll('.dirBtn');

        // 基础参数
        let carX = gameBox.clientWidth / 2;
        let carY = gameBox.clientHeight / 2;
        let carRotate = 0;
        const speed = 5;
        let score = 0;
        let runTime = 0; // 连续行驶计时
        const carW = 52;
        const carH = 30;
        let treeList = [];

        // 生成树木
        function initTree(num = 18) {
            for(let i = 0; i < num; i++) {
                const tree = document.createElement('div');
                tree.className = 'tree';
                tree.innerHTML = `<div class="tree-crown"></div><div class="tree-trunk"></div>`;
                let x = Math.random() * (gameBox.clientWidth - 60);
                let y = Math.random() * (gameBox.clientHeight - 80);
                tree.style.left = x + 'px';
                tree.style.top = y + 'px';
                gameBox.appendChild(tree);
                treeList.push({el: tree, x, y, w: 48, h: 75});
            }
        }
        initTree();

        // 更新车辆位置与样式
        function renderCar() {
            // 边界限制
            carX = Math.max(carW/2, Math.min(carX, gameBox.clientWidth - carW/2));
            carY = Math.max(carH/2, Math.min(carY, gameBox.clientHeight - carH/2));

            car.style.left = carX + 'px';
            car.style.top = carY + 'px';
            car.style.setProperty('--angle', carRotate + 'deg');
            car.style.transform = `translate(-50%, -50%) rotate(${carRotate}deg)`;

            checkHit();
        }

        // 碰撞检测
        function checkHit() {
            for(let tree of treeList) {
                if(
                    carX + carW/2 > tree.x &&
                    carX - carW/2 < tree.x + tree.w &&
                    carY + carH/2 > tree.y &&
                    carY - carH/2 < tree.y + tree.h
                ) {
                    // 撞树扣分+震动
                    score -= 8;
                    scoreText.innerText = score;
                    car.classList.add('shake');
                    setTimeout(()=> car.classList.remove('shake'), 200);
                    // 回退位置
                    carX -= (carRotate === 0 ? speed : carRotate === 180 ? -speed : 0);
                    carY -= (carRotate === 90 ? speed : carRotate === 270 ? -speed : 0);
                    runTime = 0; // 中断连续计分
                    break;
                }
            }
        }

        // 按键控制
        btns.forEach(btn => {
            let moveInterval = null;
            btn.addEventListener('touchstart', e => {
                e.preventDefault();
                moveInterval = setInterval(() => {
                    if(btn.classList.contains('btn-up')){
                        carY -= speed;
                        carRotate = 0;
                    }else if(btn.classList.contains('btn-down')){
                        carY += speed;
                        carRotate = 180;
                    }else if(btn.classList.contains('btn-left')){
                        carX -= speed;
                        carRotate = 270;
                    }else if(btn.classList.contains('btn-right')){
                        carX += speed;
                        carRotate = 90;
                    }
                    renderCar();
                }, 20);
            });
            btn.addEventListener('touchend', () => {
                clearInterval(moveInterval);
            });
        });

        // 连续行驶加分
        setInterval(() => {
            runTime++;
            if(runTime >= 3) { // 平稳行驶3秒开始加分
                score += 2;
                scoreText.innerText = score;
            }
        }, 1000);

        // 窗口适配重置
        window.addEventListener('resize', () => {
            carX = gameBox.clientWidth / 2;
            carY = gameBox.clientHeight / 2;
            renderCar();
        });
    </script>
</body>
</html>
.html

Game Source: 趣味开车小游戏

Creator: PrismGalaxy54

Libraries: none

Complexity: complex (260 lines, 8.3 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-prismgalaxy54" to link back to the original. Then publish at arcadelab.ai/publish.