2015-06-23 2 views
9

Я занимаюсь этим уже 2-3 недели, и я до сих пор не могу найти правильное обнаружение столкновений. Я создал лабиринт с использованием прямоугольников. Я хочу, чтобы мой объект (который находится в прямоугольнике) останавливался всякий раз, когда мой объект сталкивался с любой стеной и мог двигаться куда угодно (или скользить по стене). Мои стены (прямоугольники) имеют отрицательные координаты, как следующее:Обнаружение столкновений между прямоугольниками (без перекрытия) - libgdx

shapeRenderer.rect(0.9f, 12, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); //NORTH 
shapeRenderer.rect(1, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // WEST 
shapeRenderer.rect(2, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // EAST 
shapeRenderer.rect(0.9f, 11, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); // SOUTH 

Я в настоящее время с использованием перекрывается метод, который я нашел в SO. Вот метод, который в моем классе CollisionManager:

private boolean overlaps (Rectangle collision, Rectangle wall) { 
    return Math.min(collision.x, collision.x + collision.width) 
     < Math.max(wall.x, wall.x + wall.width) 
    && Math.max(collision.x, collision.x + collision.width) 
     > Math.min(wall.x, wall.x + wall.width) 
    && Math.min(collision.y, collision.y + collision.height) 
     < Math.max(wall.y, wall.y + wall.height) 
    && Math.max(collision.y, collision.y + collision.height) 
     > Math.min(wall.y, wall.y + wall.height); 
} 

У меня есть функция, которая сохраняет все позиции движения, сделанное объект. Таким образом, когда происходит столкновение, объект восстанавливает предыдущий шаг до последнего хода (так как последний шаг, когда столкновение произошло) (пример ниже):

private void overlapsTop(Entity object, Rectangle wall){ 

    Rectangle r = new Rectangle(); 
    if(spritePositions.size() != 0){ 
     r = spritePositions.get(spritePositions.size()-1); 
    } 
    object.update(r.x, r.y, r.width, r.height); 
    object.getObject().setBounds(r.x, r.y, r.width, r.height); 
    spritePositions.clear(); 
} 

Дополнительная информация: Я переезжаю мой объект например:

public void moveRight(){ 
    position.x += 1f; 
    update(); 
} 

public void update(){ 

     boundingRectangle.set(position.x, position.y, object.getWidth(), object.getHeight()); 
} 

Где я застрял, это моя функция перекрытий (та, которую я нашел в SO). Он работает в большинстве случаев; однако, например, если объект перемещается около стены справа и касается его, функция возвращает true, и все выполняется. Но скажем, если я скольжу по стене и двигаюсь прямо вниз и что нет стен, объект останавливается в какой-то момент, потому что он обнаруживает столкновение между дном объекта и верхней частью стены (когда их нет) и столкновение между правом объекта и левым краем стены.

Я пытаюсь найти другое решение для этого. Я просто хочу, чтобы мой объект остановился на любой стене и смог двигаться (или скользить по стене), не подозревая, что может быть столкновение, где поблизости нет стен. Я чувствую, что очень близок к решению, но мне нужна дополнительная помощь.

UPDATE

Я обновил функцию moveRight и функцию обновления. @Adrian Shum и @Matthew Mark Miller. Я сделал все теперь с целым числом (вместо 0.01f использую 1f).

Таким образом, следующий код, который я использую, чтобы переместить объект, как это:

if(Gdx.input.isKeyPressed(Keys.RIGHT)){ 

       if(collisionManager.canSpriteNotMoveRight(object)){ 
        object.stopGoingRight(); 
       }else{ 
        object.moveRight(); 
       } 
      } 

В моем классе collisionManager функция stopGoingRight является следующее:

public void stopGoingRight(){ 
    position.x -= 1f; 
    update(); 
} 

До сих пор, так хорошо. Когда объект сталкивается со стеной, объект останавливается и отскакивает назад. Это хорошо. Но у меня другая проблема (что раздражает), что я постараюсь описать все, что могу. Если, например, я продолжаю перемещать объект до стены, объект будет многократно отскакивать от этой стены; если я перестаю нажимать клавишу «вверх», объект будет иногда оставаться в стене. Таким образом, когда я нажимаю клавишу «вниз», он поднимается, а не идет вниз (или если я нажму налево, объект пойдет направо, а не налево), потому что функция перекрытий выполняется (поскольку и объект, и стена пересекаются).

Есть ли способ для решения этой проблемы? Кажется, что Libgdx не идеально подходит для такого обнаружения столкновения, но сейчас я очень глубоко в разработке своей игры.

+0

Может ли прямоугольник, которым вы управляете, вращаться? Или вы просто вращаете свой заголовок? –

+0

Да, вы можете контролировать его вращение. В основном, когда вы двигаетесь вниз, вверх, вправо или влево, объект будет вращаться соответственно. –

+0

Но 'Прямоугольник' всегда будет Оси-Выровненный справа? – Springrbua

ответ

4

Я наконец-то нашел хорошее решение, все благодаря следующей ссылке: On overlap, player gets stuck libgdx Rectangle.

В основном я должен создать «поддельный» ход, чтобы увидеть, будет ли объект сталкиваться со стеной. Если есть столкновение, я просто останавливаю объект и не выполняю новый ход.

Спасибо за помощь каждому :) !! Очень благодарен!

5

Ваш алгоритм столкновения кажется многословным, но правильным (Wordy, потому что min x, x + width всегда равен x, так как ширина должна быть> = 0, а инверсия верна для max).

Считаете ли вы, что это проблема точности с плавающей точкой? Например, если вы добавите 1 к номеру fp, а затем удалите 1 из результата, вы не вернетесь к исходному значению. Вы можете быть немного более или менее, поскольку промежуточный результат не может быть представлен как поплавок.

Мой любимый пример: .1f + .2f> .3f

Смежные вопросы