1

だから私は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)
4

1 に答える 1

1

この最初のステップは、特別な方法で管理する必要があります。これは、ユニットがすでに指定されたセルを移動している場合でも、次のセルに到達するまで同じままであるためです。

ここで、移動の半分が完了したらすぐにユニットのセルを更新することをお勧めします(パスファインダーが前のセルからではなく、次のセルからのパスを検索するようにします)。さらに、あなたは次のようなもので特別な状況を管理する必要があります

if unit is standing still
  compute pathfinding as you would normally do
else
  compute pathfinding from the unit cell
  discard the first cell of the pathfinding route (since it would backtrack)
  compute the route directly to the next cell (by drawing a correct path)

もちろん、これはあなたが持っている動きの自由度に応じて簡単または難しくなります。直交する動きだけを許可する場合は簡単です。斜めの動きを許可する場合は、障害物を越えないように注意する必要があります(ユニットが障害物の角と重なっているなど、小さなグリッチに対してどの程度の許容範囲が必要かについて)。

于 2012-06-16T01:09:34.107 に答える