Пятница, 29.03.2024, 10:15
Приветствую Вас Гость
Главная | Снова о коллизиях... - Форум | Регистрация | Вход
Меню сайта
Наш опрос
А вы пойдете на выборы?
1. Пошел бы, но я не совершеннолетний
2. Да
3. Нет
4. Да, я хочу сделать жизнь лучше
5. Нет, мой голос ни на что не повлияет
6. Нет, я не совершеннолетний
Всего ответов: 13
Форма входа
Друзья сайта
Статистика
Форум
[ Новые сообщения · Участники · Правила форума · Поиск ]
  • Страница 1 из 1
  • 1
Форум » Программирование » BlitzMax » Снова о коллизиях... (О скорости, способах и реализации)
Снова о коллизиях...
Ize_g0reDate: Четверг, 02.08.2007, 22:44 | Message # 1
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
Интересует вот что: насколько сильно тормозят попиксельные коллизии? Если объектов, скажем так, не мало?

Второй пункт:
Линейные коллизии. Казалось бы, что может быть проще - коллизии с линией? Ан нет. Мне пришлось написать весьма хитрую функцию для линейных коллизий. Завтра вы ее увидите во всей ее ужасающей красе [:

Пункт третий:
Коллизии с динамичным контуром. В принципе, я представляю себе как это реализовать через сферовые коллизии, но вопрос с динамикой не решается - нужно заставить сферы повторять движения анимированного рисунка. Если подскажите идею - буду рад!


Ize'g0re's game lab
Return=CurrentPhase(Ize'g0re)
Read Returned. . .
/Work in Progress
 
JohnKDate: Пятница, 03.08.2007, 06:28 | Message # 2
EA FAN
Группа: Администраторы
Сообщений: 408
Статус: Offline
1. Они тормозят прямо пропорционально размеру картинки. Если проверят на коллизии объекты, что в кадре, то тормозов быть не должно, думаю.
2. Линейные коллизии, на мой взгляд, самые быстрые, вот только их надо написать smile
3. Не совсем понял. Если наподобие ландшафта в Worms'ах, то это можно реализовать так:
Взрыв - окружность, и если взрыв охватывает ландшафт, то с ландшафта удаляются все пиксели, что сколлизились со взрывом.



 
Ize_g0reDate: Пятница, 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
 
JohnKDate: Пятница, 03.08.2007, 12:16 | Message # 4
EA FAN
Группа: Администраторы
Сообщений: 408
Статус: Offline
Спасибо! smile


 
dimanche13Date: Пятница, 03.08.2007, 12:30 | Message # 5
Рядовой
Группа: Пользователи
Сообщений: 16
Статус: Offline
Думаю,если в сцене много объектов, то сначала надо проверить колиззии их, так называемых bound_boxes, то есть прямоугольников, в которые вписаны ваши картинки, сделать что-то типа rectoverlap. А уже потом , если есть коллизия прямоугольников - применять попиксельную коллизию. А насчет линии,думаю зачем изобретать - нарисовать картинку "линия" , отскалить как надо, повернуть - и далее коллизия с картинкой... ИМХО.
 
Ize_g0reDate: Пятница, 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
 
ArchiXDate: Пятница, 03.08.2007, 13:39 | Message # 7
Рядовой
Группа: Пользователи
Сообщений: 49
Статус: Offline
На ГД обсуждалось подобное. Погугли.

Уважение - вот мое кредо.
 
dimanche13Date: Суббота, 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)
Всмотритесь в мой код, полагаю, и "на глаз" видно, что он будет быстрее

ну на глаз трудно определить wink раньше писал программы для микроконтроллеров,там каждая миллисекунда на счету, вот там скорость нужна, а современные процы многое проглотят и даже не подавятся.
С уважением.
 
Ize_g0reDate: Суббота, 04.08.2007, 22:46 | Message # 9
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
Передача списка линий в функцию для моего проекта - необходимость, поскольку я намерен использовать несколько списков для различных линий - один для верхней, второй - для нижней...

В любом случае, даже мизерная экономия ресурсов оправдана - я делаю проект не для суперкомпьютеров, а для хиленьких офисных машин.

Кстати, функция уже изрядно полегчала, завтра выложу обновлённый вариант.


Ize'g0re's game lab
Return=CurrentPhase(Ize'g0re)
Read Returned. . .
/Work in Progress
 
dimanche13Date: Суббота, 04.08.2007, 23:01 | Message # 10
Рядовой
Группа: Пользователи
Сообщений: 16
Статус: Offline
Quote (Ize_g0re)
поскольку я намерен использовать несколько списков для различных линий - один для верхней, второй - для нижней
не пойму ,чтоже мешает сделать эти списки глобальными? или к примеру ввести один тип Линия и унаследовать Верхняя и Нижняя. Или не так, что за игра-то? идею не пойму
 
JohnKDate: Воскресенье, 05.08.2007, 11:30 | Message # 11
EA FAN
Группа: Администраторы
Сообщений: 408
Статус: Offline
Quote
ввести один тип Линия и унаследовать Верхняя и Нижняя.
А еще лучше - сделать его абстрактным. smile



 
Ize_g0reDate: Воскресенье, 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
 
ArchiXDate: Воскресенье, 19.08.2007, 10:26 | Message # 13
Рядовой
Группа: Пользователи
Сообщений: 49
Статус: Offline
Ize_g0re, респект.

Уважение - вот мое кредо.
 
Ize_g0reDate: Воскресенье, 19.08.2007, 22:20 | Message # 14
Рядовой
Группа: Пользователи
Сообщений: 24
Статус: Offline
спасибо, я старался. работы в общем-то немного, никакой "верхней" математики... но всё равно, кому-нибудь могут понадобится такие коллизии для скроллера, например.

Ize'g0re's game lab
Return=CurrentPhase(Ize'g0re)
Read Returned. . .
/Work in Progress
 
Форум » Программирование » BlitzMax » Снова о коллизиях... (О скорости, способах и реализации)
  • Страница 1 из 1
  • 1
Поиск:
Copyright JohnK© 2024