说到 海底捞鱼,第一反应就是:拿着网,一边捕鱼一边小心别捞到炸弹。 以前要自己写这样的小游戏,得设计 渔网移动逻辑、鱼群生成、炸弹判定、得分系统,还得调 UI 和动画。
现在有了 Trae IDE,一句话,一个“能玩的、好玩的”捕鱼游戏就出现了。
💡 我想要的玩法
脑子里画的场景很简单:
- 玩家能移动渔网:左右移动,按下就能下网捕捞;各种鱼随机游动:小鱼大鱼都有,速度也不一样;海里混着炸弹:要小心,捞到就扣分或者直接 Game Over;难度递增:随着时间,鱼游得更快,炸弹也更多;画面要轻松可爱:像卡通风格的海底世界。
于是我只输入了一句话:
“生成一个海底捞鱼游戏,玩家控制渔网捕捞海里的鱼,避免捕捞到炸弹。”
✨ Trae 是怎么“秒变游戏”的
没几秒钟,Trae 就交付了一个 完整的海底捞鱼:
✅ 渔网控制顺滑:左右键/滑动屏幕都能操作,按键就能下网;✅ 鱼群随机出现:不同大小、颜色的鱼,不停从屏幕游过;✅ 炸弹混在其中:看起来无害,但一旦被捞到,直接爆炸;✅ 计分系统完善:捕到鱼得分,捞到炸弹扣命,界面上实时显示分数;✅ 渐进式难度:随着时间,鱼游得更快,炸弹更频繁,游戏越来越紧张。
🧩 试玩体验
第一次玩就上瘾:
🐟 开局很轻松,随便下网就能捞到鱼;💣 突然一个炸弹混进来,我眼疾手快地收网,差点炸了;🔥 难度上来后,鱼群乱窜、炸弹乱飞,手忙脚乱的那种紧张感超刺激。
Trae 自动生成的版本,不光是能玩,还很有“街机游戏”的感觉,让人忍不住一局接一局。
🛠 想增加花样?一句话就能实现
Trae 的乐趣在于 说一句就能加玩法,比如:
- “加稀有金鱼,捞到得分翻倍” → 给玩家一个小惊喜;“加入时间模式,60 秒内拼分数” → 短局游戏更刺激;“加上技能,比如护盾网或磁力网” → 游戏策略性更强;“让海底有宝箱,偶尔掉落道具” → 增加随机奖励,玩起来更爽。
不用手写复杂逻辑,Trae 自动补好代码和动画。
🎮 过去 vs 现在
过去写捕鱼游戏:
- 设计 鱼的运动轨迹;调 炸弹判定逻辑;写 渔网操作和计分系统;搞 难度递增机制。
费时、麻烦,还容易出 bug。
现在用 Trae:👉 一句话 → 核心玩法秒完成;👉 想扩展 → 直接说,立刻补逻辑。
✅ 结语
如果你也想做一个 “捕鱼+炸弹+反应力” 的小游戏,打开 Trae,只要输入:
“生成一个海底捞鱼游戏,玩家控制渔网捕捞海里的鱼,避免捕捞到炸弹。”
几秒后,你就能玩到一个 轻松又刺激的海底世界:鱼游得欢快,炸弹随时威胁,分数越刷越想破纪录。
这就是 Trae 的魅力 —— 一句话,把你的创意变成一个真能玩的游戏。
<!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> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Arial', sans-serif; background-color: #87CEEB; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; } .game-container { position: relative; width: 800px; height: 600px; background: linear-gradient(to bottom, #1E90FF, #000080); border-radius: 10px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); overflow: hidden; } .score-container { position: absolute; top: 20px; left: 20px; background-color: rgba(255, 255, 255, 0.7); padding: 10px 15px; border-radius: 5px; font-size: 18px; font-weight: bold; color: #333; z-index: 10; } .time-container { position: absolute; top: 20px; right: 20px; background-color: rgba(255, 255, 255, 0.7); padding: 10px 15px; border-radius: 5px; font-size: 18px; font-weight: bold; color: #333; z-index: 10; } .net { position: absolute; width: 80px; height: 80px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="45" fill="none" stroke="white" stroke-width="2"/><line x1="5" y1="50" x2="95" y2="50" stroke="white" stroke-width="2"/><line x1="50" y1="5" x2="50" y2="95" stroke="white" stroke-width="2"/><line x1="15" y1="15" x2="85" y2="85" stroke="white" stroke-width="2"/><line x1="15" y1="85" x2="85" y2="15" stroke="white" stroke-width="2"/></svg>'); background-size: cover; cursor: pointer; z-index: 5; transform-origin: center bottom; } .fish { position: absolute; width: 50px; height: 30px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 60"><path d="M20,30 Q40,10 70,30 Q40,50 20,30 Z" fill="orange" stroke="black" stroke-width="2"/><circle cx="25" cy="25" r="3" fill="black"/><path d="M70,30 L90,15 L90,45 Z" fill="orange" stroke="black" stroke-width="2"/></svg>'); background-size: cover; z-index: 3; } .fish-gold { background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 60"><path d="M20,30 Q40,10 70,30 Q40,50 20,30 Z" fill="gold" stroke="black" stroke-width="2"/><circle cx="25" cy="25" r="3" fill="black"/><path d="M70,30 L90,15 L90,45 Z" fill="gold" stroke="black" stroke-width="2"/></svg>'); } .fish-blue { background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 60"><path d="M20,30 Q40,10 70,30 Q40,50 20,30 Z" fill="lightblue" stroke="black" stroke-width="2"/><circle cx="25" cy="25" r="3" fill="black"/><path d="M70,30 L90,15 L90,45 Z" fill="lightblue" stroke="black" stroke-width="2"/></svg>'); } .bomb { position: absolute; width: 40px; height: 40px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="60" r="35" fill="black" stroke="gray" stroke-width="2"/><rect x="45" y="10" width="10" height="20" fill="gray"/><path d="M45,10 Q50,0 55,10" fill="none" stroke="red" stroke-width="3"/></svg>'); background-size: cover; z-index: 3; } .bubble { position: absolute; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); z-index: 2; } .seaweed { position: absolute; bottom: 0; width: 30px; height: 100px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 200"><path d="M30,200 Q10,150 30,100 Q50,50 30,0" fill="none" stroke="green" stroke-width="5"/></svg>'); background-size: cover; z-index: 1; } .game-over { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 20; display: none; } .game-over-title { font-size: 48px; font-weight: bold; color: white; margin-bottom: 20px; text-align: center; } .final-score { font-size: 36px; color: white; margin-bottom: 30px; text-align: center; } .restart-button { padding: 15px 30px; font-size: 20px; font-weight: bold; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; transition: all 0.3s; } .restart-button:hover { background-color: #45a049; transform: scale(1.05); } .start-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 20; } .start-screen-title { font-size: 48px; font-weight: bold; color: white; margin-bottom: 20px; text-align: center; } .start-screen-subtitle { font-size: 24px; color: white; margin-bottom: 30px; text-align: center; max-width: 80%; line-height: 1.4; } .start-button { padding: 15px 30px; font-size: 20px; font-weight: bold; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; transition: all 0.3s; } .start-button:hover { background-color: #45a049; transform: scale(1.05); } .catch-animation { animation: catch 0.5s ease-out; } @keyframes catch { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(0); opacity: 0; } } .explosion { position: absolute; width: 100px; height: 100px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="orange"/><circle cx="50" cy="50" r="30" fill="yellow"/><path d="M50,10 L55,25 L70,15 L60,30 L80,35 L60,45 L75,60 L55,55 L60,80 L45,65 L30,85 L35,65 L10,70 L30,55 L15,40 L35,45 L25,25 L45,35 Z" fill="red"/></svg>'); background-size: cover; z-index: 6; animation: explode 0.5s ease-out forwards; } @keyframes explode { 0% { transform: scale(0); opacity: 1; } 50% { transform: scale(1.5); opacity: 1; } 100% { transform: scale(2); opacity: 0; } } </style></head><body> <div class="game-container" id="game-container"> <div class="score-container"> 分数: <span id="score">0</span> </div> <div class="time-container"> 时间: <span id="time">60</span>秒 </div> <div class="net" id="net"></div> <div class="game-over" id="game-over"> <div class="game-over-title">游戏结束</div> <div class="final-score">最终得分: <span id="final-score">0</span></div> <button class="restart-button" id="restart-button">再玩一次</button> </div> <div class="start-screen" id="start-screen"> <div class="start-screen-title">海底捞鱼</div> <div class="start-screen-subtitle">用鼠标控制渔网捕捞海里的鱼,获得分数。金色鱼可获得更多分数!小心炸弹,碰到炸弹会扣分!</div> <button class="start-button" id="start-button">开始游戏</button> </div> </div> <script> // 游戏元素 const gameContainer = document.getElementById('game-container'); const net = document.getElementById('net'); const scoreElement = document.getElementById('score'); const timeElement = document.getElementById('time'); const gameOver = document.getElementById('game-over'); const finalScore = document.getElementById('final-score'); const restartButton = document.getElementById('restart-button'); const startScreen = document.getElementById('start-screen'); const startButton = document.getElementById('start-button'); // 游戏配置 const containerWidth = gameContainer.offsetWidth; const containerHeight = gameContainer.offsetHeight; const netWidth = 80; const netHeight = 80; const fishGenerationInterval = 1000; // 毫秒 const bombGenerationInterval = 3000; // 毫秒 const gameTime = 60; // 秒 // 游戏状态 let score = 0; let timeLeft = gameTime; let fishes = []; let bombs = []; let bubbles = []; let gameRunning = false; let gameLoop; let fishInterval; let bombInterval; let timeInterval; // 初始化游戏 function initGame() { // 隐藏开始屏幕 startScreen.style.display = 'none'; // 重置游戏状态 score = 0; timeLeft = gameTime; fishes = []; bombs = []; bubbles = []; // 清除所有元素 const existingElements = document.querySelectorAll('.fish, .bomb, .bubble, .seaweed, .explosion'); existingElements.forEach(element => element.remove()); // 更新显示 scoreElement.textContent = score; timeElement.textContent = timeLeft; // 创建海草背景 createSeaweed(); // 创建气泡 createBubbles(); // 开始游戏循环 gameRunning = true; gameLoop = setInterval(updateGame, 16); // 约60帧每秒 // 开始生成鱼 fishInterval = setInterval(generateFish, fishGenerationInterval); // 开始生成炸弹 bombInterval = setInterval(generateBomb, bombGenerationInterval); // 开始倒计时 timeInterval = setInterval(() => { if (gameRunning) { timeLeft--; timeElement.textContent = timeLeft; if (timeLeft <= 0) { endGame(); } } }, 1000); // 设置渔网初始位置 net.style.left = `${containerWidth / 2 - netWidth / 2}px`; net.style.top = `${containerHeight / 2 - netHeight / 2}px`; } // 创建海草背景 function createSeaweed() { for (let i = 0; i < 8; i++) { const seaweed = document.createElement('div'); seaweed.className = 'seaweed'; const x = Math.random() * containerWidth; const height = 100 + Math.random() * 100; seaweed.style.left = `${x}px`; seaweed.style.height = `${height}px`; gameContainer.appendChild(seaweed); } } // 创建气泡 function createBubbles() { for (let i = 0; i < 20; i++) { generateBubble(); } // 定期生成新气泡 setInterval(() => { if (gameRunning && bubbles.length < 30) { generateBubble(); } }, 1000); } // 生成单个气泡 function generateBubble() { const bubble = document.createElement('div'); bubble.className = 'bubble'; const size = 5 + Math.random() * 20; const x = Math.random() * containerWidth; const y = containerHeight; const speed = 1 + Math.random() * 2; bubble.style.width = `${size}px`; bubble.style.height = `${size}px`; bubble.style.left = `${x}px`; bubble.style.bottom = `0px`; gameContainer.appendChild(bubble); bubbles.push({ element: bubble, x: x, y: 0, speed: speed }); } // 生成鱼 function generateFish() { if (!gameRunning) return; const fish = document.createElement('div'); fish.className = 'fish'; // 随机鱼的类型 const fishType = Math.random(); if (fishType < 0.2) { fish.classList.add('fish-gold'); } else if (fishType < 0.5) { fish.classList.add('fish-blue'); } const fishWidth = 50; const fishHeight = 30; // 随机鱼的位置和方向 const fromRight = Math.random() > 0.5; const x = fromRight ? containerWidth : -fishWidth; const y = 50 + Math.random() * (containerHeight - 150); const speed = 1 + Math.random() * 3; fish.style.left = `${x}px`; fish.style.top = `${y}px`; // 设置鱼的方向 if (fromRight) { fish.style.transform = 'scaleX(-1)'; } gameContainer.appendChild(fish); fishes.push({ element: fish, x: x, y: y, width: fishWidth, height: fishHeight, speed: speed, fromRight: fromRight, type: fishType < 0.2 ? 'gold' : (fishType < 0.5 ? 'blue' : 'normal'), caught: false }); } // 生成炸弹 function generateBomb() { if (!gameRunning) return; const bomb = document.createElement('div'); bomb.className = 'bomb'; const bombWidth = 40; const bombHeight = 40; // 随机炸弹的位置 const x = Math.random() * (containerWidth - bombWidth); const y = -bombHeight; const speed = 1 + Math.random() * 2; bomb.style.left = `${x}px`; bomb.style.top = `${y}px`; gameContainer.appendChild(bomb); bombs.push({ element: bomb, x: x, y: y, width: bombWidth, height: bombHeight, speed: speed, exploded: false }); } // 更新游戏状态 function updateGame() { if (!gameRunning) return; // 更新鱼的位置 fishes.forEach((fish, index) => { if (!fish.caught) { if (fish.fromRight) { fish.x -= fish.speed; } else { fish.x += fish.speed; } fish.element.style.left = `${fish.x}px`; // 检查是否超出屏幕 if ((fish.fromRight && fish.x + fish.width < 0) || (!fish.fromRight && fish.x > containerWidth)) { fish.element.remove(); fishes.splice(index, 1); } } }); // 更新炸弹的位置 bombs.forEach((bomb, index) => { if (!bomb.exploded) { bomb.y += bomb.speed; bomb.element.style.top = `${bomb.y}px`; // 检查是否超出屏幕 if (bomb.y > containerHeight) { bomb.element.remove(); bombs.splice(index, 1); } } }); // 更新气泡的位置 bubbles.forEach((bubble, index) => { bubble.y += bubble.speed; bubble.element.style.bottom = `${bubble.y}px`; // 检查是否超出屏幕 if (bubble.y > containerHeight) { bubble.element.remove(); bubbles.splice(index, 1); } }); } // 检查碰撞 function checkCollision(net, object) { const netRect = net.getBoundingClientRect(); const objectRect = object.element.getBoundingClientRect(); return !(netRect.right < objectRect.left || netRect.left > objectRect.right || netRect.bottom < objectRect.top || netRect.top > objectRect.bottom); } // 捕获鱼 function catchFish(fish) { if (fish.caught) return; fish.caught = true; fish.element.classList.add('catch-animation'); // 根据鱼的类型增加分数 let points = 10; if (fish.type === 'gold') { points = 50; } else if (fish.type === 'blue') { points = 20; } score += points; scoreElement.textContent = score; // 移除鱼 setTimeout(() => { fish.element.remove(); const index = fishes.indexOf(fish); if (index > -1) { fishes.splice(index, 1); } }, 500); } // 炸弹爆炸 function explodeBomb(bomb) { if (bomb.exploded) return; bomb.exploded = true; // 创建爆炸效果 const explosion = document.createElement('div'); explosion.className = 'explosion'; explosion.style.left = `${bomb.x - 30}px`; explosion.style.top = `${bomb.y - 30}px`; gameContainer.appendChild(explosion); // 扣分 score = Math.max(0, score - 30); scoreElement.textContent = score; // 移除炸弹和爆炸效果 setTimeout(() => { bomb.element.remove(); explosion.remove(); const index = bombs.indexOf(bomb); if (index > -1) { bombs.splice(index, 1); } }, 500); } // 结束游戏 function endGame() { gameRunning = false; clearInterval(gameLoop); clearInterval(fishInterval); clearInterval(bombInterval); clearInterval(timeInterval); // 显示游戏结束界面 gameOver.style.display = 'flex'; document.getElementById('final-score').textContent = score; } // 鼠标控制渔网 gameContainer.addEventListener('mousemove', (e) => { if (!gameRunning) return; const rect = gameContainer.getBoundingClientRect(); const x = e.clientX - rect.left - netWidth / 2; const y = e.clientY - rect.top - netHeight / 2; // 限制渔网在游戏区域内 const boundedX = Math.max(0, Math.min(containerWidth - netWidth, x)); const boundedY = Math.max(0, Math.min(containerHeight - netHeight, y)); net.style.left = `${boundedX}px`; net.style.top = `${boundedY}px`; // 检查是否捕获鱼 fishes.forEach(fish => { if (!fish.caught && checkCollision(net, fish)) { catchFish(fish); } }); // 检查是否碰到炸弹 bombs.forEach(bomb => { if (!bomb.exploded && checkCollision(net, bomb)) { explodeBomb(bomb); } }); }); // 触摸控制(移动设备) gameContainer.addEventListener('touchmove', (e) => { if (!gameRunning) return; e.preventDefault(); const rect = gameContainer.getBoundingClientRect(); const touch = e.touches[0]; const x = touch.clientX - rect.left - netWidth / 2; const y = touch.clientY - rect.top - netHeight / 2; // 限制渔网在游戏区域内 const boundedX = Math.max(0, Math.min(containerWidth - netWidth, x)); const boundedY = Math.max(0, Math.min(containerHeight - netHeight, y)); net.style.left = `${boundedX}px`; net.style.top = `${boundedY}px`; // 检查是否捕获鱼 fishes.forEach(fish => { if (!fish.caught && checkCollision(net, fish)) { catchFish(fish); } }); // 检查是否碰到炸弹 bombs.forEach(bomb => { if (!bomb.exploded && checkCollision(net, bomb)) { explodeBomb(bomb); } }); }, { passive: false }); // 事件监听 restartButton.addEventListener('click', () => { gameOver.style.display = 'none'; initGame(); }); startButton.addEventListener('click', () => { initGame(); }); </script></body></html>
