2013-08-08 2 views
0


저는 XNA 4.0에서 사원 전 달과 같은 3 차원 러너 게임을하려고했습니다.
벽돌 벽에 약간의 타격이 가해 지므로 도움을 받으실 수 있습니다!
현재 충돌 탐지에 하드 코딩 된 각 모델의 크기가 필요한 충돌 감지에 대해 자체적 인 방법을 사용하고 있습니다. 나는 바로 아래 마이크로 소프트의 코드를 사용하여 시도했지만, 항상 false를 돌려 다음과 같이XNA 4.0 3D 충돌

static bool CheckForCollisions(Entity c1, Entity c2) 
    { 
     for (int i = 0; i < c1.body.Meshes.Count; i++) 
     { 
      // Check whether the bounding boxes of the two cubes intersect. 
      BoundingSphere c1BoundingSphere = c1.body.Meshes[i].BoundingSphere; 
      c1BoundingSphere.Center += c1.position; 

      for (int j = 0; j < c2.body.Meshes.Count; j++) 
      { 
       BoundingSphere c2BoundingSphere = c2.body.Meshes[j].BoundingSphere; 
       c2BoundingSphere.Center += c2.position; 

       if (c1BoundingSphere.Intersects(c2BoundingSphere)) 
       { 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

이 찍은에서 아주 약간 수정, Here 내 Entity 클래스 간다. 나는 것 관련이 생각하는 내

코드 : 모델을 회전 할 때

public class Entity 
    { 
     public int rowID; 
     public Model body; 
     public Vector3 position; 
     public float rotation = 0f; 
     public float rotatePerFrame = 0f; 
     protected internal float toRight = 0; 
     protected internal float toLeft = 0; 
     protected internal float forward = 0; 
     protected internal float back = 0; 
     protected internal float bottom = 0; 
     protected internal float top = 0; 
     public void setDimensions(float right, float left, float front, float back, float top, float bottom) 
     { 
      this.toRight = right; 
      this.toLeft = left; 
      this.forward = front; 
      this.back = back; 
      this.top = top; 
      this.bottom = bottom; 
     } 
     public Entity RotateEnt(Entity e,float degrees)//Psuedo-only accurate to 90 degrees. 
     { 
      float actual = MathHelper.ToDegrees(degrees); 
      switch ((int)actual) 
      { 
       case 0: 
        break; 
       case 90: 
        // float temp = e.forward; 
        // e.forward = e.toLeft; 
       // e.toLeft =e.back ; 
       // e.back = e.toRight; 
       // e.toRight = temp; 
        float temp = e.forward; 
        e.forward = e.toRight; 
        e.toRight = e.back; 
        e.back = e.toLeft; 
         e.toLeft = temp; 
        break; 
       case 180: 
        e.forward = e.back; 
        e.back = e.forward; 
        e.toRight = e.toLeft; 
        e.toLeft = e.toRight; 
        break; 
       default: //case: 270 

        e.toRight = e.forward; 
        e.back = e.toRight; 
        e.toLeft = e.back; 
        e.forward = e.toLeft; 
        break; 
      } 


      return e; 
     } 
     public bool Collides(Entity e) 
     { 

      Entity c1 = RotateEnt(this, this.rotation); 
      Entity c2 = RotateEnt(e, e.rotation); 


      float myRightest = c1.position.X + c1.toRight; 
      float myLeftest = c1.position.X - c1.toLeft; 

      float hisRightest = c2.position.X + c2.toRight; 
      float hisLeftest = c2.position.X - c2.toLeft; 
      if(Collides1D(myLeftest, myRightest, hisLeftest, hisRightest)) 
      { 

       float myTop = c1.position.Y + c1.top; 
       float myBottom = c1.position.Y - c1.bottom; 

       float hisTop = c2.position.Y + c2.top; 
       float hisBottom = c2.position.Y - c2.bottom; 
       if (Collides1D(myBottom, myTop, hisBottom, hisTop)) 
       { 

        float myBack = c1.position.Z - c1.forward; 
        float myForward = c1.position.Z + c1.back; 

        float hisBack = c2.position.Z - c2.forward; 
        float hisForward = c2.position.Z + c2.back; 
        if (Collides1D(myBack, myForward, hisBack, hisForward)) 
        { 

         return true; 
        } 
       } 
      } 
      return false; 


     } 
    } 


    static bool Collides1D(float left1, float right1, float left2, float right2) 
    { 
     if (left1 >= left2 && left1 <= right2) 
      return true; 
     if (right1 >= left2 && right1 <= right2) 
      return true; 

     if (left2 >= left1 && left2 <= right1) 
      return true; 
     if (right2 >= left1 && right2 <= right1) 
      return true; 



     return false; 
    } 

내 자신의 방법도 속이고있다.
이상적으로 Microsoft의 코드가 무엇이 잘못된 것인지 알고 있으면 좋을 것입니다. 따라서 개체 차원에서 하드 코딩을 걱정하지 않고도 어디에서나 사용할 수 있습니다.
누구나 내 기본 충돌 감지 방법에 대한 빠른 수정을 볼 수 있다면 좋을 것입니다.
나는 Reimers 튜토리얼을 살펴 봤지만, 지금은 그 코드를 얻지 못하고있다. 아마도 내가 너무 오랫동안 내 코드를 쳐다 보았을 것이다.
원하는 다른 정보는 모두 시도해 볼 수있다. 공급. 그게 문제라면 모델을 업로드 할 수도 있습니다. 저는 Maya에서 FBX로 내 보낸 모델을 사용하고 있습니다. MSVS 2010을 사용하고 있습니다. 대단히 감사합니다!

+0

모델 위치를 어떻게 업데이트합니까? – davidsbro

+0

여기 내 업데이트 방법에서 코드의 마지막 부분입니다 : 이 경우 (kbstate.IsKeyDown (Keys.Up) || gpstate.DPad.Up == ButtonState.Pressed) { p1.position.Z - = 속도; } cameraPos = p1.position; cameraPos.Y + = 275; cameraPos.Z + = 550; base.Update (gameTime); – user1905811

+0

내 속도는 현재 15f 인 플로트이며, 중력도 있습니다. Vector3 gravity = new Vector3 (0f, -0.0017f, 0f); // 나중에 ... if (하강) { p1 속도 + = (중력 * 속도); } 내가 충돌 할 수있는 것을 지나치지 않도록 작업 속도를 늦췄습니다. – user1905811

답변

0

충돌 코드에 문제가 없을 수도 있지만 엔티티의 위치를 ​​어떻게 업데이트하는지 생각해보십시오. 업데이트 코드 나 MoveForward() 등 코드 유형이 표시되지 않습니다. 우선, 회전을위한 float 값 대신에 Matrix을 사용하는 것이 훨씬 쉬울 것이라고 생각합니다. 예를 들어, 당신은 할 수 :

public Void RotateEnt(float Degrees) 
{ 
    RotationMatrix *= Matrix.CreateFromAxisAngle(RotationMatrix.Up, MathHelper.ToRadians(Degrees)); 
} 

그리고 당신은 모든이 작업을 수행 할 경우, 당신은 쉽게 업데이트 할 수 있어야한다 :

public class Entity 
{ 
    ... 
    public Matrix RotationMatrix = Matrix.Identity; 
    public Vector3 position; 

    Public Entity(Vector3 FaceDirection, Vector3 UpDirection, Vector3 Position) 
    { 
     ... 
     position = Position 
     RotationMatrix = Matrix.CreateWorld(Position, FaceDirection, UpDirection) 
    } 
} 

을 다음 회전 할 경우, 당신이해야 할 것입니다 내가 생각하는 당신의 엔티티의 위치는, 이렇게하면, 당신의 엔티티의 위치가 다음 충돌 문제를 해결해야하는 업데이트됩니다 생각하는 문제

public Void Update(GameTime gametime) 
{ 
    position += RotationMatrix.Forward * gametime.ElapsedRealTime.TotalMilliseconds * x; //x = some number to scale up or down velocity. 
} 

입니다. 그러나 엔티티의 위치를 ​​업데이트하는 방법을 알지 못하고 있습니다. HTH

+0

내 모델이 움직이고 잘 표시되므로 여기서 다루고 싶은 문제는 아닙니다. 어쨌든 제안 해 주셔서 감사합니다. – user1905811