You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:47:10