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

网页小游戏

一、反应速度挑战游戏

代码:

<!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 { background: #0f0f1a; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: 'Segoe UI', system-ui, sans-serif; user-select: none; overflow: hidden; } .game-container { position: relative; width: 700px; height: 500px; background: #1a1a2e; border-radius: 20px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); display: flex; flex-direction: column; align-items: center; justify-content: center; } .header { position: absolute; top: 20px; width: 100%; display: flex; justify-content: space-around; align-items: center; color: #e0e0e0; z-index: 10; } .stat { text-align: center; } .stat-label { font-size: 12px; text-transform: uppercase; letter-spacing: 2px; color: #888; } .stat-value { font-size: 32px; font-weight: bold; color: #ffcc00; } .timer-ring { position: relative; width: 60px; height: 60px; } .timer-ring svg { transform: rotate(-90deg); } .timer-ring .bg-circle { fill: none; stroke: #333; stroke-width: 6; } .timer-ring .fg-circle { fill: none; stroke: #ff4444; stroke-width: 6; stroke-linecap: round; transition: stroke-dashoffset 0.1s linear; } .timer-ring .time-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 18px; font-weight: bold; color: white; } .play-area { position: relative; width: 100%; height: 340px; margin-top: 80px; cursor: crosshair; } .target { position: absolute; border-radius: 50%; cursor: pointer; animation: popIn 0.15s ease-out; box-shadow: 0 0 20px rgba(255, 255, 255, 0.4); transition: transform 0.05s; } .target:hover { transform: scale(1.1); } .target:active { transform: scale(0.85); } @keyframes popIn { 0% { transform: scale(0); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.85); display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 20px; z-index: 20; } .overlay.hidden { display: none; } .overlay h2 { font-size: 42px; color: #ffcc00; margin-bottom: 10px; } .overlay .final-score { font-size: 64px; font-weight: bold; color: white; } .overlay .detail { color: #aaa; margin: 10px 0 25px; } .btn { padding: 14px 40px; font-size: 18px; border: none; border-radius: 30px; cursor: pointer; font-weight: bold; letter-spacing: 1px; transition: all 0.2s; } .btn-start { background: #ffcc00; color: #1a1a2e; } .btn-start:hover { background: #ffe566; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(255, 204, 0, 0.4); } .btn-restart { background: #ff4444; color: white; } .btn-restart:hover { background: #ff6666; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(255, 68, 68, 0.4); } .combo-text { position: absolute; pointer-events: none; font-weight: bold; font-size: 24px; color: #ffcc00; animation: floatUp 0.8s ease-out forwards; } @keyframes floatUp { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-50px); } } </style> </head> <body> <div class="game-container" id="gameContainer"> <!-- 顶部信息栏 --> <div class="header"> <div class="stat"> <div class="stat-label">得分</div> <div class="stat-value" id="scoreDisplay">0</div> </div> <div class="timer-ring"> <svg width="60" height="60"> <circle class="bg-circle" cx="30" cy="30" r="26"/> <circle class="fg-circle" id="timerCircle" cx="30" cy="30" r="26" stroke-dasharray="163.36" stroke-dashoffset="0"/> </svg> <div class="time-text" id="timeText">30</div> </div> <div class="stat"> <div class="stat-label">连击</div> <div class="stat-value" id="comboDisplay">0</div> </div> </div> <!-- 游戏区域 --> <div class="play-area" id="playArea"></div> <!-- 开始遮罩 --> <div class="overlay" id="startOverlay"> <h2>⚡ 反应速度挑战</h2> <p style="color:#ccc; margin-bottom:20px;">点击出现的彩色圆点 · 越快分数越高</p> <button class="btn btn-start" id="btnStart">开始游戏</button> </div> <!-- 结束遮罩 --> <div class="overlay hidden" id="endOverlay"> <h2>⏱️ 时间到!</h2> <div class="final-score" id="finalScore">0</div> <div class="detail"> 命中 <span id="finalHits">0</span> 次 · 最高连击 <span id="finalCombo">0</span> </div> <button class="btn btn-restart" id="btnRestart">再来一局</button> </div> </div> <script> (function() { // ==================== DOM元素 ==================== const playArea = document.getElementById('playArea'); const scoreDisplay = document.getElementById('scoreDisplay'); const comboDisplay = document.getElementById('comboDisplay'); const timeText = document.getElementById('timeText'); const timerCircle = document.getElementById('timerCircle'); const startOverlay = document.getElementById('startOverlay'); const endOverlay = document.getElementById('endOverlay'); const finalScore = document.getElementById('finalScore'); const finalHits = document.getElementById('finalHits'); const finalCombo = document.getElementById('finalCombo'); const btnStart = document.getElementById('btnStart'); const btnRestart = document.getElementById('btnRestart'); // ==================== 游戏状态 ==================== const TOTAL_TIME = 30; // 总时长(秒) const CIRCLE_RADIUS = 163.36; // 圆形进度条总长度 let score = 0; let combo = 0; let maxCombo = 0; let hits = 0; let timeLeft = TOTAL_TIME; let gameActive = false; let timerInterval = null; let spawnTimeout = null; let currentTarget = null; let difficulty = 1; // 随剩余时间增加 // ==================== 音效(使用AudioContext,避免加载文件) ==================== let audioCtx = null; function getAudioContext() { if (!audioCtx) { audioCtx = new(window.AudioContext || window.webkitAudioContext)(); } return audioCtx; } function playBeep(freq, duration, type = 'sine') { try { const ctx = getAudioContext(); const osc = ctx.createOscillator(); const gain = ctx.createGain(); osc.type = type; osc.frequency.setValueAtTime(freq, ctx.currentTime); gain.gain.setValueAtTime(0.1, ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + duration); osc.connect(gain); gain.connect(ctx.destination); osc.start(); osc.stop(ctx.currentTime + duration); } catch (e) { // 静默处理 } } function playHitSound() { playBeep(800 + combo * 30, 0.1, 'square'); } function playMissSound() { playBeep(200, 0.15, 'sawtooth'); } // ==================== 生成目标 ==================== function spawnTarget() { if (!gameActive) return; // 清除旧目标 if (currentTarget && currentTarget.parentNode) { currentTarget.remove(); } // 难度影响:方块大小和停留时间 const minSize = Math.max(30, 70 - difficulty * 3); const maxSize = Math.max(45, 90 - difficulty * 3); const size = Math.floor(Math.random() * (maxSize - minSize + 1)) + minSize; const areaRect = playArea.getBoundingClientRect(); const maxX = areaRect.width - size; const maxY = areaRect.height - size; const x = Math.random() * maxX; const y = Math.random() * maxY; // 随机颜色 const hue = Math.random() * 360; const color = `hsl(${hue}, 80%, 60%)`; const target = document.createElement('div'); target.className = 'target'; target.style.width = size + 'px'; target.style.height = size + 'px'; target.style.left = x + 'px'; target.style.top = y + 'px'; target.style.backgroundColor = color; target.addEventListener('click', (e) => { e.stopPropagation(); if (!gameActive) return; hitTarget(target, x, y); }); playArea.appendChild(target); currentTarget = target; // 目标停留时间随难度降低 const stayTime = Math.max(600, 1800 - difficulty * 100); spawnTimeout = setTimeout(() => { if (currentTarget === target && gameActive) { missTarget(target); } }, stayTime); } // ==================== 命中目标 ==================== function hitTarget(target, x, y) { clearTimeout(spawnTimeout); hits++; combo++; if (combo > maxCombo) maxCombo = combo; // 计分:基础10分 + 连击奖励 const comboBonus = Math.min(combo - 1, 20) * 3; score += 10 + comboBonus; updateUI(); // 飘分特效 showComboText(x, y, comboBonus > 0 ? `+${10 + comboBonus}` : '+10'); // 音效 playHitSound(); // 移除目标并生成新目标 target.remove(); currentTarget = null; spawnTarget(); } // ==================== 未命中目标 ==================== function missTarget(target) { if (target && target.parentNode) { target.remove(); } combo = 0; updateUI(); playMissSound(); currentTarget = null; if (gameActive) spawnTarget(); } // ==================== 点击空白区域 ==================== playArea.addEventListener('click', (e) => { if (!gameActive) return; if (e.target === playArea) { // 点空了 combo = 0; updateUI(); playMissSound(); } }); // ==================== 飘字特效 ==================== function showComboText(x, y, text) { const el = document.createElement('div'); el.className = 'combo-text'; el.textContent = text; el.style.left = x + 'px'; el.style.top = y + 'px'; playArea.appendChild(el); setTimeout(() => el.remove(), 800); } // ==================== 更新UI ==================== function updateUI() { scoreDisplay.textContent = score; comboDisplay.textContent = combo; if (combo >= 5) { comboDisplay.style.color = '#ff6666'; } else if (combo >= 3) { comboDisplay.style.color = '#ffaa00'; } else { comboDisplay.style.color = '#ffcc00'; } } function updateTimer() { timeText.textContent = timeLeft; const offset = CIRCLE_RADIUS * (1 - timeLeft / TOTAL_TIME); timerCircle.style.strokeDashoffset = offset; // 时间快结束时变红 if (timeLeft <= 5) { timerCircle.style.stroke = '#ff0000'; timeText.style.color = '#ff4444'; } else { timerCircle.style.stroke = '#ff4444'; timeText.style.color = 'white'; } } // ==================== 游戏循环 ==================== function startGame() { // 重置状态 score = 0; combo = 0; maxCombo = 0; hits = 0; timeLeft = TOTAL_TIME; gameActive = true; difficulty = 1; updateUI(); updateTimer(); comboDisplay.style.color = '#ffcc00'; timerCircle.style.stroke = '#ff4444'; timeText.style.color = 'white'; startOverlay.classList.add('hidden'); endOverlay.classList.add('hidden'); // 启动计时器 timerInterval = setInterval(() => { timeLeft--; difficulty = Math.floor((TOTAL_TIME - timeLeft) / 5) + 1; // 每5秒升一级 updateTimer(); if (timeLeft <= 0) { endGame(); } }, 1000); // 生成第一个目标 spawnTarget(); } function endGame() { gameActive = false; clearInterval(timerInterval); clearTimeout(spawnTimeout); if (currentTarget && currentTarget.parentNode) { currentTarget.remove(); currentTarget = null; } // 显示结算画面 finalScore.textContent = score; finalHits.textContent = hits; finalCombo.textContent = maxCombo; endOverlay.classList.remove('hidden'); // 结算音效 playBeep(523, 0.1); setTimeout(() => playBeep(659, 0.1), 150); setTimeout(() => playBeep(784, 0.2), 300); } // ==================== 按钮事件 ==================== btnStart.addEventListener('click', startGame); btnRestart.addEventListener('click', startGame); // ==================== 键盘快捷键 ==================== document.addEventListener('keydown', (e) => { if (e.code === 'Space') { e.preventDefault(); if (!gameActive && (timeLeft === TOTAL_TIME || timeLeft <= 0)) { startGame(); } } }); })(); </script> </body> </html>
玩法说明:

1.目标:在 30 秒内尽可能多地点击随机出现的彩色圆点。

2.计分:每次命中 +10 分,连续命中会触发连击,连击越高额外加分越多。

3.难度:时间越靠后,圆点越小、消失越快,挑战你的反应极限。

4.操作:鼠标点击圆点得分,点空白处会断掉连击。

5.快捷键:游戏结束或开始前按空格键可直接开始。

二、记忆翻牌

代码:

<!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 { background: #1a1a2e; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: system-ui, sans-serif; } .container { background: #16213e; padding: 30px; border-radius: 20px; box-shadow: 0 20px 60px rgba(0,0,0,0.5); } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; color: white; } .stats { font-size: 18px; } .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } .card { width: 80px; height: 80px; perspective: 600px; cursor: pointer; } .card-inner { position: relative; width: 100%; height: 100%; transition: transform 0.4s; transform-style: preserve-3d; } .card.flipped .card-inner { transform: rotateY(180deg); } .card-front, .card-back { position: absolute; width: 100%; height: 100%; border-radius: 12px; backface-visibility: hidden; display: flex; align-items: center; justify-content: center; font-size: 32px; } .card-front { background: #0f3460; color: #e94560; } .card-back { background: white; transform: rotateY(180deg); } .btn { padding: 10px 24px; border: none; border-radius: 20px; background: #e94560; color: white; font-size: 16px; cursor: pointer; } .message { color: #ffcc00; font-size: 20px; text-align: center; margin-top: 15px; min-height: 30px; } </style> </head> <body> <div class="container"> <div class="header"> <div class="stats">步数: <span id="moves">0</span></div> <button class="btn" onclick="resetGame()">重新开始</button> <div class="stats">配对: <span id="pairs">0</span>/8</div> </div> <div class="grid" id="grid"></div> <div class="message" id="message"></div> </div> <script> const emojis = ['🐶','🐱','🐸','🦊','🐻','🐼','🐨','🐯']; let cards = [...emojis, ...emojis]; let flippedCards = []; let moves = 0; let pairsFound = 0; let lockBoard = false; function shuffle(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i+1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } } function resetGame() { shuffle(cards); flippedCards = []; moves = 0; pairsFound = 0; lockBoard = false; document.getElementById('moves').textContent = '0'; document.getElementById('pairs').textContent = '0'; document.getElementById('message').textContent = ''; renderGrid(); } function renderGrid() { const grid = document.getElementById('grid'); grid.innerHTML = ''; cards.forEach((emoji, i) => { const card = document.createElement('div'); card.className = 'card'; card.dataset.index = i; card.innerHTML = ` <div class="card-inner"> <div class="card-front">?</div> <div class="card-back">${emoji}</div> </div>`; card.addEventListener('click', () => flipCard(card, i)); grid.appendChild(card); }); } function flipCard(card, index) { if (lockBoard) return; if (flippedCards.length === 2) return; if (card.classList.contains('flipped')) return; card.classList.add('flipped'); flippedCards.push({ card, index, emoji: cards[index] }); if (flippedCards.length === 2) { moves++; document.getElementById('moves').textContent = moves; checkMatch(); } } function checkMatch() { const [a, b] = flippedCards; if (a.emoji === b.emoji) { pairsFound++; document.getElementById('pairs').textContent = pairsFound; flippedCards = []; if (pairsFound === 8) { document.getElementById('message').textContent = `🎉 恭喜通关!用了 ${moves} 步`; } } else { lockBoard = true; setTimeout(() => { a.card.classList.remove('flipped'); b.card.classList.remove('flipped'); flippedCards = []; lockBoard = false; }, 600); } } resetGame(); </script> </body> </html>

规则:点开两张牌,图案一样就消除,不一样就翻回去;没有限制次数,界面会记录你的翻牌次数,用的次数越少越好。

三、开灯游戏

<!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 { background: #0a0a0a; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: system-ui, sans-serif; } .container { text-align: center; color: white; } h2 { margin-bottom: 10px; } .grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin: 20px auto; width: fit-content; } .cell { width: 60px; height: 60px; border-radius: 10px; background: #333; cursor: pointer; transition: 0.2s; } .cell.on { background: #ffcc00; box-shadow: 0 0 20px rgba(255,204,0,0.6); } .info { margin-top: 10px; color: #aaa; } .btn { margin-top: 12px; padding: 10px 24px; border: none; border-radius: 20px; background: #ffcc00; color: #000; font-weight: bold; cursor: pointer; } .message { margin-top: 12px; font-size: 20px; color: #ffcc00; min-height: 28px; } </style> </head> <body> <div class="container"> <h2>💡 光影解谜</h2> <div class="grid" id="grid"></div> <div class="info">点击方块翻转它和上下左右邻居</div> <div class="message" id="message"></div> <button class="btn" onclick="shuffleBoard()">随机洗牌</button> </div> <script> const size = 5; let board = []; function createBoard() { board = Array.from({length: size}, () => Array.from({length: size}, () => false)); } function render() { const grid = document.getElementById('grid'); grid.innerHTML = ''; for (let r = 0; r < size; r++) { for (let c = 0; c < size; c++) { const cell = document.createElement('div'); cell.className = 'cell' + (board[r][c] ? ' on' : ''); cell.addEventListener('click', () => toggle(r, c)); grid.appendChild(cell); } } } function toggle(r, c) { const dirs = [[0,0],[1,0],[-1,0],[0,1],[0,-1]]; dirs.forEach(([dr, dc]) => { const nr = r + dr, nc = c + dc; if (nr >= 0 && nr < size && nc >= 0 && nc < size) { board[nr][nc] = !board[nr][nc]; } }); render(); if (checkWin()) { document.getElementById('message').textContent = '🎉 全亮了!你解开了!'; } else { document.getElementById('message').textContent = ''; } } function checkWin() { return board.every(row => row.every(cell => cell === true)); } function shuffleBoard() { createBoard(); // 随机点50下来生成可解局面 for (let i = 0; i < 50; i++) { const r = Math.floor(Math.random() * size); const c = Math.floor(Math.random() * size); const dirs = [[0,0],[1,0],[-1,0],[0,1],[0,-1]]; dirs.forEach(([dr, dc]) => { const nr = r + dr, nc = c + dc; if (nr >= 0 && nr < size && nc >= 0 && nc < size) { board[nr][nc] = !board[nr][nc]; } }); } document.getElementById('message').textContent = ''; render(); } createBoard(); shuffleBoard(); </script> </body> </html>

规则:点击一个方块,它和上下左右四个邻居都会翻转颜色(亮↔暗)。目标是把所有方块都点亮。

三个代码文件:网页小游戏代码,包括反应测试游戏,翻牌游戏,和开灯游戏资源-CSDN下载

http://www.jsqmd.com/news/751120/

相关文章:

  • 金融学论文降AI工具免费推荐:2026年财经类毕业论文4.8元极速降AI知网通过完整指南 - 还在做实验的师兄
  • CPUDoc:3大核心功能解锁CPU隐藏性能,让你的电脑快如闪电
  • 创业团队如何通过Taotoken管理多个AI项目的API成本
  • 3分钟搞定远程游戏手柄:RdpGamepad终极解决方案
  • 工作站虚拟化与普通桌面云有什么区别?
  • Python heapq实战:用内置小顶堆搞定Top K问题(附LeetCode真题)
  • 基于飞书与RAG技术构建企业知识库智能体:从原理到部署实践
  • BilibiliDown:B站视频下载的终极解决方案与完整使用指南
  • 从音箱到服务器:一张图看懂GB 4943.1-2022新国标覆盖哪些电子产品(附详细清单)
  • 2026年降AI工具支持平台对比:知网维普万方Turnitin各平台兼容性完整测试 - 还在做实验的师兄
  • 教育学论文降AI工具免费推荐:2026年师范类研究生毕业论文降AI知网达标亲测方案 - 还在做实验的师兄
  • 智能体与Web搜索结合:intelliweb-GPT实战解析
  • 正规名表维修服务商场网点电话全收录 - 亨得利官方服务中心
  • 终极冒险岛WZ文件解析器:WzComparerR2让你的游戏数据触手可及
  • SOCD Cleaner终极指南:如何彻底解决游戏键盘冲突问题
  • 避坑指南:STM32移植U8G2到0.96寸IIC屏,我遇到的5个编译错误和3个显示问题
  • 北京警察学院考研辅导班推荐:排名深度评测与选哪家分析 - michalwang
  • 2026年降AI工具改写模式对比:普通模式和深度改写哪个效果更好完整实测分析 - 还在做实验的师兄
  • 终极二进制文件识别工具Detect It Easy:从入门到精通的完整指南
  • 中国财政科学研究院考研辅导班推荐:排名深度评测与选哪家分析 - michalwang
  • 新闻传播学论文降AI工具免费推荐:2026年新闻系毕业论文4.8元知网99.26%亲测达标 - 还在做实验的师兄
  • PromptBridge:大语言模型提示工程的跨模型迁移解决方案
  • Uptime Kuma Helm Chart:Kubernetes监控部署标准化实践
  • 终极指南:使用ncmdump轻松解密网易云音乐NCM文件,实现音乐自由!
  • 工作站虚拟化能跑哪些软件?覆盖行业与应用一览
  • WPF Page导航实战:从Hyperlink到Frame,手把手打造你的第一个‘浏览器式’桌面应用
  • 别再只盯着NRZ了!PAM4时代,你的CDR设计踩了这3个坑吗?
  • 2026年降AI工具退款保障对比:哪些平台真的不达标退款完整政策横评 - 还在做实验的师兄
  • Mac终极NTFS读写解决方案:Nigate开源工具完全指南
  • 法学论文降AI工具免费推荐:2026年法律系毕业论文知网AI率超标4.8元99.26%达标方案 - 还在做实验的师兄