![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: May 2008
Сообщений: 102
|
Привет всем. Долго выбирал раздел форума, и надеюсь написал в нужный. Если что, прошу извинить
![]() Ибо моя проблема не затрагивает сам язык или технологию - речь идет про обычную математику. Делаю игру про бегающих человечков - вид сверху. Все человечки основаны на окружностях. Игрок бегает, все остальные за ним охотятся, то есть могу облепить его со всех сторон. Обрабатываю столкновения и есть один нехороший баг, который я никак не могу побороть. Спец. билд, показывающий баг: http://makegames.ru/temp/builds/zombieLab/temporary/ Баг состоит в том, что когда игрока облепливают со всех сторон и если начать бежать в одну сторону, то персонаж начинается двигаться в абсолютно противоположную и тащить за собой всю толпу. А в идеале он должен либо стоять на месте, либо хотя бы продвигаться в указанном направлении. Скорость игрока в 2 с небольшим раза больше, чем скорость зомби. Помогите пожалуйста понять где ошибка. Вот кусок кода с подробными комментариями: // в одном методе идет и проверка на столкновения и перемещение объекта. У каждой окружности есть такой метод public function detectCollisionsAndMove():void { // если близко нет соседей, то проверять на столкновения не с кем - перемещаем тело и выходим if ( !neighborsLength ) { if ( velocityVector.length ) { x += velocityVector.x; y += velocityVector.y; } return false; } var i:int, j:int; var result:Boolean = false; // Разобьем дистанцию на 4 промежутка и проверим каждый кусочек var iter:int = 4; var k:Number = 1 / iter; var velocityX:Number = velocityVector.x * k; var velocityY:Number = velocityVector.y * k; var distanceFull:Number; var separationLength:Number; var scaleFactor:Number; var separationX:Number = 0; var separationY:Number = 0; var object:ObjectBase; var human:HumanBase; // это временный объект для хранения координат и вычислений ghostPosition.setTo( x, y, 0 ); for (j = 0; j < iter; j++) { // начинаем двигаться к целевой точке ghostPosition.x += velocityX; ghostPosition.y += velocityY; for ( i = 0; i < neighborsLength; i++ ) { object = neighbors[i]; if ( object == this || object == null ) continue; separationLength = 0; if ( object is HumanBase ) { // проверка на столкновение движущихся объектов human = object as HumanBase; // составляем вектор от центра объекта, до центра объекта с которым проверяем separationVector.setTo( ghostPosition.x - human.x, ghostPosition.y - human.y, 0 ); // вычисляем расстояние - сумма радиусов distanceFull = firstRadius + human.firstRadius; separationLength = separationVector.length; if ( separationLength < distanceFull ) { // если расстояние меньше чем сумма радиусов, сжимаем вектор, чтобы получить вектор смещения if ( separationLength ) separationVector.scaleBy( ( distanceFull / separationLength ) - 1); // накапливаем данные о смещении separationX += separationVector.x; separationY += separationVector.y; result = true; } } } // если мы уже с кем-то столкнулись, то сдвигаться дальше к целевой точке нет смысла - будем упираться в те же объекты, с которыми столкнулись if ( result ) break; } x = ghostPosition.x + separationX; y = ghostPosition.y + separationY; } |
|
|||||
|
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
Ну он начинает двигаться, а его начинают возвращать) Возможно, человек у вас постоянно в начале списка, потому сперва всегда его возвращают на место и поможет его перекинуть в конец списка (а если в конце, то наоборот =).
А вообще задача сложная и, в общем, точно не решается. Этим занимается solver физ. движков. Потому тут наверное лучше просто взять box2d какой-нить.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. |
|
|||||
|
Регистрация: May 2008
Сообщений: 102
|
Box2d тут очень тормозит, я пробовал. Игрок апдейтится последним.
Цитата:
|
|
|||||
|
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
А если его таки попробовать первым апдейтить? Вообще поигрался - довольно забавно =)
Только меня больше смутило, что малейшее касание зомба очень сильно стопит. А смещение при облеплении - не заметил бы даже. И когда он облеплен, то по идее он и так быстро сдохнет, не думаю, что игрок заметит то смещение, оно очень медленно ползет. Я бы предложил вместо того, чтобы бить на 4 части отрезок, на одну отрисовку (т.е. enter frame), 4 раза апдейтить мир (ну соответственно скорости все в 4 раза меньше, как вы делали при помощи k и iter ваших).
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. |
|
|||||
|
Регистрация: May 2008
Сообщений: 102
|
От логики мира пока сделаны как раз только коллизии. Там ничего другого нет. Я попробую отдельно вытащить метод и протестировать.
Добавлено через 24 часа 51 минуту Если кому интересно, то буду пробовать вот этот подход - http://www.gamedev.ru/code/articles/...onBasedPhysics |
![]() |
![]() |
Часовой пояс GMT +4, время: 21:49. |
|
|
« Предыдущая тема | Следующая тема » |
|
|