虚拟Hama珠子工具:优化矩阵邻居状态检测实现边缘圆角
优化Hama珠子边缘圆角显示的解决方案
一、安全处理边界:避免索引越界
先实现一个安全的邻居查找函数,自动处理矩阵边缘的越界情况,无需每次手动判断:
// 假设矩阵列数为cols,行数为rows;1D数组转坐标:index = y * cols + x function getNeighbor(x, y, dx, dy) { const nx = x + dx; const ny = y + dy; // 边界外的位置直接返回"无邻居"的虚拟对象 if (nx < 0 || nx >= cols || ny < 0 || ny >= rows) { return { isOn: false }; } const index = ny * cols + nx; return hamas[index]; }
调用这个函数时,无论当前珠子在矩阵哪个位置,都不会出现索引越界问题。
二、减少计算量:只更新受影响的珠子
不用每次放置珠子都遍历整个hamas数组,只需要更新当前点击的珠子和它的8个相邻珠子——只有这些珠子的圆角显示状态会发生变化:
- 当用户点击珠子时,先获取它的坐标
(x, y),切换其isOn状态 - 收集当前珠子和8个邻居的坐标(共9个点)
- 对每个有效坐标(在矩阵范围内的),重新计算其邻居状态并更新显示
伪代码示例:
function updateAffectedBeads(clickedX, clickedY) { // 包含当前珠子和8个邻居的偏移量 const allOffsets = [ [0,0], [-1,-1], [0,-1], [1,-1], [-1,0], [1,0], [-1,1], [0,1], [1,1] ]; allOffsets.forEach(([dx, dy]) => { const x = clickedX + dx; const y = clickedY + dy; if (x >=0 && x < cols && y >=0 && y < rows) { const index = y * cols + x; const bead = hamas[index]; // 重新计算该珠子的邻居状态并更新显示 bead.neighborMask = calculateNeighborMask(x, y); updateBeadDisplay(bead); } }); }
三、高效映射圆角状态:用位掩码替代字符串编码
把原来的字符串邻居编码替换为8位位掩码,数字运算比字符串拼接/匹配高效得多:
- 给8个邻居固定顺序(比如上、右上、右、右下、下、左下、左、左上)
- 每个邻居存在(
isOn=true)就把对应位设为1,最终得到0-255的整数掩码 - 用掩码直接映射对应的圆角图片
实现代码:
// 定义8个邻居的偏移量(固定顺序) const neighborOffsets = [ [0, -1], // 上 [1, -1], // 右上 [1, 0], // 右 [1, 1], // 右下 [0, 1], // 下 [-1, 1], // 左下 [-1, 0], // 左 [-1, -1] // 左上 ]; function calculateNeighborMask(x, y) { let mask = 0; for (let i = 0; i < neighborOffsets.length; i++) { const [dx, dy] = neighborOffsets[i]; const neighbor = getNeighbor(x, y, dx, dy); if (neighbor.isOn) { mask |= (1 << i); // 将对应位设为1 } } return mask; }
之后可以直接用mask值匹配图片,比如hama_${mask}.png,或者用一个对象做映射表。
四、可选优化:缓存掩码减少重复计算
给每个hama对象添加lastMask属性,只有当自身或邻居的isOn状态变化时,才重新计算掩码,避免无意义的重复计算:
// 在更新珠子时先判断是否需要重新计算 if (bead.lastMask !== undefined && bead.lastMask === newMask) { return; // 状态无变化,无需更新显示 } bead.lastMask = newMask; updateBeadDisplay(bead);
内容的提问来源于stack exchange,提问作者Alix Turcq
相关产品推荐
相关产品推荐

