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

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

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

Регистрация: Oct 2013
Сообщений: 23
Question Физика движения и столкновений

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

Сам алгоритм движения и проверки столкновений на данный момент таков(двигается не сам автомобиль, а фон):
Код AS3:
public function Movement(event:Event):void{
			var pos_x,pos_y:int;
			var fpn,bpn,rpn,lpn:int; //Счетчики точек отталкивания
 
			if ((Up == true) && (speed >=(-maxspeed))){speed -= power;} //Если нажата кнопка вперед 
			if ((Down == true) && (speed <=(maxspeed/5))) {speed += power;	}//Если нажата кнопка назад
			if ((Left == true) && (Math.abs(speed) >=1 ))  //Если нажата кнопка влево
				if (speed<0) car_test.rotation -= angle
				else if (speed>0) car_test.rotation += angle;
			if ((Right == true) && (Math.abs(speed) >=1 )) //Если нажата кнопка вправо
				if (speed<0) car_test.rotation += angle
				else if (speed>0) car_test.rotation -= angle;
			/*Проверка передних точек*/
			for (fpn=0;fpn<3;fpn++){
				var _forward:Point = new Point(car_test['fp'+fpn].x,car_test['fp'+fpn].y);
				var _forwardG:Point = new Point();
				_forwardG  = car_test.localToGlobal(_forward);
				if (map_c.wall.hitTestPoint(_forwardG.x,_forwardG.y,true)){
					if (Math.abs(speed)<5) speed *= (-1)
					else {
						speed = (speed/2)*(-1);
						trace('/4');
					}
					break;
				}
			}
			/*Проверка задних точек*/
			for (bpn=0;bpn<3;bpn++){
				var _back:Point = new Point(car_test['bp'+bpn].x,car_test['bp'+bpn].y);
				var _backG:Point = new Point();
				_backG  = car_test.localToGlobal(_back);
				if (map_c.wall.hitTestPoint(_backG.x,_backG.y,true)){
					if (Math.abs(speed)<5) speed *= (-1)
					else {
						speed = (speed/2)*(-1);
					}
					break;
				}	
			}
			/*Проверка точек справа*/
			for (rpn=0;rpn<3;rpn++){
				var _turnR:Point = new Point(car_test['rp'+rpn].x,car_test['rp'+rpn].y);
				var _turnRG:Point = new Point();
				_turnRG  = car_test.localToGlobal(_turnR);
				if (map_c.wall.hitTestPoint(_turnRG.x,_turnRG.y,true)){
					if ((speed<0) && (Math.abs(speed)>1)) car_test.rotation -= angle*2;
					else if (speed>0) car_test.rotation += angle*2;
					break;
				}			
			}
			/*Проверка точек слева*/
			for (lpn=0;lpn<3;lpn++){
				var _turnL:Point = new Point(car_test['lp'+lpn].x,car_test['lp'+lpn].y);
				var _turnLG:Point = new Point();
				_turnLG  = car_test.localToGlobal(_turnL);
				if (map_c.wall.hitTestPoint(_turnLG.x,_turnLG.y,true)){
					if ((speed<0) && (Math.abs(speed)>1)) car_test.rotation += angle*2;
					else if ((speed>0) && (Math.abs(speed)>1)) car_test.rotation -= angle*2;
					break;
				}			
			}
			speed *= friction;//Добавление трения
			/*Нахождение следующей точки положения автомобиля*/
			pos_x = speed*Math.cos(car_test.rotation * Math.PI/180); 
			pos_y = speed*Math.sin(car_test.rotation * Math.PI/180);
 
			map_c.x -= pos_x;
 			map_c.y -= pos_y;
 
			map_s.x -= pos_x;
 			map_s.y -= pos_y;
 
			map_p.x -= pos_x;
 			map_p.y -= pos_y;
 
		}
Проблема в том, что как я не переставлял точки проверки столкновений, и как не правил значения переменных, всё-равно удается воспроизвести ошибку "застревания в непроходимый объектах".

Проблема явно случается при одновременном соприкосновении торцовой и боковой точки с непроходимым объектом.
Подскажите как можно было бы с этим бороться.
PS: Игра достаточно проста, чтобы не использовать продвинутые физ. движки.

Старый 02.02.2014, 11:24
Hauts вне форума Посмотреть профиль Отправить личное сообщение для Hauts Посетить домашнюю страницу Hauts Найти все сообщения от Hauts
  № 2  
Ответить с цитированием
Hauts
 
Аватар для Hauts

