如何避免Asteroids游戏中小行星分裂时子星重叠生成?
问题描述
我近期开始学习JavaScript,正在制作一款Asteroids游戏,代码与freeCodeCamp教程版本基本一致,仅在计分存储、音乐音效方面有改动。目前遇到的问题是:小行星分裂时,生成的两个子小行星会重叠在一起,我希望分裂效果更真实,让它们相邻生成而非重叠。
分裂小行星的代码如下:
function destroyAsteroid(index) { var x = roids[index].x; var y = roids[index].y; var r = roids[index].r; if (r == Math.ceil(ROID_SIZE / 2)) { roids.push(newAsteroid(x, y, Math.ceil(ROID_SIZE / 4))); roids.push(newAsteroid(x, y, Math.ceil(ROID_SIZE / 4))); score += ROID_PTS_LGE; } else if (r == Math.ceil(ROID_SIZE / 4)) { roids.push(newAsteroid(x, y, Math.ceil(ROID_SIZE / 8))); roids.push(newAsteroid(x, y, Math.ceil(ROID_SIZE / 8))); score += ROID_PTS_MED; } else { score += ROID_PTS_SML; }
我仅尝试过计算两个子小行星的距离,并用条件判断是否等于小行星尺寸,但未解决问题。请问让子小行星相邻生成的最简单方法是什么?
解决方法
最简单的方案是给两个子小行星生成相反方向的偏移坐标,基于子小行星的半径计算偏移量,确保它们的中心距离刚好等于2倍子半径(边缘完全贴合,既不重叠也无空隙),同时用随机角度让分裂方向更自然。
修改后的代码如下:
function destroyAsteroid(index) { var x = roids[index].x; var y = roids[index].y; var r = roids[index].r; // 生成0到2π之间的随机角度,让每次分裂方向都不同 var angle = Math.random() * Math.PI * 2; let childR; if (r == Math.ceil(ROID_SIZE / 2)) { childR = Math.ceil(ROID_SIZE / 4); // 计算偏移量,长度等于子小行星半径 const offsetX = Math.cos(angle) * childR; const offsetY = Math.sin(angle) * childR; // 向相反方向偏移生成两个子小行星 roids.push(newAsteroid(x + offsetX, y + offsetY, childR)); roids.push(newAsteroid(x - offsetX, y - offsetY, childR)); score += ROID_PTS_LGE; } else if (r == Math.ceil(ROID_SIZE / 4)) { childR = Math.ceil(ROID_SIZE / 8); const offsetX = Math.cos(angle) * childR; const offsetY = Math.sin(angle) * childR; roids.push(newAsteroid(x + offsetX, y + offsetY, childR)); roids.push(newAsteroid(x - offsetX, y - offsetY, childR)); score += ROID_PTS_MED; } else { score += ROID_PTS_SML; } // 移除被摧毁的父小行星,避免它继续出现在画布上 roids.splice(index, 1); }
关键说明
- 随机角度:让分裂效果更自然,不会每次都固定在同一个方向
- 偏移量计算:利用三角函数生成x、y方向的偏移,长度等于子小行星半径,确保两个子小行星中心距离刚好为2倍子半径,边缘完全贴合
- 移除父小行星:原代码遗漏了这一步,必须用
splice删除被摧毁的父小行星,否则它会继续存在于游戏中
内容的提问来源于stack exchange,提问作者Medardas Prusinskas
相关产品推荐
相关产品推荐

