だから私はPygameをいじくり回していて、解決できる問題に遭遇しましたが、それはエレガントではありません。
基本的に、私は黒のプレーンフィールドにユニット(この時点では赤い四角)を持っています。ユニットをクリックしてから、フィールド上の他の場所をクリックすると、ユニットはそのポイントに進みます。アルゴリズム自体は非常に完璧に機能し、障害物が導入された後でも、パスファインディングをすばやく処理します。
私の問題は私の実装にあります。単位は16x16の正方形であるため、フィールドは16x16の正方形に分割されます。輸送中にユニットの目的地を変更すると、新しいルートを続行する前に、以前の「ウェイポイント」に「バックトラック」することがあります。
これが発生する理由を理解しています。パスファインディングモジュールは、各正方形をグリッド上のポイントとして扱うため、マウス座標をパスメソッドに渡すと、ポイント(2,2)のピクセル座標は実際には(32,32)になります。私はそれらを16で割って整数を切り捨てます(したがって、(34,37)は(2,2)になります)ので、ユニットは実際の「グリッドポイント」の間にある可能性がありますが、パスファインディングモジュールは最後の実際のウェイポイントからパスを見つけます。現在の場所ではありません。新しいルートをユニットに渡すとき、ユニットはパスファインディングモジュールが見つけたルートをたどるために「バックトラック」する必要があります
明らかに、あらゆる種類のパスファインディングを行うすべてのゲーム開発者がこれを解決したので、よりエレガントなソリューションを見つけられることを望んでいます。画面上のすべてのピクセルに沿ったパスをウェイポイントだけで見つけたくはありませんが、バックトラックは少しイライラします。助言がありますか?
以下に提案されているように、関連するコードは次のとおりです。
メインの.pyファイル
if pygame.mouse.get_pressed()[0]: # if left mouse button pressed
mouse_x,mouse_y = pygame.mouse.get_pos()
if selected: # checks if a unit is selected
unit.getRoute((mouse_x/16,mouse_y/16))
unit.pyファイル内
def getRoute(self,target):
self.route = path((self.x/16,self.y/16), target)
def getNode(self):
if self.route:
self.node = route.pop(0)
dif_x,dif_y = self.node[0] - self.x, self.node[1] - self.y
if dif_x > 0:
self.vector_x = self.speed
if dif_x < 0:
self.vector_x = self.speed * -1
else:
self.vector_x = 0
if dif_y > 0:
self.vector_y = self.speed
if dif_x < 0:
self.vector_y = self.speed * -1
else:
self.vector_y = 0
else:
self.node = None
self.vector_x = 0
self.vector_y = 0
def update(self):
if self.route or self.node:
if self.route and not self.node:
self.getNode()
if (self.x,self.y) == self.node:
self.getNode()
self.x += self.vector_x
self.y += self.vector_y
self.rect.topleft = (self.x,self.y)