блогер
Регистрация: Feb 2008
Адрес: Россия, Новосибирск, Академгородок
Сообщений: 2,113
Записей в блоге: 1
Отправить сообщение для Hauts с помощью ICQ Отправить сообщение для Hauts с помощью Skype™
На каждую итерацию "физики" сдвигайте положение машинки в цикле на 1 пиксель и проверяйте.

Код ужасен.
__________________
hauts.ru

Старый 02.02.2014, 11:58
Всеволод вне форума Посмотреть профиль Отправить личное сообщение для Всеволод Найти все сообщения от Всеволод
  № 3  
Ответить с цитированием
Всеволод
 
Аватар для Всеволод

Регистрация: Oct 2013
Сообщений: 23
Цитата:
Сообщение от Hauts Посмотреть сообщение
На каждую итерацию "физики" сдвигайте положение машинки в цикле на 1 пиксель и проверяйте.
Вы имеете в виду, проблема в том, что положение точек является числом с плавающей точкой?

Старый 02.02.2014, 13:44
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 4  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Вы машину передвигаете на большие расстоянии, вот Вам и посоветовали передвигать по одному пикселю.
Или ещё можно находить вектор и выталкивать машину по нему.

Старый 02.02.2014, 14:59
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 5  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Вы машину передвигаете на большие расстоянии, вот Вам и посоветовали передвигать по одному пикселю.
Оо с чего бы это? То есть, по вашему, скорость всегда должна быть равна 1 пикселю?
Просто проверять столкнется ли машина с чем-то, нужно еще до, того как происходит смещение. То есть, образно говоря:
Код AS3:
если (машина.х + скорость < положениеПрепятствия) {
   машина.х += скорость.
}
Автору: как уже верно подметили, код ужасен. Но так как вы новичок, не буду сильно углубляться в исправления, скажу только, что
названия переменных и функций всегда пишутся с маленькой буквы, а названия классов с большой. У вас же тут вообще каша. Часть переменных с большой, часть с маленькой, часть с нижнего подчеркивания.
Чтобы себе голову не захламлять неправильными концепциями, очень советую ознакомиться с конвенциями написания кода на ас3, и писать строго в соответствии с ними.

Старый 02.02.2014, 15:10
Zebestov вне форума Посмотреть профиль Отправить личное сообщение для Zebestov Посетить домашнюю страницу Zebestov Найти все сообщения от Zebestov
  № 6  
Ответить с цитированием
Zebestov
Lorem ipsum
 
Аватар для Zebestov

модератор форума
Регистрация: May 2001
Адрес: Одесса
Сообщений: 4,869
Записей в блоге: 4
Автору настоятельно рекомендую срочно прекратить изобретение велосипеда, взять в разработку Nape и начать таки делать игру.
__________________
Поймай яблоко 2!

Старый 02.02.2014, 15:11
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 7  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Цитата:
Оо с чего бы это? То есть, по вашему, скорость всегда должна быть равна 1 пикселю?
Тогда мне кажется лучше будет сделать вот так, чем проверять на меньше<препятствие, ведь препятствие может быть любой формы, а это ещё добавит рассчетов в разы. А в move косинс - синус умноженное на 1 и hitTest.
Код AS3:
private function stage_enterFrame(event:Event):void 
{
	for (var i:int = 0; i < _speed; i++) 
	{
		this.move();
	}
}
Хотя наверное лучше будет, как Вы сказали, добавлять в HitTestPoint... Но машина же под углом заходит, а значит нужно вектор высчитывать..
А ещё может не плюс надо, а минус, в зависимости от стороны..
Лучше Nape

Старый 02.02.2014, 16:34
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 8  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Тогда мне кажется лучше будет сделать вот так, чем проверять на меньше<препятствие, ведь препятствие может быть любой формы, а это ещё добавит рассчетов в разы. А в move косинс - синус умноженное на 1 и hitTest.
Это был псевдокод, без учета каких-либо форм. Чисто чтобы показать, что столкновение проверяется еще до перемещения. Когда ведешь реальную машину, ты же не ждешь пока въедешь в столб, чтобы убедиться, что столкновение со столбом действительно произойдет, если продолжить движение, а вместо этого смотришь глазами на столб, и оцениваешь расстояние и скорость. И если столкновение предвидится, начинаешь заблаговременно тормозить.
Цитата:
Лучше Nape
Он лучше только в том случае, если разрабатываешь реальный проект, в котором главное - решить задачу.
А в целях обучения, я бы советовал все-таки самому понаступать на разные грабли, и поизобретать велосипеды. А нейп, бокс2д и тому подобное, оставить на потом.

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

Теги
hitTestPoint , алгоритмы , физика

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

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


 


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


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