梦幻接球 - 柔和色彩反弹小游戏
1. 柔和色彩设计方案
使用柔和的粉蓝渐变作为主色调,营造梦幻感
背景采用淡蓝到淡紫的渐变,视觉舒适
小球使用柔和的粉红色,挡板使用蓝紫渐变
所有色彩饱和度适中,避免视觉疲劳
2. 现代化UI设计
磨砂玻璃效果的面板,带有微妙阴影
圆角设计元素,符合现代UI趋势
平滑的动画过渡效果
精美的装饰性圆形元素增强视觉效果
3. 游戏功能
使用鼠标控制挡板位置
小球会以随机角度反弹
接住小球获得分数,每10分递增
每50分增加游戏难度(小球加速)
实时显示当前分数和最高分
游戏暂停/继续功能
4. 交互设计
游戏开始和结束有美观的弹窗提示
按钮有悬停和点击动画效果
小球和挡板都有精致的渐变和阴影效果
背景网格增加空间感和深度
5. 响应式设计
适配不同屏幕尺寸
在移动设备上也能良好显示
6. 游戏逻辑
小球物理反弹效果
挡板碰撞检测
分数计算与存储(使用localStorage保存最高分)
游戏状态管理(开始、暂停、结束)
7.截图展示
8.代码重现
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>梦幻接球 - 柔和色彩反弹小游戏</title><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);min-height: 100vh;display: flex;justify-content: center;align-items: center;overflow: hidden;color: #5a6782;}.game-container {width: 800px;max-width: 95%;height: 600px;background: rgba(255, 255, 255, 0.85);border-radius: 20px;box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);overflow: hidden;position: relative;display: flex;flex-direction: column;backdrop-filter: blur(10px);border: 1px solid rgba(255, 255, 255, 0.3);}/* 装饰元素 */.decoration {position: absolute;border-radius: 50%;opacity: 0.3;z-index: -1;}.dec-1 {width: 300px;height: 300px;background: linear-gradient(45deg, #ff9a9e, #fad0c4);top: -150px;right: -150px;}.dec-2 {width: 200px;height: 200px;background: linear-gradient(45deg, #a1c4fd, #c2e9fb);bottom: -100px;left: -100px;}/* 头部区域 */.game-header {padding: 20px 30px;display: flex;justify-content: space-between;align-items: center;background: rgba(255, 255, 255, 0.5);border-bottom: 1px solid rgba(0, 0, 0, 0.05);}.game-title {display: flex;align-items: center;gap: 10px;font-size: 24px;font-weight: 700;color: #6c7b95;}.game-title i {color: #ff8b94;font-size: 28px;}.score-container {display: flex;gap: 25px;}.score-box {background: linear-gradient(to right, #e0f7fa, #f5f5f5);padding: 10px 20px;border-radius: 15px;box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);display: flex;flex-direction: column;align-items: center;min-width: 100px;}.score-label {font-size: 14px;font-weight: 600;color: #7d8da7;margin-bottom: 5px;}.score-value {font-size: 28px;font-weight: 800;color: #5a6782;}/* 游戏区域 */.game-area {flex: 1;position: relative;overflow: hidden;background: rgba(245, 247, 250, 0.6);}#game-canvas {position: absolute;top: 0;left: 0;width: 100%;height: 100%;}/* 控制面板 */.game-controls {padding: 20px;display: flex;justify-content: center;gap: 15px;background: rgba(255, 255, 255, 0.6);border-top: 1px solid rgba(0, 0, 0, 0.05);}.btn {padding: 12px 30px;border: none;border-radius: 50px;font-size: 16px;font-weight: 600;cursor: pointer;transition: all 0.3s ease;display: flex;align-items: center;gap: 8px;box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);}.btn-play {background: linear-gradient(to right, #a6c1ee, #fbc2eb);color: white;}.btn-reset {background: linear-gradient(to right, #d4fc79, #96e6a1);color: white;}.btn:hover {transform: translateY(-3px);box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);}.btn:active {transform: translateY(1px);}/* 游戏状态弹窗 */.game-popup {position: absolute;top: 0;left: 0;width: 100%;height: 100%;background: rgba(255, 255, 255, 0.9);display: flex;flex-direction: column;justify-content: center;align-items: center;z-index: 10;opacity: 0;pointer-events: none;transition: opacity 0.5s ease;}.popup-visible {opacity: 1;pointer-events: all;}.popup-content {background: white;padding: 40px;border-radius: 20px;text-align: center;box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15);max-width: 80%;transform: translateY(20px);transition: transform 0.5s ease;}.popup-visible .popup-content {transform: translateY(0);}.popup-title {font-size: 32px;font-weight: 800;margin-bottom: 20px;color: #6c7b95;}.popup-message {font-size: 18px;margin-bottom: 30px;color: #7d8da7;line-height: 1.6;}.final-score {font-size: 24px;font-weight: 700;color: #ff8b94;margin: 15px 0;}/* 说明区域 */.instructions {position: absolute;bottom: 20px;left: 0;width: 100%;text-align: center;color: #a3b1c6;font-size: 14px;padding: 0 20px;}/* 响应式设计 */@media (max-width: 600px) {.game-header {flex-direction: column;gap: 15px;}.score-container {width: 100%;justify-content: center;}.btn {padding: 10px 20px;font-size: 14px;}}</style>
</head>
<body><div class="game-container"><!-- 装饰元素 --><div class="decoration dec-1"></div><div class="decoration dec-2"></div><!-- 游戏头部 --><div class="game-header"><div class="game-title"><i class="fas fa-basketball-ball"></i><span>梦幻接球</span></div><div class="score-container"><div class="score-box"><div class="score-label">分数</div><div class="score-value" id="score">0</div></div><div class="score-box"><div class="score-label">最高分</div><div class="score-value" id="high-score">0</div></div></div></div><!-- 游戏区域 --><div class="game-area"><canvas id="game-canvas"></canvas><!-- 游戏开始提示 --><div class="game-popup" id="start-popup"><div class="popup-content"><div class="popup-title">梦幻接球</div><div class="popup-message">使用鼠标移动挡板接住小球<br>不要让小球落到地面!<br>每接住一次小球获得10分</div><button class="btn btn-play" id="start-btn"><i class="fas fa-play"></i>开始游戏</button></div></div><!-- 游戏结束提示 --><div class="game-popup" id="game-over-popup"><div class="popup-content"><div class="popup-title">游戏结束</div><div class="popup-message">哎呀!小球掉下去了<br>再接再厉哦!</div><div class="final-score">最终得分: <span id="final-score">0</span></div><button class="btn btn-play" id="restart-btn"><i class="fas fa-redo"></i>重新开始</button></div></div><!-- 游戏说明 --><div class="instructions">移动鼠标控制挡板位置 | 接住小球获得分数</div></div><!-- 控制面板 --><div class="game-controls"><button class="btn btn-play" id="pause-btn"><i class="fas fa-pause"></i>暂停游戏</button><button class="btn btn-reset" id="reset-btn"><i class="fas fa-sync-alt"></i>重新开始</button></div></div><script>// 获取DOM元素const canvas = document.getElementById('game-canvas');const ctx = canvas.getContext('2d');const scoreElement = document.getElementById('score');const highScoreElement = document.getElementById('high-score');const finalScoreElement = document.getElementById('final-score');const startPopup = document.getElementById('start-popup');const gameOverPopup = document.getElementById('game-over-popup');const startBtn = document.getElementById('start-btn');const restartBtn = document.getElementById('restart-btn');const pauseBtn = document.getElementById('pause-btn');const resetBtn = document.getElementById('reset-btn');// 设置Canvas尺寸function resizeCanvas() {const gameArea = canvas.parentElement;canvas.width = gameArea.clientWidth;canvas.height = gameArea.clientHeight;}// 游戏变量let gameRunning = false;let gamePaused = false;let score = 0;let highScore = localStorage.getItem('highScore') || 0;let animationId;// 小球属性const ball = {x: 0,y: 0,radius: 15,speed: 5,dx: 0,dy: 0,color: '#ff8b94'};// 挡板属性const paddle = {x: 0,y: 0,width: 120,height: 20,color: '#a6c1ee',speed: 8};// 初始化游戏function initGame() {resizeCanvas();// 初始化小球位置和方向ball.x = canvas.width / 2;ball.y = canvas.height / 2;ball.dx = (Math.random() > 0.5 ? 1 : -1) * ball.speed;ball.dy = ball.speed;// 初始化挡板位置paddle.x = canvas.width / 2 - paddle.width / 2;paddle.y = canvas.height - 40;// 重置分数score = 0;scoreElement.textContent = score;highScoreElement.textContent = highScore;// 显示开始弹窗startPopup.classList.add('popup-visible');gameOverPopup.classList.remove('popup-visible');// 绘制初始状态draw();}// 绘制游戏元素function draw() {// 清除画布ctx.clearRect(0, 0, canvas.width, canvas.height);// 绘制背景网格drawGrid();// 绘制小球drawBall();// 绘制挡板drawPaddle();// 绘制分数drawScore();}// 绘制背景网格function drawGrid() {ctx.strokeStyle = 'rgba(180, 190, 210, 0.1)';ctx.lineWidth = 1;// 垂直线for (let x = 0; x < canvas.width; x += 30) {ctx.beginPath();ctx.moveTo(x, 0);ctx.lineTo(x, canvas.height);ctx.stroke();}// 水平线for (let y = 0; y < canvas.height; y += 30) {ctx.beginPath();ctx.moveTo(0, y);ctx.lineTo(canvas.width, y);ctx.stroke();}}// 绘制小球function drawBall() {ctx.beginPath();ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);// 创建渐变const gradient = ctx.createRadialGradient(ball.x - 5, ball.y - 5, 1,ball.x, ball.y, ball.radius);gradient.addColorStop(0, '#ffffff');gradient.addColorStop(1, ball.color);ctx.fillStyle = gradient;ctx.fill();// 添加高光ctx.beginPath();ctx.arc(ball.x - ball.radius/3, ball.y - ball.radius/3, ball.radius/3, 0, Math.PI * 2);ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';ctx.fill();}// 绘制挡板function drawPaddle() {// 挡板主体ctx.beginPath();ctx.roundRect(paddle.x, paddle.y, paddle.width, paddle.height, 10);// 创建渐变const gradient = ctx.createLinearGradient(paddle.x, paddle.y,paddle.x, paddle.y + paddle.height);gradient.addColorStop(0, paddle.color);gradient.addColorStop(1, '#fbc2eb');ctx.fillStyle = gradient;ctx.fill();// 挡板边框ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';ctx.lineWidth = 2;ctx.stroke();}// 绘制分数function drawScore() {ctx.font = '16px Arial';ctx.fillStyle = '#7d8da7';ctx.textAlign = 'left';ctx.fillText(`分数: ${score}`, 20, 30);ctx.fillText(`最高分: ${highScore}`, 20, 55);}// 更新游戏状态function update() {if (gamePaused || !gameRunning) return;// 移动小球ball.x += ball.dx;ball.y += ball.dy;// 检测墙壁碰撞(左右墙)if (ball.x - ball.radius < 0 || ball.x + ball.radius > canvas.width) {ball.dx *= -1;}// 检测墙壁碰撞(上墙)if (ball.y - ball.radius < 0) {ball.dy *= -1;}// 检测挡板碰撞if (ball.y + ball.radius > paddle.y &&ball.y - ball.radius < paddle.y + paddle.height &&ball.x > paddle.x &&ball.x < paddle.x + paddle.width) {// 根据击中挡板的位置改变反弹角度const hitPosition = (ball.x - paddle.x) / paddle.width;ball.dx = (hitPosition - 0.5) * 8; // -4 到 4 的范围// 确保垂直速度足够ball.dy = -Math.abs(ball.dy);// 增加分数score += 10;scoreElement.textContent = score;// 增加难度(每50分增加一次速度)if (score % 50 === 0) {ball.speed += 0.5;ball.dx *= 1.05;ball.dy *= 1.05;}}// 检测游戏结束(小球落地)if (ball.y + ball.radius > canvas.height) {endGame();return;}// 绘制更新draw();// 继续动画循环animationId = requestAnimationFrame(update);}// 游戏结束function endGame() {gameRunning = false;cancelAnimationFrame(animationId);// 更新最高分if (score > highScore) {highScore = score;localStorage.setItem('highScore', highScore);highScoreElement.textContent = highScore;}// 显示游戏结束弹窗finalScoreElement.textContent = score;gameOverPopup.classList.add('popup-visible');}// 鼠标移动事件 - 控制挡板canvas.addEventListener('mousemove', (e) => {if (!gameRunning) return;const rect = canvas.getBoundingClientRect();const mouseX = e.clientX - rect.left;// 更新挡板位置(限制在画布内)paddle.x = Math.max(0, Math.min(mouseX - paddle.width / 2, canvas.width - paddle.width));});// 按钮事件监听startBtn.addEventListener('click', () => {startPopup.classList.remove('popup-visible');gameRunning = true;update();});restartBtn.addEventListener('click', () => {gameOverPopup.classList.remove('popup-visible');initGame();gameRunning = true;update();});pauseBtn.addEventListener('click', () => {if (!gameRunning) return;gamePaused = !gamePaused;if (gamePaused) {pauseBtn.innerHTML = '<i class="fas fa-play"></i>继续游戏';cancelAnimationFrame(animationId);} else {pauseBtn.innerHTML = '<i class="fas fa-pause"></i>暂停游戏';update();}});resetBtn.addEventListener('click', () => {if (gameRunning) {cancelAnimationFrame(animationId);gameRunning = false;}initGame();});// 窗口大小变化时重新调整Canvaswindow.addEventListener('resize', resizeCanvas);// 初始化游戏initGame();</script>
</body>
</html>