Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 11.06.2012, 20:05
ekeeper вне форума Посмотреть профиль Отправить личное сообщение для ekeeper Найти все сообщения от ekeeper
  № 1  
Ответить с цитированием
ekeeper

Регистрация: May 2008
Сообщений: 102
По умолчанию Баг при реакции на столкновение нескольких окружностей

Привет всем. Долго выбирал раздел форума, и надеюсь написал в нужный. Если что, прошу извинить
Ибо моя проблема не затрагивает сам язык или технологию - речь идет про обычную математику.

Делаю игру про бегающих человечков - вид сверху. Все человечки основаны на окружностях. Игрок бегает, все остальные за ним охотятся, то есть могу облепить его со всех сторон. Обрабатываю столкновения и есть один нехороший баг, который я никак не могу побороть.

Спец. билд, показывающий баг: http://makegames.ru/temp/builds/zombieLab/temporary/
Баг состоит в том, что когда игрока облепливают со всех сторон и если начать бежать в одну сторону, то персонаж начинается двигаться в абсолютно противоположную и тащить за собой всю толпу. А в идеале он должен либо стоять на месте, либо хотя бы продвигаться в указанном направлении. Скорость игрока в 2 с небольшим раза больше, чем скорость зомби.

Помогите пожалуйста понять где ошибка.

Вот кусок кода с подробными комментариями:
Код AS3:
// в одном методе идет и проверка на столкновения и перемещение объекта. У каждой окружности есть такой метод
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;
}

Старый 11.06.2012, 20:35
-De- вне форума Посмотреть профиль Отправить личное сообщение для -De- Найти все сообщения от -De-
  № 2  
Ответить с цитированием
-De-
 
Аватар для -De-

блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
Отправить сообщение для -De- с помощью ICQ Отправить сообщение для -De- с помощью Skype™
Ну он начинает двигаться, а его начинают возвращать) Возможно, человек у вас постоянно в начале списка, потому сперва всегда его возвращают на место и поможет его перекинуть в конец списка (а если в конце, то наоборот =).
А вообще задача сложная и, в общем, точно не решается. Этим занимается solver физ. движков. Потому тут наверное лучше просто взять box2d какой-нить.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают.

Старый 11.06.2012, 20:41
ekeeper вне форума Посмотреть профиль Отправить личное сообщение для ekeeper Найти все сообщения от ekeeper
  № 3  
Ответить с цитированием
ekeeper

Регистрация: May 2008
Сообщений: 102
Box2d тут очень тормозит, я пробовал. Игрок апдейтится последним.
Цитата:
Сообщение от -De- Посмотреть сообщение
Ну он начинает двигаться, а его начинают возвращать) Возможно, человек у вас постоянно в начале списка, потому сперва всегда его возвращают на место и поможет его перекинуть в конец списка (а если в конце, то наоборот =).
А вообще задача сложная и, в общем, точно не решается. Этим занимается solver физ. движков. Потому тут наверное лучше просто взять box2d какой-нить.

Старый 11.06.2012, 21:08
-De- вне форума Посмотреть профиль Отправить личное сообщение для -De- Найти все сообщения от -De-
  № 4  
Ответить с цитированием
-De-
 
Аватар для -De-

блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
Отправить сообщение для -De- с помощью ICQ Отправить сообщение для -De- с помощью Skype™
А если его таки попробовать первым апдейтить? Вообще поигрался - довольно забавно =)
Только меня больше смутило, что малейшее касание зомба очень сильно стопит. А смещение при облеплении - не заметил бы даже. И когда он облеплен, то по идее он и так быстро сдохнет, не думаю, что игрок заметит то смещение, оно очень медленно ползет. Я бы предложил вместо того, чтобы бить на 4 части отрезок, на одну отрисовку (т.е. enter frame), 4 раза апдейтить мир (ну соответственно скорости все в 4 раза меньше, как вы делали при помощи k и iter ваших).
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают.

Старый 11.06.2012, 21:16
ekeeper вне форума Посмотреть профиль Отправить личное сообщение для ekeeper Найти все сообщения от ekeeper
  № 5  
Ответить с цитированием
ekeeper

Регистрация: May 2008
Сообщений: 102
От логики мира пока сделаны как раз только коллизии. Там ничего другого нет. Я попробую отдельно вытащить метод и протестировать.

Добавлено через 24 часа 51 минуту
Если кому интересно, то буду пробовать вот этот подход - http://www.gamedev.ru/code/articles/...onBasedPhysics

Создать новую тему Ответ Часовой пояс GMT +4, время: 23:27.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 23:27.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.