Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.04.08;
Скачать: CL | DM;

Вниз

TBitmaps   Найти похожие ветки 

 
Nobody_1988   (2006-05-09 01:06) [0]

Люди как проверить столкновения двух Transparament(тру) TBitmap"ов. Ато тупо через TRect прямоугольниками... неточно смотрится... Можно как-нибудь поточечно...  
Тока не надо предлагать всякие DelphiX сы....


 
grouzd[E]v ©   (2006-05-09 01:31) [1]

Попробовать проверить по пикселам? То есть что-то вроде
function Collide(bitmap1, bitmap2 : tbitmap) : boolean;
result := false;
for x := 0 to bitmap1.width do
 for y := 0 to bitmap1.height do
   if (bitmap1.pixels[x, y] <> clBlack) and
      (bitmap2.pixels[x, y] <> clBlack) then
        begin
          result := true;
          exit;
        end;
end;

только перед этим лучше все же проверить на столкновение по сферам а то тормозно будет. А еще можно посмотреть _исходники_ delphix

---
... we are walking on a thin line and you better avoid the risk ...


 
antonn ©   (2006-05-09 06:36) [2]

grouzd[E]v ©   (09.05.06 1:31) [1]
тормозно будет

ну дык canvas.pixels[]...
замени на scanline:)


 
MeF Dei Corvi ©   (2006-05-09 09:31) [3]


> замени на scanline:)

и перепиши код под asm :)


 
grisme ©   (2006-05-09 10:28) [4]

Попробуй хранить несколько точек, описывающих как бы более точный каркас столкновений, чем Рект. Математически пересечение 2х отрезков легко определить. Так что дерзай. Не пойму, нафик КАЖДУЮ точку проверять? :) Удачи


 
antonn ©   (2006-05-09 11:32) [5]

о-па...
function CollisionDvaBitmapa(BT,BTT:Tbitmap; x1,y1,x2,y2:integer):boolean;
const Pixels = MaxInt div SizeOf(TRGBTriple);
type
 PRGBArray = ^TRGBArray;
 TRGBArray = array[0..Pixels-1] of TRGBTriple;
var i,ii,ix,iy:integer; _Re:Trect;
   RowOut,Rowm: PRGBArray; _r,_b,_g:integer;
   B:Tbitmap;
 function maxx(x1,x2:integer):integer;
 begin
 if x1>x2 then result:=x1 else result:=x2;
 end;
 function minn(x1,x2:integer):integer;
 begin
 if x1<x2 then result:=x1 else result:=x2;
 end;
begin
result:=false;
B:=Tbitmap.Create;
try
 B.PixelFormat:=pf24bit;
 _Re.Left:=minn(x1,x2);
 _Re.top:=minn(y1,y2);
 _Re.Right:=maxx(maxx(x1,x2)+bt.Width,maxx(x1,x2)+btt.Width);
 _Re.Bottom:=maxx(maxx(y1,y2)+bt.Height,maxx(y1,y2)+btt.Height);
 B.Width:=_Re.Right-_Re.Left;
 B.Height:=_re.Bottom-_Re.Top;
 for i:=0 to bt.Height-1 do begin
 RowOut:=bt.ScanLine[i];
 Rowm:=  B.ScanLine[i+y1-_Re.top];
   for ii:=0 to bt.Width-1 do
    if not((RowOut[ii].rgbtBlue=0)and(RowOut[ii].rgbtGreen=0)and(RowOut[ii].rgbtRed=255 )) then begin
     Rowm[ii+x1-_Re.Left].rgbtBlue:=Rowm[ii+x1-_Re.Left].rgbtBlue-100;
   end;
  end;
 for i:=0 to btt.Height-1 do begin
 RowOut:=btt.ScanLine[i];
 Rowm:=  B.ScanLine[i+y2-_Re.top];
   for ii:=0 to btt.Width-1 do begin
    if not((RowOut[ii].rgbtBlue=0)and(RowOut[ii].rgbtGreen=0)and(RowOut[ii].rgbtRed=255 )) then
     Rowm[ii+x2-_Re.Left].rgbtBlue:=Rowm[ii+x2-_Re.Left].rgbtBlue-100;
   end;
  end;
 for i:=0 to b.Height-1 do begin
 RowOut:=b.ScanLine[i];
   for ii:=0 to b.Width-1 do begin
    if ((RowOut[ii].rgbtBlue<100)) then
     result:=true;
   end;
  end;
finally
b.Free;
end;
end;


правда страшно? :)
рекомендую, прежде чем ей воспользоваться, сначала проверить пересечение TRect"ов битмапов.


 
antonn ©   (2006-05-09 11:42) [6]

да, забыл инструкцию оставить:)
BT,BTT:Tbitmap; - два битмапа 24х битные
x1,y1 - координаты первого битмапа в пространстве
x2,y2 - координаты второго битмапа в пространстве
"прозрачный" цвет обоих должен быть clred (или переделать строки сравнения в функции).


 
Nobody_1988   (2006-05-09 21:12) [7]

Вообщем ситуация такая:

Грузится из "Tipa_Asteroid.bmp" 1 Transparament TBitmap произвольного размера от 40x40 до 80x80. Второй "Tipa_Space_Ship.bmp"размера 40x40. Астероиды летят сверху вниз... на Типа_Косм. корабль... :). Как лучше тогда проверить столкновения??? (А if все это будет еще и с анимацией)
Может у кого-нибудь имеется ссылка на исходничек с подобной гамой? Написанных без доп библиотек...

