Столкновение ограничительной рамки XNA 3D не вызывает - PullRequest
0 голосов
/ 06 ноября 2018

Я просматриваю около полутора часов или около того, чтобы найти решение этой проблемы. Я видел некоторые темы на форумах по разработке Xbox Live Indie, но сами форумы не загружаются (их убрали?) И везде, где я смотрю, я не могу найти ответ.

Проблема, с которой я столкнулся, заключается в том, что я не могу заставить какой-либо вид Intersect срабатывать между двумя BoundingBoxes. Я создал куб в трехмерном пространстве, а затем поставил прямоугольник в противоположных вершинах, и этот прямоугольник выглядит хорошо из того, что я могу сказать в Выводе. Как и BoundingBox камеры <- Для этого я взял позицию игрока и + - 1 на каждой оси для мин / макс. Первоначально я намеревался просто повторно использовать положение игрока как для минимума, так и для максимума, но это не сработало, поэтому я попробовал это, но все равно не работает. </p>

Вот некоторые фрагменты моего кода.

    void CheckCollision(Vector3 inPos, Vector3 inOldPos) //The idea for the inPos and
old position was that I'd reset the player's position to the old pos if there's a collision
    {
        if (block.collisionBox.Intersects(cam.cameraBox))
        {
            Debug.WriteLine("HELP"); //This doesn't trigger
        }
    }

Следующее обновление в основном классе игры.

        protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        CheckCollision(cam.Position, cam.comparisonVector);

        base.Update(gameTime);
    }

Теперь переходим к классу Куба.

        private void SetUpVertices()
    {
        vertices = new VertexPositionColor[8];

        //front left bottom corner
        vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), color);
        //front left upper corner
        vertices[1] = new VertexPositionColor(new Vector3(0, 5, 0), color);
        //front right upper corner
        vertices[2] = new VertexPositionColor(new Vector3(5, 5, 0), color);
        //front lower right corner
        vertices[3] = new VertexPositionColor(new Vector3(5, 0, 0), color);
        //back left lower corner
        vertices[4] = new VertexPositionColor(new Vector3(0, 0, -5), color);
        //back left upper corner
        vertices[5] = new VertexPositionColor(new Vector3(0, 5, -5), color);
        //back right upper corner
        vertices[6] = new VertexPositionColor(new Vector3(5, 5, -5), color);
        //back right lower corner
        vertices[7] = new VertexPositionColor(new Vector3(5, 0, -5), color);

        collisionBox = new BoundingBox(vertices[0].Position, vertices[6].Position);

        vBuffer = new VertexBuffer(device, typeof(VertexPositionColor), 8, BufferUsage.WriteOnly);
        vBuffer.SetData<VertexPositionColor>(vertices);
    }

И, наконец, класс камеры.

        void UpdateBoundingBox()
    {
        cameraBox = new BoundingBox(cameraPosition + new Vector3(-1, -1, -1), cameraPosition + new Vector3(1,1,1));
    }

Если вы хотите что-нибудь еще, просто дайте мне знать :) Я ценю любую помощь, спасибо

1 Ответ

0 голосов
/ 07 ноября 2018

Проблема с минимальными и максимальными координатами вашего окна столкновения. Поле столкновения min находится в [0,0,0], а максимальное - [5,5, -5].

Координата max ограничивающего прямоугольника всегда должна быть больше для компонента x, y и z, чем для min, в противном случае вы можете создать ограничивающий прямоугольник с «отрицательной» толщиной для одного или нескольких измерений (или обычно называемый как вывернутый наизнанку). коробка).

Вы можете получить правильные минимальные и максимальные значения вашего ограничивающего прямоугольника с помощью следующей модификации. Идея здесь состоит в том, чтобы просто сравнивать компоненты x, y и z каждой вершины, ища самое низкое значение x из всех вершин, самое низкое значение y и самое низкое значение z, которое становится новым минимумом вашего блока. То же самое делается для получения максимальной координаты. (Возможно, не самый эффективный код, но, тем не менее, в качестве рабочего примера он выполняет свою работу).

Vector3 MinResult(Vector3 u, Vector3 v)
  {
     Vector3 minVec = v;

     if (u.X < v.X)
     {
        minVec.X = u.X;
     }

     if (u.Y < v.Y)
     {
        minVec.Y = u.Y;
     }

     if (u.Z < v.Z)
     {
        minVec.Z = u.Z;
     }

     return minVec;
  }

  Vector3 MaxResult(Vector3 u, Vector3 v)
  {
     Vector3 maxVec = v;

     if (u.X > v.X)
     {
        maxVec.X = u.X;
     }

     if (u.Y > v.Y)
     {
        maxVec.Y = u.Y;
     }

     if (u.Z > v.Z)
     {
        maxVec.Z = u.Z;
     }

     return maxVec;
  }

private void SetUpVertices()
{
     vertices = new VertexPositionColor[8];

     //front left bottom corner
     vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), color);
     //front left upper corner
     vertices[1] = new VertexPositionColor(new Vector3(0, 5, 0), color);
     //front right upper corner
     vertices[2] = new VertexPositionColor(new Vector3(5, 5, 0), color);
     //front lower right corner
     vertices[3] = new VertexPositionColor(new Vector3(5, 0, 0), color);
     //back left lower corner
     vertices[4] = new VertexPositionColor(new Vector3(0, 0, -5), color);
     //back left upper corner
     vertices[5] = new VertexPositionColor(new Vector3(0, 5, -5), color);
     //back right upper corner
     vertices[6] = new VertexPositionColor(new Vector3(5, 5, -5), color);
     //back right lower corner
     vertices[7] = new VertexPositionColor(new Vector3(5, 0, -5), color);

     Vector3 max = vertices[0].Position;
     Vector3 min = vertices[0].Position;

     foreach(VertexPositionColor vc in vertices)
     {
        min = MinResult(min, vc.Position);
        max = MaxResult(max, vc.Position);
     }

     collisionBox = new BoundingBox(min, max);

     vBuffer = new VertexBuffer(gd, typeof(VertexPositionColor), 8, BufferUsage.WriteOnly);
     vBuffer.SetData<VertexPositionColor>(vertices);
  }

Я попытался сделать это с положением камеры [0,0,0], и оно вернуло true для столкновения между двумя полями.

...