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

使用Svelte+TS开发象棋游戏:检测被棋子覆盖的棋盘格悬停

解决方案

方法一:通过鼠标位置计算目标棋盘格

既然棋子会挡住棋盘格的hover事件,直接跳过棋盘格的事件监听,在拖拽过程中通过鼠标实时位置计算对应的棋盘格即可。这种方法不依赖棋盘格的onmouseenter,不管棋子在哪都能准确定位目标格子。

代码示例(Piece组件)

<script lang="ts">
  import { PieceLogic } from './PieceLogic';

  let pieceEl: HTMLDivElement;
  let isDragging = false;

  // 初始化拖拽
  function startDrag(e: MouseEvent) {
    isDragging = true;
    // 绑定全局鼠标事件,跟踪拖拽过程中的位置
    document.addEventListener('mousemove', trackMousePosition);
    document.addEventListener('mouseup', endDrag);
  }

  // 跟踪鼠标位置,计算对应棋盘格索引
  function trackMousePosition(e: MouseEvent) {
    if (!isDragging) return;
    const squareIndex = getSquareIndexFromMouse(e.clientX, e.clientY);
    PieceLogic.hoveredSqr = squareIndex;
  }

  // 结束拖拽并执行落子逻辑
  function endDrag() {
    isDragging = false;
    setPosition(PieceLogic.hoveredSqr);
    // 移除全局事件监听,避免内存泄漏
    document.removeEventListener('mousemove', trackMousePosition);
    document.removeEventListener('mouseup', endDrag);
  }

  // 根据鼠标坐标计算棋盘格索引,需根据你的棋盘布局调整参数
  function getSquareIndexFromMouse(x: number, y: number): number {
    const board = document.getElementById('chess-board');
    if (!board) return -1;
    
    const boardRect = board.getBoundingClientRect();
    const squareSize = boardRect.width / 9; // 象棋为9列,根据实际情况修改
    const col = Math.floor((x - boardRect.left) / squareSize);
    const row = Math.floor((y - boardRect.top) / squareSize);
    
    // 转换为一维索引(行*列数+列)
    return row * 9 + col;
  }
</script>

<div bind:this={pieceEl} on:mousedown={startDrag}>
  <!-- 棋子的视觉内容,比如图标、文字 -->
</div>

方法二:拆分棋子结构,用pointer-events实现事件穿透

给棋子外层容器设置pointer-events: none,让鼠标事件穿透到下方的棋盘格;同时在内部添加一个拖拽手柄元素,给手柄设置pointer-events: auto来保留拖拽功能。这样棋盘格的onmouseenter能正常触发,拖拽操作也不受影响。

代码示例(Piece组件)

<script lang="ts">
  import { PieceLogic } from './PieceLogic';

  function handleMouseUp() {
    setPosition(PieceLogic.hoveredSqr);
  }
</script>

<!-- 外层容器不拦截鼠标事件,让棋盘格接收hover -->
<div class="piece-wrapper" style="pointer-events: none; position: relative; width: 100%; height: 100%;">
  <!-- 拖拽手柄负责处理拖拽事件,拦截鼠标操作 -->
  <div 
    class="piece-drag-handle" 
    style="pointer-events: auto; position: absolute; inset: 0;"
    on:mouseup={handleMouseUp}
    on:mousedown={/* 你的拖拽初始化逻辑 */}
  >
    <!-- 棋子的视觉内容,比如图标 -->
  </div>
</div>

Square组件保留原逻辑即可:

// in the Square svelte component
square.onmouseenter = () => {
  PieceLogic.hoveredSqr = index;
}

内容的提问来源于stack exchange,提问作者mwn02

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 02:27:44