фэнкс то олл...


 
grouzd[E]v ©   (2006-05-09 21:19) [8]

Nobody_1988, айда конкурс писать (или ты уже?) http://code.darthman.com/
Я по сферам проверяю

---
... we are walking on a thin line and you better avoid the risk ...


 
Nobody_1988   (2006-05-09 22:49) [9]

Я ещё пока не... всё таки первая гама... и то не факт что будет.... :)


 
Nobody_1988   (2006-05-09 23:24) [10]

Еще кое-чо придумал -

Загрузить изображение в массив точек, вывести только нужные через Pixels[].
Можно легко, точно проверить на столкновение. Двигать только придется каждую точку...
Интересно это сильно глучно будет?


 
grouzd[E]v ©   (2006-05-10 00:10) [11]

Nobody_1988, я тоже туда первую отправил. с треском, кстати, провалилась =)
А что значит "вывести только нужные"? Да и зачем битмап - по сути массив точек, переписывать в другой массив? Не сильно понимаю

---
... we are walking on a thin line and you better avoid the risk ...


 
antonn ©   (2006-05-10 06:47) [12]

Nobody_1988   (09.05.06 21:12) [7]
о-о-о, наш человек, работает с ГДИ:))
вопщем, могу так посоветовать (так делал в предыдущих работах, так делаю и на космосим:))
создается класс, который заведует столкновением астероидов и их отрисовкой.
в классе создаются 2 TList, один хранит указатели на картинки(битмапы), второй указатели на "объекты".
сами "объекты" - это есть астероиды:
type
pAster = ^TAster;
TAster = record
 x,y:double; //коодринаты текущие
 r:double;  //радиус
 w,h: //габариты
 num:integer; //номер картинки
 _F:double; //сила, с которой он долбит по кораблям
end;

pASterB = ^TAsterB;
TAsterB = record
 B:Tbitmap; //картинка, просто картинка:)
end;


таким образом работать будешь с указателем (очень быстрый доступ до нужного объекта) на структуру(гораздо быстрее получится, чем постоянно брать св-ва у TBitmap). К тому же, некоторые астероиды одинаковые "на лицо" - для них можно испольховать одну и ту же картинку, причем в процессе коллизий к самой картинке можно и не притрагиваться:)

так вот, добавляешь картинку (один раз):
procedure TClass.addpic(BT:Tbitmap);
var P:pASterB;
begin
new(P);
p.b:=Tbitmap.create;
p.b.assign(bt);
FlistB.add(p);
end;


добавляешь астероиды:
procedure TClass.addAst(x,y,w,h,f:double; num:integer);
var P:pAster;
begin
new(P);
p.x:=x; p.y:=y; p.w:=w; p.h:=h; p._f:=f; p.num:=num;
p.r:=(p.w+p.h)/2; //ну, примерно так:)
Flist.add(p);
end;


движение астероидов:
procedure TClass.move;
var P:pAster;
begin
for i:=0 to Flist.count-1 do begin
 p:=pAster(Flist.items[i]);
 p.y:=p.y-1.2; //кстати, в структуре астероида можно и скорость индивидуальную прикрутить...
end;
end;


рисуешь астероиды:
procedure TClass.DrawAstt(BT:TBitmap);
var P:pAster; i:integer; PB:pASterB;
begin
for i:=0 to Flist.count-1 do begin
 p:=pAster(Flist.items[i]);
 pb:=pASterB(FlistB.items[p.num]);
BT.canvas.copyrect(rect(trunc(p.x),trunc(p.y),trunc(p.x+p.w),trunc(p.y+p.h)),pb.b.canvas,rect(0,0,trunc(p.w),trunc(p.h)));
end;
end;


коллизии:
procedure TClass.Collision;
var i:integer; P:pAster;
 function GetTrace(x1,y1,x2,y2:double):double;
  begin
   result:=trunc(sqrt(sqr(x1-x2)+sqr(y1-y2)));
  end;
begin
for i:=0 to Flist.count-1 do begin
p:=pAster(Flist.items[i]);
if GetTrace(p.x,p.y,Кораблик.x,Кораблик.y)<=(p.r+Кораблик.радиус) then
Кораблик.бронька:=Кораблик.бронька-p._f; //бабах...
end;
end;


Nobody_1988   (09.05.06 23:24) [10]
вывести только нужные через Pixels[].

ни в коем случае. забудь вообще про canvas.pixels[] и canvas.draw(), они будут тормозить сильнее, нежели canvas.copyrect() и scanline().



Страницы: 1 вся ветка

Текущий архив: 2007.04.08;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.029 c
5-1151004761
Krants
2006-06-22 23:32
2007.04.08
Локальные параметры...


2-1173860965
Cara
2007-03-14 11:29
2007.04.08
Сумма


2-1174405501
Lexa11_2002
2007-03-20 18:45
2007.04.08
Как в DLL добавить формы


2-1174412920
Леонид
2007-03-20 20:48
2007.04.08
Копирование формы


15-1173940554
Alkid
2007-03-15 09:35
2007.04.08
Правила русского языка