当前位置: 首页 > news >正文

大模型生成浏览器端的初级俄罗斯方块

在这里插入图片描述这个真的很容易做到。
在这里插入图片描述

但我不擅长玩这个游戏。

<!DOCTYPE html>
<html>
<head>
    <title>儿童俄罗斯方块</title>
    <style>
        body {
            font-family: sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #f0f0f0;
        }
        #gameCanvas {
            border: 4px solid #333;
            background-color: #eee;
        }
        #startButton {
            padding: 10px 20px;
            font-size: 18px;
            cursor: pointer;
            margin-top: 20px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
        }
        #startButton:hover {
            background-color: #45a049;
        }
        .controls {
            margin-top: 10px;
            font-size: 16px;
            color: #777;
        }
    </style>
</head>
<body>
    <h1>儿童俄罗斯方块</h1>
    <canvas id="gameCanvas" width="240" height="400"></canvas>
    <button id="startButton">开始游戏</button>
    <div class="controls">
        使用方向键 <span style="font-weight: bold;"></span> <span style="font-weight: bold;"></span> 移动,<span style="font-weight: bold;"></span> 加速下落,<span style="font-weight: bold;"></span> 旋转。
    </div>

    <audio id="startGameSound" src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3"></audio>
    <audio id="lineClearSound" src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/doorbell.mp3"></audio>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const startButton = document.getElementById('startButton');
        const startGameSound = document.getElementById('startGameSound');
        const lineClearSound = document.getElementById('lineClearSound');

        const grid = [];
        const gridRows = 20;
        const gridCols = 12;
        const blockSize = 20;
        let currentPiece = null;
        let gameInterval;
        let isGameOver = false;
        let gameSpeed = 500; // 初始速度,毫秒

        const colors = [
            null, 'lightblue', 'yellow', 'orange', 'purple', 'green', 'red', 'blue'
        ];

        const pieces = [
            [[0,0,0,0],[0,1,1,0],[0,1,1,0],[0,0,0,0]], // O
            [[0,0,0,0],[0,0,2,0],[2,2,2,0],[0,0,0,0]], // T
            [[0,0,0,0],[0,3,3,0],[3,3,0,0],[0,0,0,0]], // S
            [[0,0,0,0],[3,3,0,0],[0,3,3,0],[0,0,0,0]], // Z
            [[0,0,0,0],[0,0,0,4],[4,4,4,4],[0,0,0,0]], // I
            [[0,0,0,0],[0,0,5,0],[0,0,5,0],[5,5,0,0]], // L
            [[0,0,0,0],[0,6,0,0],[0,6,0,0],[6,6,0,0]]  // J
        ];

        function initGrid() {
            for (let y = 0; y < gridRows; y++) {
                grid[y] = [];
                for (let x = 0; x < gridCols; x++) {
                    grid[y][x] = 0;
                }
            }
        }

        function createNewPiece() {
            const randomIndex = Math.floor(Math.random() * (pieces.length -1)) + 1; // 排除索引0的null
            const piece = pieces[randomIndex];
            return {
                shape: piece,
                colorIndex: randomIndex,
                x: Math.floor(gridCols / 2) - Math.ceil(piece[0].length / 2),
                y: 0
            };
        }

        function drawBlock(x, y, colorIndex) {
            ctx.fillStyle = colors[colorIndex];
            ctx.fillRect(x * blockSize, y * blockSize, blockSize, blockSize);
            ctx.strokeStyle = '#000';
            ctx.strokeRect(x * blockSize, y * blockSize, blockSize, blockSize);
        }

        function drawGrid() {
            for (let y = 0; y < gridRows; y++) {
                for (let x = 0; x < gridCols; x++) {
                    if (grid[y][x] !== 0) {
                        drawBlock(x, y, grid[y][x]);
                    }
                }
            }
        }

        function drawPiece() {
            if (currentPiece) {
                for (let y = 0; y < currentPiece.shape.length; y++) {
                    for (let x = 0; x < currentPiece.shape[y].length; x++) {
                        if (currentPiece.shape[y][x] !== 0) {
                            drawBlock(currentPiece.x + x, currentPiece.y + y, currentPiece.colorIndex);
                        }
                    }
                }
            }
        }

        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            drawGrid();
            drawPiece();
        }

        function collision(piece) {
            for (let y = 0; y < piece.shape.length; y++) {
                for (let x = 0; x < piece.shape[y].length; x++) {
                    if (piece.shape[y][x] !== 0) {
                        const newX = piece.x + x;
                        const newY = piece.y + y;
                        if (newY >= gridRows || newX < 0 || newX >= gridCols || (newY >= 0 && grid[newY][newX] !== 0)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        function mergePiece() {
            for (let y = 0; y < currentPiece.shape.length; y++) {
                for (let x = 0; x < currentPiece.shape[y].length; x++) {
                    if (currentPiece.shape[y][x] !== 0) {
                        grid[currentPiece.y + y][currentPiece.x + x] = currentPiece.colorIndex;
                    }
                }
            }
        }

        function movePieceDown() {
            if (!currentPiece) return;
            currentPiece.y++;
            if (collision(currentPiece)) {
                currentPiece.y--;
                mergePiece();
                currentPiece = createNewPiece();
                if (collision(currentPiece)) {
                    gameOver();
                }
                clearLines();
            }
        }

        function movePieceLeft() {
            if (!currentPiece) return;
            currentPiece.x--;
            if (collision(currentPiece)) {
                currentPiece.x++;
            }
        }

        function movePieceRight() {
            if (!currentPiece) return;
            currentPiece.x++;
            if (collision(currentPiece)) {
                currentPiece.x--;
            }
        }

        function rotatePiece() {
            if (!currentPiece) return;
            const shape = currentPiece.shape;
            const rows = shape.length;
            const cols = shape[0].length;
            const newShape = [];
            for (let i = 0; i < cols; i++) {
                newShape[i] = [];
                for (let j = rows - 1; j >= 0; j--) {
                    newShape[i][rows - 1 - j] = shape[j][i];
                }
            }

            const originalX = currentPiece.x;
            const originalY = currentPiece.y;
            currentPiece.shape = newShape;

            // 旋转后可能会发生碰撞,需要进行调整
            while (collision(currentPiece)) {
                currentPiece.x--; // 尝试向左移动
                if (collision(currentPiece)) {
                    currentPiece.x = originalX; // 如果向左移动也不行,尝试向右移动
                    currentPiece.y--; // 尝试向上移动
                    if (collision(currentPiece)) {
                        currentPiece.y = originalY; // 如果向上移动也不行,恢复原始位置和形状
                        currentPiece.shape = shape;
                        return;
                    }
                }
            }
        }

        function clearLines() {
            let linesCleared = 0;
            for (let y = gridRows - 1; y >= 0; y--) {
                if (grid[y].every(value => value !== 0)) {
                    linesCleared++;
                    for (let i = y; i > 0; i--) {
                        grid[i] = [...grid[i - 1]];
                    }
                    grid[0].fill(0);
                    if (lineClearSound) {
                        lineClearSound.play();
                    }
                    y++; // 重新检查当前行
                }
            }
            if (linesCleared > 0) {
                // 可以添加得分逻辑,这里省略
            }
        }

        function gameLoop() {
            if (!isGameOver) {
                movePieceDown();
                draw();
                setTimeout(gameLoop, gameSpeed);
            }
        }

        function gameOver() {
            isGameOver = true;
            clearInterval(gameInterval);
            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
            ctx.fillRect(0, canvas.height / 4, canvas.width, canvas.height / 2);
            ctx.fillStyle = 'white';
            ctx.font = '24px sans-serif';
            ctx.textAlign = 'center';
            ctx.fillText('游戏结束!', canvas.width / 2, canvas.height / 2);
            startButton.style.display = 'block';
        }

        function startGame() {
            initGrid();
            currentPiece = createNewPiece();
            isGameOver = false;
            gameSpeed = 500; // 重置速度
            startButton.style.display = 'none';
            if (startGameSound) {
                startGameSound.play();
            }
            gameLoop();
        }

        document.addEventListener('keydown', (e) => {
            if (!currentPiece || isGameOver) return;
            if (e.key === 'ArrowLeft') {
                movePieceLeft();
                draw();
            } else if (e.key === 'ArrowRight') {
                movePieceRight();
                draw();
            } else if (e.key === 'ArrowDown') {
                movePieceDown();
                draw();
                // 可以适当加快下落速度,但为了儿童体验,这里保持不变
            } else if (e.key === 'ArrowUp') {
                rotatePiece();
                draw();
            }
        });

        startButton.addEventListener('click', startGame);

        // 预加载音效 (可选)
        if (startGameSound) {
            startGameSound.load();
        }
        if (lineClearSound) {
            lineClearSound.load();
        }

        // 初始绘制一个空网格
        initGrid();
        drawGrid();
    </script>
</body>
</html>
http://www.dtcms.com/a/108492.html

相关文章:

  • 美团民宿 mtgsig 小程序 mtgsig1.2 分析
  • Unity中的C#脚本中文字符无法正常显示问题
  • mysql-创建和删除索引的两种方式
  • 针对 MySQL 数据库中 主键/唯一约束的更新方法 和 ON DUPLICATE KEY UPDATE 语法的详细说明及示例,并以表格总结
  • YOLOv11区域检测
  • Element Plus 常用组件
  • 超越人工智能驱动的网络攻击:现代防御者的策略
  • 电子电气架构 --- 智能座舱域控设计
  • Flutter 音视频播放器与弹幕系统开发实践
  • RK3588使用笔记:USB转232、485、422模块驱动适配
  • [蓝桥杯 2024 省 A] 训练士兵
  • 虚拟试衣间-云尚衣橱小程序-衣橱管理实现
  • 算法:二进制求和
  • 从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.3.3低代码开发:快速构建行业应用(电商推荐与金融风控案例)
  • Python 驱动周立功200U收发报文
  • 国产系统服务器识别不到SATA盘
  • STM32学习笔记之RCC模块(实操篇)
  • 横扫SQL面试——中位数问题
  • git tag
  • Linux 中CIFS和NFS使用说明
  • MCP学习总结
  • 基于RapidIO接口的DSP+GPU工业AI实时计算解决方案
  • ‘conda‘ 不是内部或外部命令,也不是可运行的程序或批处理文件
  • 【YOLOv8】YOLOv8改进系列(12)----替换主干网络之StarNet
  • 系统安全——文件监控-FileMonitor
  • 数据在内存中存储(C语言)
  • 杂篇-行业分类一二-2(通、专用设备制造,汽车制造)
  • (done) MIT6.824 Lecture 02 - RPC and Threads
  • stm32:sg90 和 mg90s舵机学习
  • Python----计算机视觉处理(Opencv:道路检测之提取车道线)