Наш опрос |
А вы пойдете на выборы?
1. Пошел бы, но я не совершеннолетний4. Да, я хочу сделать жизнь лучше5. Нет, мой голос ни на что не повлияет6. Нет, я не совершеннолетний
Всего ответов: 13
|
Статистика |
|
|
Форум |
|
Снова о коллизиях...
| |
Ize_g0re | Date: Четверг, 02.08.2007, 22:44 | Message # 1 |
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
| Интересует вот что: насколько сильно тормозят попиксельные коллизии? Если объектов, скажем так, не мало? Второй пункт: Линейные коллизии. Казалось бы, что может быть проще - коллизии с линией? Ан нет. Мне пришлось написать весьма хитрую функцию для линейных коллизий. Завтра вы ее увидите во всей ее ужасающей красе [: Пункт третий: Коллизии с динамичным контуром. В принципе, я представляю себе как это реализовать через сферовые коллизии, но вопрос с динамикой не решается - нужно заставить сферы повторять движения анимированного рисунка. Если подскажите идею - буду рад!
Ize'g0re's game lab Return=CurrentPhase(Ize'g0re) Read Returned. . . /Work in Progress
|
|
| |
JohnK | Date: Пятница, 03.08.2007, 06:28 | Message # 2 |
EA FAN
Группа: Администраторы
Сообщений: 408
Статус: Offline
| 1. Они тормозят прямо пропорционально размеру картинки. Если проверят на коллизии объекты, что в кадре, то тормозов быть не должно, думаю. 2. Линейные коллизии, на мой взгляд, самые быстрые, вот только их надо написать 3. Не совсем понял. Если наподобие ландшафта в Worms'ах, то это можно реализовать так: Взрыв - окружность, и если взрыв охватывает ландшафт, то с ландшафта удаляются все пиксели, что сколлизились со взрывом.
|
|
| |
Ize_g0re | Date: Пятница, 03.08.2007, 12:00 | Message # 3 |
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
| Итак, долгожданные линейные коллизии! Немного теории: Будем делать тип линий. Линии состоят из точек, каждая точка вписана в тип: Code ' Великий супер Стрикт, так ревностно борящийся за чистоту кода. Хорошая команда (: SuperStrict
Global plX:Int ' Позиция игрока по X Global plY:Int ' Позиция игрока по У
' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rem Тип линий. Будет расширятся типами линий коллизии... поля: х и у точки, номер точки и номер списка, в котором находятся все точки этой линии. End Rem Type lines Field x:Int Field y:Int Field N:Int Field listN:Int End Type ' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ' Тип линий коллизии... Type col_lines Extends lines ' Methods . . . End Type ' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Code
' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ' Вот заготовка ф-ции. Входные параметры: координаты игрока, направление движения (вверх/вниз)... ' ...и всё! Остально придётся ручками вытаскивать... А, не, ещё один параметр: список линии. Function Line_collision(pX:Int,pY:Int,pD:Int,LineList:TList) Local l:col_lines ' берём 2 временные переменные Local temp1:Int Local temp2:Int ' Локальные переменные для хранения координат Local tX:Int Local tY:Int Local coef:Float ' Прошариваем список с линией For l=EachIn LineList ' если точка линии за игроком и при этом мы продвинулись дальше от предыдущей точки... If l.x<=pX And l.x>temp1 Then ' То считаем эту точку самой ближайшей к игроку temp1=l.x ' И запоминаем её номер temp2=l.n ElseIf l.x>pX And l.x>temp1 ' Если же точка дальше, чем игрок, даём себе об этом знать... temp2=-temp2 EndIf Next If Sgn(temp2)=-1 Then temp2=Abs(temp2) temp1=0 For l=EachIn LineList If l.N=temp2 Then tX=l.x tY=l.y End If temp1=l.N-1 If temp2=temp1 Then ' вычисляем коэф. проиденности линии игроком temp1=l.x-tX temp2=pX-tX coef=temp1/temp2 ' вычисляем У точки линии, что находится по Х наравне с игроком temp1=l.y-tY temp2=temp1*coef+tY ' Применяем полученную информацию для определения коллизий res=Sgn(pY-temp2) End If Next EndIf End Function ' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Теперь немного пояснений: Я разбил код на 2 части - так его будет проще вшить в вашу игру. Я использовал далеко не самый оптимизированный алгоритм поиска ближайших к игроку точек, так что тут "таки есть над чем работать!" Особо умные приметят, что я не создал ни одного списка. Так и надо, поскольку каждая линия коллизии должна будет находится в своём списке. Самые проницательные узреют, что я определял ближайшие точки по одной лишь координате Х, а значит мой метод придётся сильно усовершенствовать, если вы пожелаете использовать его для сильно ломаных линий, которые иногда отходят и назад относительно прошлой точки.
Ize'g0re's game lab Return=CurrentPhase(Ize'g0re) Read Returned. . . /Work in Progress
|
|
| |
JohnK | Date: Пятница, 03.08.2007, 12:16 | Message # 4 |
EA FAN
Группа: Администраторы
Сообщений: 408
Статус: Offline
| Спасибо!
|
|
| |
dimanche13 | Date: Пятница, 03.08.2007, 12:30 | Message # 5 |
Рядовой
Группа: Пользователи
Сообщений: 16
Статус: Offline
| Думаю,если в сцене много объектов, то сначала надо проверить колиззии их, так называемых bound_boxes, то есть прямоугольников, в которые вписаны ваши картинки, сделать что-то типа rectoverlap. А уже потом , если есть коллизия прямоугольников - применять попиксельную коллизию. А насчет линии,думаю зачем изобретать - нарисовать картинку "линия" , отскалить как надо, повернуть - и далее коллизия с картинкой... ИМХО.
|
|
| |
Ize_g0re | Date: Пятница, 03.08.2007, 13:25 | Message # 6 |
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
| На мой взляд, самодельные линейные коллизии быстрее, ибо: допустим, у меня линия с баунд боксом 500*300 (угла в угол, диагональ) тогда: проверка на коллизии будет производится 500*300=150 000 раз для случая, когда игрок - пиксель. Всмотритесь в мой код, полагаю, и "на глаз" видно, что он будет быстрее
Ize'g0re's game lab Return=CurrentPhase(Ize'g0re) Read Returned. . . /Work in Progress
|
|
| |
ArchiX | Date: Пятница, 03.08.2007, 13:39 | Message # 7 |
Рядовой
Группа: Пользователи
Сообщений: 49
Статус: Offline
| На ГД обсуждалось подобное. Погугли.
Уважение - вот мое кредо.
|
|
| |
dimanche13 | Date: Суббота, 04.08.2007, 20:08 | Message # 8 |
Рядовой
Группа: Пользователи
Сообщений: 16
Статус: Offline
| Quote (Ize_g0re) допустим, у меня линия с баунд боксом 500*300 (угла в угол, диагональ) хорошо, а почему бы не сделать пять линий по 100 или еще меньше, тогда и вычислений будет меньше, если ты понял о чем я. Quote (Ize_g0re) Function Line_collision(pX:Int,pY:Int,pD:Int,LineList:TList) а нужно ли передавать список линий в функцию? может объявить его глобально? Quote (Ize_g0re) Всмотритесь в мой код, полагаю, и "на глаз" видно, что он будет быстрее ну на глаз трудно определить раньше писал программы для микроконтроллеров,там каждая миллисекунда на счету, вот там скорость нужна, а современные процы многое проглотят и даже не подавятся. С уважением.
|
|
| |
Ize_g0re | Date: Суббота, 04.08.2007, 22:46 | Message # 9 |
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
| Передача списка линий в функцию для моего проекта - необходимость, поскольку я намерен использовать несколько списков для различных линий - один для верхней, второй - для нижней... В любом случае, даже мизерная экономия ресурсов оправдана - я делаю проект не для суперкомпьютеров, а для хиленьких офисных машин. Кстати, функция уже изрядно полегчала, завтра выложу обновлённый вариант.
Ize'g0re's game lab Return=CurrentPhase(Ize'g0re) Read Returned. . . /Work in Progress
|
|
| |
dimanche13 | Date: Суббота, 04.08.2007, 23:01 | Message # 10 |
Рядовой
Группа: Пользователи
Сообщений: 16
Статус: Offline
| Quote (Ize_g0re) поскольку я намерен использовать несколько списков для различных линий - один для верхней, второй - для нижней не пойму ,чтоже мешает сделать эти списки глобальными? или к примеру ввести один тип Линия и унаследовать Верхняя и Нижняя. Или не так, что за игра-то? идею не пойму
|
|
| |
JohnK | Date: Воскресенье, 05.08.2007, 11:30 | Message # 11 |
EA FAN
Группа: Администраторы
Сообщений: 408
Статус: Offline
| Quote ввести один тип Линия и унаследовать Верхняя и Нижняя. А еще лучше - сделать его абстрактным.
|
|
| |
Ize_g0re | Date: Воскресенье, 05.08.2007, 18:27 | Message # 12 |
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
| вот обновлённый вариант функции... В принципе, убрать входной параметр "список" легко. Просто мне лично нужно, чтобы было именно так. Code Function Line_collision(pX:Int,pY:Int,pD:Int,LineList:TList) Local l:col_lines ' берём 2 временные переменные Local temp1:Int Local temp2:Int ' Локальные переменные для хранения координат Local tX:Int Local tY:Int Local coef:Float For l=EachIn LineList If l.x<=pX Then tX=l.x tY=l.y temp2=l.n ElseIf l.x>pX temp1=l.N-1 If temp2=temp1 Then ' вычисляем коэф. проиденности линии игроком temp1=l.x-tX temp2=pX-tX coef=temp1/temp2 ' вычисляем У точки линии, что находится по Х наравне с игроком temp1=l.y-tY temp2=temp1*coef+tY ' Применяем полученную информацию для определения коллизий res=Sgn(pY-temp2) EndIf End If Next End Function
Ize'g0re's game lab Return=CurrentPhase(Ize'g0re) Read Returned. . . /Work in Progress
|
|
| |
ArchiX | Date: Воскресенье, 19.08.2007, 10:26 | Message # 13 |
Рядовой
Группа: Пользователи
Сообщений: 49
Статус: Offline
| Ize_g0re, респект.
Уважение - вот мое кредо.
|
|
| |
Ize_g0re | Date: Воскресенье, 19.08.2007, 22:20 | Message # 14 |
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
| спасибо, я старался. работы в общем-то немного, никакой "верхней" математики... но всё равно, кому-нибудь могут понадобится такие коллизии для скроллера, например.
Ize'g0re's game lab Return=CurrentPhase(Ize'g0re) Read Returned. . . /Work in Progress
|
|
| |
|
|