Spigot传送魔杖开发:传送逻辑导致玩家坐标无故翻倍的问题求解
Spigot传送魔杖坐标翻倍问题排查与修复
问题根因
- Location对象引用被直接篡改
Bukkit 中Location#add()方法为原地修改当前实例坐标值,同时返回当前实例自身引用,并不会生成独立的新Location对象。
你代码中的Location a = p.getLocation().add(x + 1, y, z);语句,本质是直接对玩家当前位置的Location引用执行坐标叠加:- 玩家原坐标为(383, 43, 256),代码中读取的x/y/z就是这组绝对坐标值
- 执行叠加操作时,直接将原Location的坐标从(383,43,256)累加(384, 43, 256),得到(767, 86, 512),和实际观测到的翻倍现象完全一致
- 此时变量a和被修改后的玩家位置Location是同一个对象,后续执行
p.teleport(a)自然会直接落到翻倍的坐标上
- 前向传送逻辑完全偏离预期
原本要实现“向前传送1格”的效果,但代码全程没有读取玩家视线方向计算前向偏移,反而把玩家的绝对坐标值当成了偏移量叠加,就算解决了引用篡改的问题,也没法实现定向前跳的效果。
修复方案
- 所有坐标调整操作必须基于玩家位置的独立副本,禁止直接修改
p.getLocation()返回的原对象 - 通过玩家视角的方向向量计算1格前向的偏移量,不要直接叠加绝对坐标值
- 修正后的核心逻辑参考代码:
// 克隆独立位置副本,避免修改原对象 Location originalLoc = p.getLocation().clone(); // 计算向前1格的目标位置:取视角方向向量,缩放1格距离 Location targetLoc = originalLoc.add(originalLoc.getDirection().multiply(1)); // 在原位置触发无伤害爆炸效果 p.getWorld().createExplosion(originalLoc, 0f); // 执行传送 p.teleport(targetLoc); // 附加1秒(20游戏刻)的生命恢复效果 p.addPotionEffect(PotionEffectType.REGENERATION.createEffect(20, 1));
额外优化提示
- 事件处理方法上不要添加
static修饰,Spigot的事件监听器基于实例化对象注册,静态方法会引发不必要的内存占用与异常问题 - 如果需要限制爆炸不破坏地形,可将爆炸方法替换为
createExplosion(originalLoc, 0f, false, false),彻底关闭方块破坏与火焰生成
内容的提问来源于stack exchange,提问作者Jason6688
相关产品推荐
相关产品推荐

