Java节奏游戏开发中如何获取LinkedList内Beat对象的x坐标
实现步骤
你可以直接在Handler类的tick方法中扩展判定逻辑,或者单独封装判定方法,通过遍历链表分别取出Player实例和所有Beat实例做坐标比对即可,具体实现如下:
前提说明
你提到GameObject的getter/setter已经实现,我们默认你已经实现了getX()、getId()两个方法,分别用于获取对象x坐标、对象的ID枚举值。
1. 直接在Handler的tick方法中加入判定逻辑
修改后的tick方法代码如下:
public void tick(){ int playerX = 0; // 第一步:先遍历获取Player的x坐标 for (GameObject tempObject : object) { if (tempObject.getId() == ID.Player) { playerX = tempObject.getX(); break; } } // 第二步:遍历所有对象,找到Beat做坐标比对 for(int i = 0; i < object.size(); i++){ GameObject tempObject = object.get(i); tempObject.tick(); if (tempObject.getId() == ID.Beat) { // 节奏游戏通常有判定容错区间,这里设置±15的误差范围,可自行调整 int offset = Math.abs(tempObject.getX() - playerX); if (offset <= 15) { // 此处写命中后的逻辑,比如加分、移除当前Beat System.out.println("命中判定成功"); removeObject(tempObject); i--; // 移除元素后索引回退,避免漏掉下一个元素 } else if (tempObject.getX() < playerX - 15) { // Beat已经飘过Player,判定Miss System.out.println("Miss"); removeObject(tempObject); i--; } } } }
2. 可选优化:单独封装判定方法
如果后续逻辑更复杂,可以把判定逻辑抽成单独的方法,在tick中调用即可:
// 新增Beat判定方法 private void checkBeatHit() { int playerX = 0; for (GameObject tempObject : object) { if (tempObject.getId() == ID.Player) { playerX = tempObject.getX(); break; } } for (int i = 0; i < object.size(); i++) { GameObject temp = object.get(i); if (temp.getId() == ID.Beat) { int offset = Math.abs(temp.getX() - playerX); if (offset <= 15) { System.out.println("命中"); removeObject(temp); i--; } else if (temp.getX() < playerX - 15) { System.out.println("Miss"); removeObject(temp); i--; } } } } // tick方法调整为 public void tick(){ for(int i = 0; i < object.size(); i++){ GameObject tempObject = object.get(i); tempObject.tick(); } checkBeatHit(); }
注意事项
- 因为
LinkedList调用get(i)的时间复杂度是O(n),如果游戏中Beat数量很多,建议换成ArrayList存储游戏对象,遍历效率更高 - 判定容错区间可以根据你的游戏难度自行调整,数值越大判定越松
- 移除Beat对象后一定要做
i--操作,否则会跳过下一个元素的遍历,导致逻辑异常
内容的提问来源于stack exchange,提问作者SourOddity
相关产品推荐
相关产品推荐

