纯前端小游戏Demo制作

Prompt分享:

P: 作为一名专为5-8岁儿童设计游戏的资深前端开发者。 

T: 请帮我创建一个“图片单词配对”的网页小游戏。 

C: 游戏的目标是帮助小学一年级学生学习10个关于水果的英文单词(Apple, Banana, Orange, Grape, Strawberry, Watermelon, Peach, Pear, Mango, Lemon)。游戏界面需要展示10张水果图片和10个单词卡片,学生需要将正确的单词拖拽到对应的图片上。拖拽正确时,卡片会吸附到图片旁并有绿色提示;错误则弹回原位并有红色提示。

 F: 请将所有的HTML、CSS和JavaScript代码生成在一个单一的HTML文件中,确保代码结构清晰并有中文注释。

生成结果:

然后就可以玩了! AI 2分钟以内就做好了

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>水果单词大挑战 - 趣味英语配对</title>
    <style>
        /* 1. 基础样式与背景 */
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f0fdf4; /* 清新的浅绿色背景 */
            margin: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
            user-select: none; /* 禁止选中文本,让拖拽更流畅 */
        }

        h1 {
            color: #16a34a;
            margin-top: 20px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
        }

        .instruction {
            color: #666;
            margin-bottom: 20px;
        }

        /* 2. 游戏主容器布局 */
        .game-container {
            display: flex;
            flex-direction: column;
            gap: 30px;
            width: 90%;
            max-width: 1000px;
            background: white;
            padding: 30px;
            border-radius: 20px;
            box-shadow: 0 10px 25px rgba(0,0,0,0.1);
        }

        /* 水果图片区域:使用网格布局 */
        .images-grid {
            display: grid;
            grid-template-columns: repeat(5, 1fr);
            gap: 15px;
        }

        /* 单个图片插槽 */
        .image-slot {
            aspect-ratio: 1;
            border: 3px dashed #cbd5e1;
            border-radius: 15px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            position: relative;
            background: #f8fafc;
            transition: all 0.3s ease;
        }

        /* 正在拖拽目标悬停时的效果 */
        .image-slot.drag-over {
            background: #dcfce7;
            border-color: #22c55e;
            transform: scale(1.02);
        }

        .fruit-emoji {
            font-size: 60px; /* 大图标方便孩子识别 */
            margin-bottom: 5px;
        }

        /* 单词卡片区域 */
        .words-container {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 12px;
            padding: 20px;
            border-top: 2px solid #f1f5f9;
        }

        /* 单词卡片样式 */
        .word-card {
            padding: 12px 24px;
            background-color: #ffffff;
            border: 2px solid #3b82f6;
            color: #1d4ed8;
            border-radius: 50px; /* 圆润的外观更亲切 */
            font-size: 20px;
            font-weight: bold;
            cursor: grab;
            box-shadow: 0 4px 6px rgba(0,0,0,0.05);
            transition: transform 0.2s, background-color 0.2s;
        }

        .word-card:active {
            cursor: grabbing;
        }

        /* 正确与错误的视觉反馈 */
        .correct {
            background-color: #22c55e !important;
            color: white !important;
            border-color: #16a34a !important;
            cursor: default;
        }

        .wrong {
            animation: shake 0.5s linear;
            border-color: #ef4444 !important;
            background-color: #fee2e2 !important;
        }

        /* 抖动动画 */
        @keyframes shake {
            0%, 100% { transform: translateX(0); }
            25% { transform: translateX(-5px); }
            50% { transform: translateX(5px); }
            75% { transform: translateX(-5px); }
        }

        /* 胜利庆祝弹窗 */
        #win-message {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 40px;
            border-radius: 20px;
            box-shadow: 0 0 100px rgba(0,0,0,0.3);
            text-align: center;
            z-index: 100;
        }

        button {
            background: #22c55e;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 10px;
            font-size: 18px;
            cursor: pointer;
            margin-top: 15px;
        }
    </style>
