游戏中玩家与敌人碰撞扣血不稳定,Coordinate类equals问题求助
问题排查与解决方案
咱们先一步步拆解你遇到的“触碰敌人有时扣血有时不扣”的问题,找到核心原因再给出解决办法:
1. 碰撞检测逻辑的根本性问题
你现在用player.equals(enemy.getEnemy())来判断碰撞,本质是只有当玩家和敌人的坐标点完全重合时才触发扣血,但游戏里的角色都是有实际碰撞体积的(比如一个矩形区域),不是单个像素点。举个例子:如果玩家的碰撞盒是20x20像素,敌人也是20x20,只要两个矩形有重叠就应该判定碰撞,但你现在只有当它们的坐标点(比如中心点)完全一致时才触发,这就会出现“偶尔刚好重合才扣血,大部分时候碰到但没重合就不扣”的情况。
解决方案:改用碰撞盒重叠检测
给玩家和敌人添加基于矩形区域的碰撞判断,假设每个角色的碰撞大小是固定的(比如20x20),可以写一个通用的碰撞检测方法:
// 假设每个角色的碰撞尺寸为20x20,可根据你的游戏调整 private static final int COLLISION_SIZE = 20; // 检测两个角色是否碰撞的方法 private boolean isColliding(Coordinate a, Coordinate b) { // 计算两个角色的碰撞矩形边界 int aLeft = a.getX(); int aRight = a.getX() + COLLISION_SIZE; int aTop = a.getY(); int aBottom = a.getY() + COLLISION_SIZE; int bLeft = b.getX(); int bRight = b.getX() + COLLISION_SIZE; int bTop = b.getY(); int bBottom = b.getY() + COLLISION_SIZE; // 矩形不重叠的四个条件,取反就是重叠(碰撞) return !(aRight < bLeft || aLeft > bRight || aBottom < bTop || aTop > bBottom); }
然后把原来的扣血逻辑替换成:
// HP LOST if(isColliding(player, enemy1.getEnemy()) || isColliding(player, enemy2.getEnemy()) || isColliding(player, enemy3.getEnemy()) || isColliding(player, enemy4.getEnemy()) || isColliding(player, enemy5.getEnemy())){ HP = HP-1; Toast.makeText(c,"HP -1",Toast.LENGTH_SHORT).show(); if(HP==0){ currentGameState = GameState.Lost; } }
2. 优化Coordinate的equals方法(避免潜在bug)
你的equals方法逻辑是对的,但嵌套if的写法容易让人误解,建议改成更简洁清晰的形式,减少后续出错概率:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Coordinate that = (Coordinate) o; return getX() == that.getX() && getY() == that.getY(); }
同时按照Java规范,重写equals时最好同步重写hashCode方法,避免后续用集合(比如HashMap)存放Coordinate时出现异常:
@Override public int hashCode() { return Objects.hash(getX(), getY()); } // 记得导入java.util.Objects包
3. 额外排查点:敌人位置的更新逻辑
你贴的Enemy类代码里enemysMechanic方法没写完,如果敌人是可移动的,要确保敌人的Coordinate对象是实时更新的——比如敌人移动时必须调用setX/setY来修改坐标,否则碰撞判断会基于旧的位置,也会导致触发不稳定。
内容的提问来源于stack exchange,提问作者toja6755
相关产品推荐
相关产品推荐

