使用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
相关产品推荐
相关产品推荐

