使用 A* 实现寻路的类似口吃的运动
我正在尝试开发一个基本的 RTS 游戏,并且使用 A* 库的寻路工作正常。然而,当发出新的目标位置时,该实现会导致角色精灵口吃或向后“传送”一点。
当短时间内连续发出呼叫时,这会变成一个大问题。
我使用的方法是 main
循环将鼠标坐标输入到 User
类和 create_path()
方法中。创建路径使用一个名为“pathfinding”的 A* 库来使用矩阵生成路径坐标列表。
然后方法create_collision_rects()
在每个路径节点坐标的中心创建小矩形对象。
然后,方法create_direction()
创建一个从Unit
对象到寻路矩形
的第一个实例的向量。
每一帧都会运行 path_collisions()
方法来检查用户是否与系列中的第一个 rect
发生碰撞。如果是这样,请删除 rect[0]
和 path[0]
并再次运行 create_direction()
。
因此寻路工作如所描述的那样,但是正如前面提到的,最大的问题是当生成新路径时,Unit 对象会向后卡顿。当需要在短时间内连续改变路径时,这是一个大问题。
我已经考虑这个问题很长一段时间了,但还没有找到任何解决方案。任何帮助将不胜感激!
Code
在用户发出寻路命令时运行一次(例如,单击屏幕):
#-----Create pathfinding-----
def create_path(self, mouse_x, mouse_y):
start_x, start_y = self.get_coord()
start = self.grid.node(start_x, start_y)
end_x, end_y = abs(mouse_x) // tile_size, abs(mouse_y) // tile_size
end = self.grid.node(end_x,end_y)
self.path,_ = self.finder.find_path(start, end, self.grid)
self.grid.cleanup()
self.create_collision_rects()
在 create_path()
之后运行一次
#-----Create collision rects-----
def create_collision_rects(self):
self.collision_rects = []
for point in self.path:
x = ((point[0] * tile_size) + tile_size//2)
y = ((point[1] * tile_size) + tile_size//2)
rect = pygame.Rect(((x - 4), (y - 4)), (8, 8))
self.collision_rects.append(rect)
self.get_direction()
在 create_collision_rects()
之后运行一次>
#-----Create vector-----
def get_direction(self):
if self.collision_rects:
start = pygame.math.Vector2(self.pos)
end = pygame.math.Vector2(self.collision_rects[0].center)
if start != end:
self.direction = (end - start).normalize()
else:
self.direction = pygame.math.Vector2(0,0)
self.path = []
运行 Unit
类的 update()
方法中的每一帧
#-----Check path collisions-----
def path_collisions(self):
if self.collision_rects:
if self.collision_rects[0].collidepoint(self.pos):
self.pos = self.collision_rects[0].center
self.collision_rects.pop(0)
self.path.pop(0)
self.get_direction()
else:
self.path = []
I'm trying to develop a rudimentary RTS game and the pathfinding using a A* library is working fine. However the implementation is causing the character sprite to stutter or to get "teleported" backwards a bit when issued a new target location to path towards.
This turns into a big issue when issued continous calls during a short time.
The method I use is the main
-loop feeds mouse-coordinates into the User
-class and the create_path()
-method. The create path uses an A* library called simply "pathfinding" to generate a list of path coordinates using a matrix.
Then the method create_collision_rects()
creates small rect objects at the center of the coordinates of each path node.
Then the method create_direction()
creates a vector from the Unit
-object to the first instance of the pathfinding rects
.
Every frame the method path_collisions()
is run to check if the user has collided with the first rect
in the series. If so remove rect[0]
and path[0]
and run create_direction()
again.
So the pathfinding works as described, however as mentioned the big problem is that the Unit
-object stutters backward when a new path is generated. This is a big problem when the path needs to be changed continously during a short time.
I've thought about this for quite some time now and haven't found any solution. Any help would be much appreciated!
Code
Runs once on user issuing a pathfinding command (eg. clicks on the screen):
#-----Create pathfinding-----
def create_path(self, mouse_x, mouse_y):
start_x, start_y = self.get_coord()
start = self.grid.node(start_x, start_y)
end_x, end_y = abs(mouse_x) // tile_size, abs(mouse_y) // tile_size
end = self.grid.node(end_x,end_y)
self.path,_ = self.finder.find_path(start, end, self.grid)
self.grid.cleanup()
self.create_collision_rects()
Runs once after create_path()
#-----Create collision rects-----
def create_collision_rects(self):
self.collision_rects = []
for point in self.path:
x = ((point[0] * tile_size) + tile_size//2)
y = ((point[1] * tile_size) + tile_size//2)
rect = pygame.Rect(((x - 4), (y - 4)), (8, 8))
self.collision_rects.append(rect)
self.get_direction()
Runs once after create_collision_rects()
#-----Create vector-----
def get_direction(self):
if self.collision_rects:
start = pygame.math.Vector2(self.pos)
end = pygame.math.Vector2(self.collision_rects[0].center)
if start != end:
self.direction = (end - start).normalize()
else:
self.direction = pygame.math.Vector2(0,0)
self.path = []
Runs every frame in the Unit
-class' update()
-method
#-----Check path collisions-----
def path_collisions(self):
if self.collision_rects:
if self.collision_rects[0].collidepoint(self.pos):
self.pos = self.collision_rects[0].center
self.collision_rects.pop(0)
self.path.pop(0)
self.get_direction()
else:
self.path = []
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在另一个线程中找到了一个答案,以回答此问题,以便其他任何正在搜索的人都可以找到它:
用pygame实现A*算法,我找到了我的单元“ back-tracks”
I found an answer in another thread, answering this so that anyone else searching may find it:
Implementing an A* algorithm with pygame I find my unit "back-tracks"