</head>
<body>

    <h1>🍎 水果英语大闯关 🍌</h1>
    <p class="instruction">把下方的英语单词拖拽到对应的水果图片上吧!</p>

    <div class="game-container">
        <!-- 水果图片展示区 -->
        <div class="images-grid" id="imagesGrid">
            <!-- 由 JS 动态生成 -->
        </div>

        <!-- 待选单词区 -->
        <div class="words-container" id="wordsContainer">
            <!-- 由 JS 动态生成 -->
        </div>
    </div>

    <!-- 胜利提示 -->
    <div id="win-message">
        <h2 style="font-size: 40px;">太棒了!🌟</h2>
        <p>你认识了所有的水果单词!</p>
        <button onclick="location.reload()">再玩一次</button>
    </div>

    <script>
        // 1. 数据配置
        const fruits = [
            { id: 'apple', name: 'Apple', emoji: '🍎' },
            { id: 'banana', name: 'Banana', emoji: '🍌' },
            { id: 'orange', name: 'Orange', emoji: '🍊' },
            { id: 'grape', name: 'Grape', emoji: '🍇' },
            { id: 'strawberry', name: 'Strawberry', emoji: '🍓' },
            { id: 'watermelon', name: 'Watermelon', emoji: '🍉' },
            { id: 'peach', name: 'Peach', emoji: '🍑' },
            { id: 'pear', name: 'Pear', emoji: '🍐' },
            { id: 'mango', name: 'Mango', emoji: '🥭' },
            { id: 'lemon', name: 'Lemon', emoji: '🍋' }
        ];

        let matchedCount = 0;

        // 2. 初始化游戏
        function initGame() {
            const imagesGrid = document.getElementById('imagesGrid');
            const wordsContainer = document.getElementById('wordsContainer');

            // 打乱水果顺序(为了增加重复玩的乐趣)
            const shuffledFruits = [...fruits].sort(() => Math.random() - 0.5);
            const shuffledWords = [...fruits].sort(() => Math.random() - 0.5);

            // 生成图片槽
            shuffledFruits.forEach(fruit => {
                const slot = document.createElement('div');
                slot.className = 'image-slot';
                slot.dataset.id = fruit.id;
                slot.innerHTML = `<span class="fruit-emoji">${fruit.emoji}</span>`;
                
                // 绑定拖放事件
                slot.ondragover = e => e.preventDefault();
                slot.ondragenter = () => slot.classList.add('drag-over');
                slot.ondragleave = () => slot.classList.remove('drag-over');
                slot.ondrop = handleDrop;
                
                imagesGrid.appendChild(slot);
            });

            // 生成单词卡片
            shuffledWords.forEach(fruit => {
                const card = document.createElement('div');
                card.className = 'word-card';
                card.draggable = true;
                card.innerText = fruit.name;
                card.id = `card-${fruit.id}`;
                card.dataset.id = fruit.id;
                
                card.ondragstart = e => {
                    e.dataTransfer.setData('text/plain', fruit.id);
                    card.classList.add('dragging');
                };
                
                wordsContainer.appendChild(card);
            });
        }

        // 3. 处理拖放逻辑
        function handleDrop(e) {
            e.preventDefault();
            const slot = e.currentTarget;
            slot.classList.remove('drag-over');
            
            const draggedId = e.dataTransfer.getData('text/plain');
            const targetId = slot.dataset.id;
            const draggedElement = document.getElementById(`card-${draggedId}`);

            // 如果该位置已经配对成功,则不处理
            if (slot.querySelector('.correct')) return;

            if (draggedId === targetId) {
                // 配对正确
                draggedElement.draggable = false;
                draggedElement.classList.add('correct');
                slot.appendChild(draggedElement); // 吸附到图片下方
                
                matchedCount++;
                checkWin();
            } else {
                // 配对错误:显示红色提示并抖动
                draggedElement.classList.add('wrong');
                setTimeout(() => {
                    draggedElement.classList.remove('wrong');
                }, 500);
            }
        }

        // 4. 检查是否全对
        function checkWin() {
            if (matchedCount === fruits.length) {
                setTimeout(() => {
                    document.getElementById('win-message').style.display = 'block';
                }, 500);
            }
        }

        // 启动游戏
        initGame();
    </script>
</body>
</html>

#Prompt分享#
全部评论
牛客太高效了,可以点这里试玩:https://static.nowcoder.com/activity/2025christmas/wordgame.html
点赞 回复 分享
发布于 01-30 13:57 北京

相关推荐

