0

私が行っている 3D 用に作成した衝突検出に問題があります。

衝突検出を行った方法は、最初に古い xyz 座標を変数に格納し、次に移動関数を呼び出し、次に衝突関数を呼び出します。移動後に衝突があった場合、カメラは (今のところ) プレーヤーの場合と同様に、古い xyz 座標に戻されます。

キャラクターが立方体の側面に沿って「スライド」できるようにしたいので、x 軸で衝突した場合でも、z 軸に沿ってわずかにスライドできます。ただし、コーナーでは、x と z の両方の衝突があるため、キャラクターは完全に停止します。これが起こらないように、z と x の衝突に個別の変数を作成することにしましたが、角にいるときに立方体の内側に入ることができますが、X 軸でのみです。これを修正する方法がわかりません。さまざまなこと(コードの最新の変数など)を試しましたが、よくわかりません。助けていただければ幸いです。コードの関連部分は次のとおりです。

def otherCollision(self,x,y,z):
       print(float(Camera.x))
       xcol = 0
       zcol = 0
       latest = 0
       if (-Camera.x >= cubez[0][0] - 1) and \
          (-Camera.x <= cubez[0][0] + cubez[0][3] + 1) and \
          (-Camera.z >= cubez[0][2] - 1) and \
          (-Camera.z <= cubez[0][2] + cubez[0][5] + 1):

            if (-Camera.x >= cubez[0][0] - 1) and \
               (-Camera.x <= cubez[0][0]) or \
               (-Camera.x <= cubez[0][0] - 1 + cubez[0][3] + 2) and \
               (-Camera.x >= cubez[0][0] - 1 + cubez[0][3] + 1): #>
                #Camera.x = x
                xcol = 1
                latest = 1

            if (-Camera.z >= cubez[0][2] - 1) and \
               (-Camera.z <= cubez[0][2]) or \
               (-Camera.z <= cubez[0][2] - 1 + cubez[0][5] + 2) and \
               (-Camera.z >= cubez[0][2] - 1 + cubez[0][5] + 1):    #>=
                #Camera.z = z
                zcol = 1
                latest = 2

       if xcol == 1 and zcol == 0:
           Camera.x = x
       if zcol == 1 and xcol == 0:
           Camera.z = z
       if xcol == 1 and zcol == 1 and latest == 2:
           Camera.x = x
       if xcol == 1 and zcol == 1 and latest == 1:
           Camera.z = z

にはリスト内にリストがあることに注意してくださいcubez。最初のインデックスはオブジェクトの番号で、次のインデックスは探している値です。それらは順番に、x,y,z,width,height,depth.

私はpyglet 1.2alphaを使用していますが、問題は明らかに私のロジックにあるため、これは投稿にあまり関係していないと思います。

4

1 に答える 1

0

最善の解決策は、アクターに速度属性を追加することだと思います (例では「キャラクター」または「カメラ」ですか?)。次に、衝突に応じて、速度アトリビュートをゼロにします。

次のような単純なベクトル クラスがあるとします。

class Vector(object):
    def __init__(self, x=0.0, y=0.0, z=0.0):
        self.x = x
        self.y = y
        self.z = z

... アクターは次のようになります。

class Actor(object):
    def __init__(self):
        self.pos = Vector()
        self.vel = Vector()

シーンを更新するときは、次の手順を実行します (例に抽象化されています)。

  1. アクターにかかる力を計算し、velアトリビュートを更新します。
  2. vel衝突を判断し、それに応じて属性を更新します。
  3. posからのデータでアクターを更新しvelます。

以下の例では、簡単にするために 2D ワールド (zは常に0) を使用し、更新の一定のタイムステップ (dtは 1 秒と見なされます) を使用します。

class Actor(object):
    #(...)
    def update(self, dt=1):
        # Step 1 - assumes a constant movement to the top right
        self.vel.x = 1
        self.vel.y = 1

        # Step 2 - cube is your collision tested object
        cube = Cube()
        new_pos = self.pos + (self.vel * dt)
        if new_pos.x > cube.left and new_pos.x < cube.right:
            self.vel.x = 0
        if new_pos.y > cube.bottom and new_pos.y < cube.top:
            self.vel.y = 0

        # Step 3
        self.pos += self.vel * dt

まず、このようなものが機能するようにする必要があります。正常に機能する場合は、バウンディング ボックスをアクターに追加して、コリジョンが中央ではなく側面で実行されるようにします。

于 2013-09-08T09:36:51.250 に答える