如何在HTML5 Canvas中添加旋转黑洞元素实现飞船靠近触发跳转功能
实现方案
我们可以通过以下步骤修改现有代码完成需求:
步骤1:新增全局配置变量
在JS代码开头的常量定义部分,新增以下内容:
// 场景状态:1=初始太空场景,2=黑洞跳转后的新场景 let currentScene = 1; // 黑洞配置 const BLACKHOLE_CONFIG = { orbitCenter: { x: window.innerWidth / 2, y: window.innerHeight / 2 }, // 圆周运动中心 orbitRadius: 200, // 圆周运动半径 rotateSpeed: 0.02, // 旋转速度 size: 30, // 黑洞大小 triggerDistance: 150 // 触发交互的距离阈值 }; let blackholeAngle = 0; // 黑洞当前旋转角度
步骤2:修改键盘事件监听函数
在handleKeyInput函数中新增回车键的判断逻辑:
function handleKeyInput(event) { const { keyCode, type } = event; const isKeyDown = type === 'keydown' ? true : false; if (keyCode === 37) spaceShip.rotatingLeft = isKeyDown; if (keyCode === 39) spaceShip.rotatingRight = isKeyDown; if (keyCode === 38) spaceShip.engineOn = isKeyDown; // 新增回车键逻辑 if (keyCode === 13 && isKeyDown) { // 计算飞船中心坐标 const shipCenterX = spaceShip.position.x + spaceShip.size.width / 2; const shipCenterY = spaceShip.position.y + spaceShip.size.height / 2; // 计算黑洞当前坐标 const blackholeX = BLACKHOLE_CONFIG.orbitCenter.x + Math.cos(blackholeAngle) * BLACKHOLE_CONFIG.orbitRadius; const blackholeY = BLACKHOLE_CONFIG.orbitCenter.y + Math.sin(blackholeAngle) * BLACKHOLE_CONFIG.orbitRadius; // 计算两点距离 const distance = Math.sqrt(Math.pow(shipCenterX - blackholeX, 2) + Math.pow(shipCenterY - blackholeY, 2)); // 距离小于阈值则切换场景 if (distance < BLACKHOLE_CONFIG.triggerDistance) { currentScene = currentScene === 1 ? 2 : 1; } } }
步骤3:修改draw渲染函数
更新draw函数,新增黑洞渲染、距离判断、场景切换逻辑:
function draw() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; // 1. 根据场景渲染背景 if (currentScene === 1) { context.fillStyle = 'rgb(0, 10, 60)'; } else { // 新场景示例:深紫色背景 context.fillStyle = 'rgb(30, 0, 60)'; } context.fillRect(0, 0, window.innerWidth, canvas.height); // 2. 根据场景渲染星星 let starColor = currentScene === 1 ? 'white' : 'cyan'; // 小恒星 for (var i = 1; i<window.innerWidth; i+=100){ for(var j = 1; j<window.innerHeight; j+=100){ context.beginPath(); context.arc(i, j, 1, 0, Math.PI*2, false); context.fillStyle = starColor; context.fill(); } } // 中恒星 for (var i = 1; i<window.innerWidth; i+=150){ for(var j = 1; j<window.innerHeight; j+=150){ context.beginPath(); context.arc(i, j, 2, 0, Math.PI*2, false); context.fillStyle = starColor; context.fill(); } } // 大恒星 for (var i = 1; i<window.innerWidth; i+=225){ for(var j = 1; j<window.innerHeight; j+=225){ context.beginPath(); context.arc(i, j, 3, 0, Math.PI*2, false); context.fillStyle = starColor; context.fill(); } } // 3. 更新并渲染黑洞 blackholeAngle += BLACKHOLE_CONFIG.rotateSpeed; const blackholeX = BLACKHOLE_CONFIG.orbitCenter.x + Math.cos(blackholeAngle) * BLACKHOLE_CONFIG.orbitRadius; const blackholeY = BLACKHOLE_CONFIG.orbitCenter.y + Math.sin(blackholeAngle) * BLACKHOLE_CONFIG.orbitRadius; // 绘制黑洞本体 context.beginPath(); context.arc(blackholeX, blackholeY, BLACKHOLE_CONFIG.size, 0, Math.PI * 2); context.fillStyle = 'black'; context.fill(); // 绘制黑洞发光边缘 context.beginPath(); context.arc(blackholeX, blackholeY, BLACKHOLE_CONFIG.size + 5, 0, Math.PI * 2); context.strokeStyle = '#9d4edd'; context.lineWidth = 3; context.stroke(); // 4. 计算飞船与黑洞距离,显示提示 const shipCenterX = spaceShip.position.x + spaceShip.size.width / 2; const shipCenterY = spaceShip.position.y + spaceShip.size.height / 2; const distance = Math.sqrt(Math.pow(shipCenterX - blackholeX, 2) + Math.pow(shipCenterY - blackholeY, 2)); if (distance < BLACKHOLE_CONFIG.triggerDistance) { context.font = "24px Arial"; context.fillStyle = "white"; context.textAlign = "center"; context.fillText("按回车键进入新场景", window.innerWidth / 2, window.innerHeight - 50); } // 5. 渲染飞船 spaceShip.moveSpaceShip(); spaceShip.draw(); requestAnimationFrame(draw); }
效果说明
- 黑洞会以屏幕中心为原点做匀速圆周运动,自带紫色发光边缘
- 当飞船距离黑洞小于150px时,屏幕底部会弹出按回车键的提示
- 按下回车键后会切换到新场景,场景背景变为深紫色,星星变为淡青色,也可以根据自己的需求修改新场景的渲染逻辑
内容的提问来源于stack exchange,提问作者AllinTheSauce
相关产品推荐
相关产品推荐

