Skip to content

Commit 7d244c8

Browse files
committed
fix: pathfinding jump and falling handling
1 parent 0f4eebe commit 7d244c8

File tree

1 file changed

+57
-15
lines changed

1 file changed

+57
-15
lines changed

src/main/java/com/smallaswater/npc/route/RouteFinder.java

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,14 @@ private void process() {
8686
}
8787

8888
LinkedList<Node> nextNodes = new LinkedList<>();
89-
90-
for (int y = 1; y > -1; y--) {
89+
90+
// 顺序:先尝试平面移动(0),然后下落(-1),最后跳跃(1)
91+
for (int y : new int[]{0, -1, 1}) {
9192
boolean N = this.check(nowNode, nextNodes, 0, y, -1);
9293
boolean E = this.check(nowNode, nextNodes, 1, y, 0);
9394
boolean S = this.check(nowNode, nextNodes, 0, y, 1);
9495
boolean W = this.check(nowNode, nextNodes, -1, y, 0);
95-
96+
9697
if (N && E) {
9798
this.check(nowNode, nextNodes, 1, y, -1);
9899
}
@@ -132,7 +133,18 @@ private boolean check(Node nowNode, LinkedList<Node> nextNodes, int x, int y, in
132133
}
133134
this.closeNodes.add(vector3);
134135

135-
Node nextNode = new Node(vector3, nowNode, vector3.distance(this.start), vector3.distance(this.end));
136+
double moveCost = 1.0;
137+
if (x != 0 && z != 0) {
138+
moveCost = 1.414; // sqrt(2)
139+
}
140+
if (y != 0) {
141+
moveCost += 0.5;
142+
}
143+
144+
double G = nowNode.getG() + moveCost;
145+
double H = vector3.distance(this.end);
146+
147+
Node nextNode = new Node(vector3, nowNode, G, H);
136148
if (this.canMoveTo(nowNode, nextNode)) {
137149
nextNodes.add(nextNode);
138150
return true;
@@ -148,23 +160,53 @@ private boolean check(Node nowNode, LinkedList<Node> nextNodes, int x, int y, in
148160
* @return 是否可以移动到目标节点
149161
*/
150162
private boolean canMoveTo(Node nowNode, Node target) {
163+
// 基本检查:目标位置和头顶必须可通过
151164
if (!this.getBlockFast(target).canPassThrough() ||
152-
!this.getBlockFast(target.getVector3().add(0, 1, 0)).canPassThrough() ||
153-
!this.canWalkOn(this.getBlockFast(target.getVector3().add(0, -1, 0)))) {
165+
!this.getBlockFast(target.getVector3().add(0, 1, 0)).canPassThrough()) {
154166
return false;
155167
}
156-
157-
//跳跃检查
158-
if (target.getVector3().getY() > nowNode.getVector3().getY() &&
159-
!this.getBlockFast(nowNode.getVector3().add(0, 2, 0)).canPassThrough()) {
168+
169+
// 脚下必须可以站立
170+
if (!this.canWalkOn(this.getBlockFast(target.getVector3().add(0, -1, 0)))) {
160171
return false;
161172
}
162-
163-
if (target.getVector3().getY() < nowNode.getVector3().getY() &&
164-
!this.getBlockFast(target.getVector3().add(0, 2, 0)).canPassThrough()) {
165-
return false;
173+
174+
int yDiff = (int) (target.getVector3().getY() - nowNode.getVector3().getY());
175+
176+
// 向上跳跃检查
177+
if (yDiff > 0) {
178+
// 当前位置头顶需要有足够空间
179+
if (!this.getBlockFast(nowNode.getVector3().add(0, 2, 0)).canPassThrough()) {
180+
return false;
181+
}
182+
183+
// 检查跳跃路径中间是否有阻挡
184+
for (int i = 1; i < yDiff; i++) {
185+
Vector3 midPos = nowNode.getVector3().add(0, i, 0);
186+
if (!this.getBlockFast(midPos).canPassThrough() ||
187+
!this.getBlockFast(midPos.add(0, 1, 0)).canPassThrough()) {
188+
return false;
189+
}
190+
}
166191
}
167-
192+
193+
// 向下移动检查
194+
if (yDiff < 0) {
195+
// 目标位置头顶需要有空间
196+
if (!this.getBlockFast(target.getVector3().add(0, 2, 0)).canPassThrough()) {
197+
return false;
198+
}
199+
200+
// 检查下落路径是否畅通
201+
for (int i = -1; i > yDiff; i--) {
202+
Vector3 midPos = nowNode.getVector3().add(0, i, 0);
203+
if (!this.getBlockFast(midPos).canPassThrough() ||
204+
!this.getBlockFast(midPos.add(0, 1, 0)).canPassThrough()) {
205+
return false;
206+
}
207+
}
208+
}
209+
168210
return true;
169211
}
170212

0 commit comments

Comments
 (0)