如何在2D Canvas中实现玩家可变角度的扇形交互视图?
实现自定义角度的玩家交互式视图
可以通过以下修改实现自定义角度的视图范围,核心是新增一个可配置的视图角度参数,然后基于方向的中心角度动态计算视图的起始和结束弧度:
修改后的完整代码
const canvas = document.querySelector('canvas') const context = canvas.getContext('2d'); canvas.height = window.innerHeight; canvas.width = window.innerWidth; const keymap = []; const player = { x: window.innerWidth / 2 - 50, y: window.innerHeight / 2 - 50, size: 100, range: 200, viewAngle: Math.PI / 2, // 自定义视图角度,这里设为90°(π/2弧度),可随意修改 view: { start: 0, end: Math.PI } }; const draw = () => { context.clearRect(0, 0, canvas.width, canvas.height); context.fillStyle = 'rgba(0, 0, 255, .6)'; context.fillRect( player.x, player.y, player.size, player.size, ); context.fillStyle = 'rgba(0, 0, 0, .6)'; context.beginPath(); context.arc( player.x + player.size / 2, player.y + player.size / 2, player.range, player.view.start, player.view.end, false ); context.fill(); }; const change = () => { let tempChange = { x: 0, y: 0 }; keymap.forEach(direction => { if (direction === 'KeyS' || direction === 'ArrowDown') { tempChange.y = 1; } if (direction === 'KeyA' || direction === 'ArrowLeft') { tempChange.x = -1; } if (direction === 'KeyW' || direction === 'ArrowUp') { tempChange.y = -1; } if (direction === 'KeyD' || direction === 'ArrowRight') { tempChange.x = 1; } }); // 计算视图半角,用于生成起始和结束弧度 const halfAngle = player.viewAngle / 2; const actions = { '1_1': () => { // Down Right - 中心角度225°(5π/4) const centerAngle = 5 * Math.PI / 4; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '1_-1': () => { // Up Right - 中心角度315°(7π/4) const centerAngle = 7 * Math.PI / 4; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '1_0': () => { // Right - 中心角度270°(3π/2) const centerAngle = 3 * Math.PI / 2; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '-1_1': () => { // Down Left - 中心角度45°(π/4) const centerAngle = Math.PI / 4; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '-1_-1': () => { // Up Left - 中心角度135°(3π/4) const centerAngle = 3 * Math.PI / 4; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '-1_0': () => { // Left - 中心角度90°(π/2) const centerAngle = Math.PI / 2; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '0_1': () => { // Down - 中心角度0°(0) const centerAngle = 0; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '0_-1': () => { // Up - 中心角度180°(π) const centerAngle = Math.PI; player.view.start = centerAngle - halfAngle; player.view.end = centerAngle + halfAngle; }, '0_0': () => {}, }; const dir = tempChange.x + '_' + tempChange.y; const func = actions[dir]; func(); }; const loop = () => { change(); draw(); requestAnimationFrame(loop); }; const setup = () => { window.addEventListener('keydown', event => { const key = event.code; const index = keymap.indexOf(key); if (index > -1) keymap.splice(index, 1); keymap.push(key); }); window.addEventListener('keyup', event => { const key = event.code; const index = keymap.indexOf(key); if (index > -1) keymap.splice(index, 1); }); }; setup(); requestAnimationFrame(loop);
<canvas></canvas>
关键改动说明
- 新增自定义角度参数:在
player对象中添加viewAngle属性,使用弧度值定义视图的总角度(例如Math.PI/2对应90°,Math.PI/3对应60°),修改这个值就能直接调整视图范围大小。 - 动态计算视图范围:在
change函数中先计算halfAngle(视图角度的一半),然后针对每个方向的中心角度,通过中心角度±半角得到视图的起始和结束弧度,替代原来硬编码的180°范围值。 - 保留原有交互逻辑:WASD和方向键的控制逻辑完全保留,只是视图的角度范围变得可自定义。
内容的提问来源于stack exchange,提问作者RoyBlunk
相关产品推荐
相关产品推荐