1.&nbsp;自我介绍2.&nbsp;项目都是自己写的吗?3.&nbsp;我看你用&nbsp;koa2&nbsp;写后端,为什么选择它,能讲讲吗?4.&nbsp;那你提到&nbsp;koa2&nbsp;它是不提供中间件的,你是怎么解决的?5.&nbsp;中间件的原理是什么?(洋葱模型)6.&nbsp;你刚刚说碰到&nbsp;next()&nbsp;就进入下一个中间件,那&nbsp;next&nbsp;只能执行同步,如果是异步的话,你是怎么处理的?(async/await,但是我发现,有的中间件需要在异步中间件之前执行,所以我用&nbsp;try/catch&nbsp;来处理异步中间件的异常)7.&nbsp;JS&nbsp;异步发展史,以及它们的优缺点说一下&nbsp;(回调函数--Promise--Generator--async/await)8.&nbsp;你刚刚说&nbsp;Promise&nbsp;状态不能更改,那如果我要设计一个能修改&nbsp;Promise&nbsp;状态的函数,你会怎么设计?9.&nbsp;CSS&nbsp;水平垂直居中的方法(flex、grid、绝对定位&nbsp;+&nbsp;margin:auto、绝对定位&nbsp;+&nbsp;负&nbsp;margin、绝对定位&nbsp;+&nbsp;transform、table-cell)10.&nbsp;你刚刚说到&nbsp;flex&nbsp;布局,那&nbsp;flex:1&nbsp;是什么意思?(flex:&nbsp;flex-grow&nbsp;&nbsp;flex-shrink&nbsp;&nbsp;flex-basis;等价&nbsp;flex:1&nbsp;1&nbsp;0%表示元素可以均分剩余空间,可拉伸、可压缩,不依赖内容宽度,自动自适应填充布局。)11.&nbsp;父容器宽是&nbsp;500px,然后它左右各有两个子容器是&nbsp;100px,如果设置&nbsp;flex:&nbsp;1,那它的宽度是多少?(500-100-100=300px)12.&nbsp;说说你对浏览器缓存的理解(强缓存、协商缓存)13.&nbsp;如果一个用户,他怎么去刷新都无法刷到最新版的代码,你能说下可能的原因吗?(版本号、hash等)还有吗?(我说我不知道了,面试官说还有&nbsp;CDN&nbsp;没有同步,我说企业才会这么干,自己写项目一般不会,我知道&nbsp;cdn&nbsp;是用来解决高并发的手段)14.&nbsp;React你熟吗?说下&nbsp;React&nbsp;函数组件和类组件的区别15.&nbsp;怎么避免&nbsp;Hooks&nbsp;导致组件重新渲染?(使用&nbsp;useCallback、useMemo、React.memo、useRef等等)16.&nbsp;谈一下我对&nbsp;React&nbsp;的状态管理的理解(Redux、Mobx、Zustand,我说&nbsp;Zustand&nbsp;用的最多)17.&nbsp;React&nbsp;常见的&nbsp;hooks&nbsp;有哪些?(useState、useEffect、useRef、useCallback、useMemo、useReducer、useContext、useImperativeHandle、useLayoutEffect、useDebugValue)18.&nbsp;TS&nbsp;你熟吗?我们引进&nbsp;TS&nbsp;的目的是为什么?19.&nbsp;interface&nbsp;和&nbsp;type&nbsp;的区别20.&nbsp;说下&nbsp;TS&nbsp;里的泛型21.&nbsp;我现在有十个字段,比如十个字段就要&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;G&nbsp;这种。那我现在另有另外一个方法,这个方法接受的参数呢,必须是这个&nbsp;interface&nbsp;A&nbsp;里面的这个&nbsp;K。就比如说你可以是&nbsp;A&nbsp;B&nbsp;C&nbsp;可以&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;任何组合都可以,但是必须是这个&nbsp;interface&nbsp;里面的&nbsp;A&nbsp;里面的定义的。这个&nbsp;K&nbsp;这种类型的话是怎么去定义呢?(说实话我有点不太理解啥意思,反正我说了&nbsp;keyof)```&nbsp;TypeScriptinterface&nbsp;Obj&nbsp;{A:&nbsp;stringB:&nbsp;stringC:&nbsp;stringD:&nbsp;stringE:&nbsp;string//&nbsp;其他字段...}```22.&nbsp;vite&nbsp;用过吗?说说和&nbsp;webpack&nbsp;的区别。vite&nbsp;的优缺点是什么23.&nbsp;说说&nbsp;Tree&nbsp;shaking(树摇)&nbsp;和&nbsp;Code&nbsp;Splitting&nbsp;(代码分割)的区别24.&nbsp;Git&nbsp;你熟吗?说说&nbsp;git&nbsp;merge&nbsp;和&nbsp;git&nbsp;rebase&nbsp;的区别,什么时候用&nbsp;git&nbsp;merge,什么时候用&nbsp;git&nbsp;rebase?25.&nbsp;web3&nbsp;你熟吗?(不太熟,听说过而已)26.&nbsp;我看你自我介绍说了&nbsp;AI,你是怎么用的?27.&nbsp;除了提示词,还有什么能让&nbsp;AI&nbsp;更聪明?28.&nbsp;AI&nbsp;的优缺点你说一下29.&nbsp;AI&nbsp;发展这么快,你觉得我们以后会扮演什么角色?30.&nbsp;反问基本都答上来了。面了我80分钟,我还以为稳过的
查看29道真题和解析
点赞 评论 收藏
分享
评论
13
8
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务