Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.06.2015, 09:11   #1
DLev2
Пользователь
 
Регистрация: 26.09.2009
Сообщений: 22
По умолчанию Сталкивание объектов (много)

Пишу игру, и мне нужно узнать наложился ли shape1 на shape2, если быть точным, то наложился ли shape1 на любой другой shape, а их у меня порядка 10тысяч.
10 тысяч шейпов = 9МБ памяти оперативы, в принципе мало. но вот так обработать столкновение?
в частности, мне нужно "игроком" поглотить "бусинки". Помимо этого игроков может быть несколько.
есть у кого нибудь какие нибудь соображения на этот счет?

может есть такой метод "задел", а дальше уже по формулам площадей посчитать процент покрытия "съел или не съел". Спрашиваю, потому что помню когда то давно в логомирах был такой метод.
заранее спасибо, если есть какие-то дельные соображения, пожалуйста напишите в скайпе dolgushinlev или вичате, вичат такой же.
DLev2 вне форума Ответить с цитированием
Старый 28.06.2015, 13:03   #2
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Можно столкновение по областям объектов проверять

Проверка пересечений 2х областей объектов если true то объекты столкнулись эту функцию в любом месте проверки в игре применяешь. Это самый простой способ, с областями надеюсь знакомы. Каждый объект имеет область или же состоит из множества областей, вот их то и задаешь для объекта. Я этот код для своей игре применял.
Код:
function CheckCollision(r, r2: TRect): boolean;
begin
result := (r.Top >= r2.Top) and (r.Top <= r2.Bottom) and
(r.Left >= r2.Left) and (r.Left <= r2.Right) or
(r.Top >= r2.Top) and (r.Top <= r2.Bottom) and
(r.Right >= r2.Left) and (r.Right <= r2.Right) or
(r.Bottom >= r2.Top) and (r.Bottom <= r2.Bottom) and
(r.Left >= r2.Left) and (r.Left <= r2.Right) or
(r.Bottom >= r2.Top) and (r.Bottom <= r2.Bottom) and
(r.Right >= r2.Left) and (r.Right <= r2.Right);
end;
В вашем случае проверку можно делать так
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
//Используем нашу функцию
if CheckCollision(Shape1.BoundsRect, Shape2.BoundsRect) then
Showmessage('Столкнулись');
end;
Если у вас много объектов то каждый нужно проверять в потоке так быстрее и не будет заторможенности игры

Код:
//Проверка множества столкновений Shape можете в таймере попробовать но если много объектов то код желательно в потоке применять
var
i, a: integer;
begin
for i:= 0 to ComponentCount -1 do
for a:= i + 1 to ComponentCount -1 do
if ('TShape' = Components[I].ClassName) and ('TShape' = Components[a].ClassName)and
CheckCollision((Components[I] as TShape).BoundsRect , (Components[a] as TShape).BoundsRect) then
Showmessage('Столкнулись' + (Components[I] as TShape).Name + #32 + (Components[a] as TShape).Name);
end;
если все же нужно в потоке проверку делать то могу код написать.

Последний раз редактировалось Aliens_wolfs; 28.06.2015 в 21:25.
Aliens_wolfs вне форума Ответить с цитированием
Старый 28.06.2015, 14:20   #3
DLev2
Пользователь
 
Регистрация: 26.09.2009
Сообщений: 22
По умолчанию

т.е. по факту все равно перебор по всем возможным объектам выходит. придется делить карту на сектора дабы уменьшить количество переборов.
спасибо за совет, если сработает ClientRect то будет гораздо проще чем сверять по координатам. А вот интересно, метод ClientRect работает быстрее чем сверить по 4 точкам?
дабы ускорить процесс, и не загружать клиент, можно с начало сверить так, а при "столкновении" проверять на % поглощения.
DLev2 вне форума Ответить с цитированием
Старый 28.06.2015, 14:55   #4
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Вернее пробуй BoundsRect это и есть 4 точки региона объекта это квадрат, а ClipRect это помойму к общему региону привязка. Если у тебя сложные объекты тогда нужно систему координат применять но это сложнее.
По типу объекта можно проверять на % поглощение, тип объекта можно в Tag объекта хранить, но это простой способ. Например

Задаем в начале тип объектов
Код:
Const
Object_Player = $00002221;
Object_Wragi= $00002222;
Затем задаем объектам этот тип
Код:
Share1.tag:= Object_Player;
Share2.tag:= Object_Wragi;
При столкновении ты их проверяешь на тип в том коде что я написал и можешь что то с ними делать.

Код:
for i:= 0 to ComponentCount -1 do
for a:= i + 1 to ComponentCount -1  do
if ('TShape' = Components[I].ClassName) and ('TShape' = Components[a].ClassName)and
CheckCollision((Components[I] as TShape).BoundsRect , (Components[a] as TShape).BoundsRect ) then
if (Components[I] as TShape).Tag = Object_Player) and (Components[I] as TShape).Tag = Object_Wragi) then
Что то сделать с объектами
А если хочешь много значений делать для объектов например звук и т.д. тогда нужно создавать класс того же Shape только со своими параметрами и в них нужные значения делать, а потом сверять.


Либо в Tag можно хранить указатель на нужный буфер с нужными значениями например

Код:
  //Структура объекта
Type
  PShapeStruct = ^TShapeStruct;
  TShapeStruct = record
  TypeObj: Integer;
  HSoundBass: DWORD;
  Weapon: Integer;
  Texture: TBitmap;
  end;
Код:
 //Выделяем память для структуры объекта
var
P: PShapeStruct;
begin
New(P);
//Задаем указатель созданной структуры объекту
Shape1.Tag:= Dword(P);
//Обращение к структуре объекта через tag компонета
PShapeStruct(Shape1.Tag)^.TypeObj:= Object_Player;
PShapeStruct(Shape1.Tag).HSoundBass:= хендел звука созданного в Bass
PShapeStruct(Shape1.Tag).Weapon:= количество либо тип оружия
//Можно еще Задать текстуру
PShapeStruct(Shape1.Tag).Texture= TBitmap.Create; 
... и так для всех
Уничтожение
Код:
PShapeStruct(Shape1.Tag).Texture.free;
Dispose(PShapeStruct(Shape1.Tag));
Shape1.Tag:= 0;
Проверка по параметрам

Код:
for i:= 0 to ComponentCount -1 do
for a:= i + 1 to ComponentCount -1  do
if ('TShape' = Components[I].ClassName) and ('TShape' = Components[a].ClassName)and
CheckCollision((Components[I] as TShape).BoundsRect , (Components[a] as TShape).BoundsRect) and
((Components[I] as TShape).Tag > 0) and ((Components[a] as TShape).Tag > 0) then
if PShapeStruct((Components[I] as TShape).Tag).TypeObj = Object_Player) and 
PShapeStruct((Components[I] as TShape).Tag).TypeObj = Object_Wragi) then
Что то сделать с объектами

Последний раз редактировалось Aliens_wolfs; 28.06.2015 в 21:20.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C# сталкивание объектов MyXa C# (си шарп) 2 03.11.2012 00:05
Сталкивание Image SnJon Общие вопросы Delphi 4 29.12.2011 11:29
DelphiX не сталкивание объектов Virus191288 Gamedev - cоздание игр: Unity, OpenGL, DirectX 16 04.02.2010 16:29
Много объектов. Манжосов Денис :) Общие вопросы Delphi 5 04.09.2008 22:34