Столкновение сдвига 2D-прямоугольника не работает

Поэтому я разрабатываю небольшую побег, и хочу убедиться, что ты не сможешь пройти сквозь стены. Я также хочу иметь возможность скользить по стенам. Под этим я подразумеваю, что когда у вас слева стена и вы нажимаете влево и вверх, вы скользите вверх, но не проходите сквозь стену. Сначала я изготовил некоторый глючный код, который не очень хорошо работал. После некоторых поисков в Интернете я нашел это:

http://xboxforums.create.msdn.com/forums/t/59723.aspx

Это звучало действительно логично и легко, поэтому я реализовал это в своей программе. Проблема в том, что это все еще не работает, только очень нерегулярно. Иногда это позволяет вам скользить (хотя и медленнее / быстрее, чем ожидалось), иногда вы можете скользить только быстрее, а иногда вообще не можете. Мой код выглядит так:

bool cLevel::slideCol(SDL_Rect* pos, SDL_Rect* oldPos) {
bool col = false;

for (int i = 0; i < walls.size(); ++i) {
if (rectCol(*pos, walls[i])) {
pos->x = oldPos->x;
col = true;
}

if (rectCol(*pos, walls[i])) {
pos->y = oldPos->y;
col = true;
}
}

return col;
}

Он проверяет все стены против текущей позиции. Сначала он корректирует позицию x, а если столкновение все еще имеет место, то корректирует позицию y. Вы можете получить демо здесь, если хотите увидеть мою проблему в действии: https://dl.dropbox.com/u/65227065/Operation%20Get%20Out.zip . Я почти уверен, что функция rectCol работает, я тщательно ее протестировал. Но просто чтобы быть уверенным, вот оно в любом случае:

bool rectCol(SDL_Rect f, SDL_Rect s) {
bool ret = false;

int t1, r1, b1, l1;
int t2, r2, b2, l2;

t1 = f.y;
r1 = f.x + f.w;
b1 = f.y + f.h;
l1 = f.x;

t2 = s.y;
r2 = s.x + s.w;
b2 = s.y + s.h;
l2 = s.x;

// Er zijn vier situaties mogelijk: - rechtsonder1 overlapt linksboven2
//                                  - linksonder1 overlapt rechtsboven2
//                                  - linksboven1 overlapt rechtsonder2
//                                  - rechtsboven1 overlapt linksonder2
// Die worden hier elk individueel gechecked

if (r1 > l2 && r1 < r2) { // rechts
if (b1 > t2 && b1 < b2) { // onder1 overlapt linksboven2
ret = true;
} else if (t1 > t2 && t1 < b2) { // boven overlapt overlapt linksonder2
ret = true;
}
} else if (l1 > l2 && l1 < r2) { // links
if (b1 > t2 && b1 <= b2) { // onder1 overlapt rechtsboven2
ret = true;
} else if (t1 > t2 && t1 < b2) { // boven1 overlapt met rechtsonder2
ret = true;
}
}

return ret;
}

Я в конце моего ума здесь. Может быть, я просто упускаю что-то очень простое (я, вероятно, как всегда), но я просто не могу понять это. Надеюсь, что вы, ребята, сможете мне помочь, или проблема «подать» позволит мне увидеть свет.

Заранее спасибо!

[РЕДАКТИРОВАТЬ] Хорошо, поэтому я попробовал свой оригинальный подход снова, потому что у меня была догадка. Оказалось, что моя оригинальная система не работала, потому что в одной функции я прыгал вперед и назад между координатами с плавающей точкой и целочисленными координатами. Так что, если этот поток будет найден в будущем кем-то с подобной проблемой, то убедитесь, что вы придерживаетесь одного типа: целые числа или числа с плавающей точкой. Это избавит вас от головной боли.

0

Решение

Ваш rectCol Функция указывает, было ли столкновение, но оно не различает столкновение в X и столкновение в Y.

Если произошло столкновение, ваш slideCol Функция регулирует положение X, даже если столкновение было полностью в Y. Таким образом, вы не можете скользить по полу или потолку.

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

0

Другие решения

Других решений пока нет …