Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

DoCollision B DelphiX [Delphi, DelphiX, Windows]


Страницы:   1 2 3 4 5 6 7 8 9 10

Аццкий_рыцарь:) ©   (2005-12-29 14:07:00) 

когда спрйт анимируется, то DoCollision происходит только на первом его кадре. А мне нужно что б на всех кадрах происходило колижн ХЕЛП!


antonn   (2006-01-19 11:57:00) [21]

Cash ©   (19.01.06 11:47) [168]
Девятку в p еще на старте запихивают, а сама процедура
рисует еще обин бтмап на p и передают его обратно в девятку.
После чего обновляют текстуру девятки.

мда...
короче в девятку просто смешивают ее саму и еще один битмап?
а нельзя сразу записать в девятку, без копирований еще одного битмапа на Р а потом в девятку?


Cash   (2006-01-19 11:47:00) [22]

antonn ©   (19.01.06 11:36) [167]:
Не учили тебя в детстве читать все посты до конца! :D :D :D
DXImageList - это типа хранилище картинок.
А выводить какраз надо на девятый индекс!
Девятку в p еще на старте запихивают, а сама процедура
рисует еще обин бтмап на p и передают его обратно в девятку.
После чего обновляют текстуру девятки.


antonn   (2006-01-19 11:36:00) [23]

Аццкий_рыцарь:)   (19.01.06 10:43) [163]
- a:=form1.dxImageList3.Items.Find('mdeadend').Picture.Bitmap;
p.Width := 768;
p.Height := 1024;

матерь божья, у тебя такой здоровый битмап??? а ты на нем еще и draw()...


> -
> a:=form1.dxImageList3.Items.Find('mdeadend').Picture.Bitmap;
>p.Width := 768;
>p.Height := 1024;
>
>- B FormDestroy вставил  
> a.Free;

я бы тоже чего нибудь выдал:)

ты вообще, объясни структуру битмапов, какой для вывода, где хранатся тайлы(я так понял в DXImageList1.Items.Items[]?)


>procedure tform1.DeathDraw;
>var
>r: TGraphic;
>t: TColor;
>b: TRect;
>
>begin
> r :=
>form1.DXImageList1.Items.Items[9].Picture.Graphic;
> t :=
>form1.DXImageList1.Items.Items[9].TransparentColor;
>b := bounds(deadkozelX,deadkozelY,77,77);
>form1.p.Canvas.Brush.Style := bsClear;
>form1.p.Canvas.BrushCopy(b,form1.a,form1.a.Canvas.ClipRect,t);
>r.Assign(form1.p);
>Form1.DXImageList1.Items.Items[9].Restore;
> end;

че то тут не то...

я так понял, тебе нужно выхватить из form1.DXImageList1.Items.Items[9] картинку и скопировать ее с прозрачным цветом на большой битмап. Так? у form1.DXImageList1.Items.Items[9] есть Tbitmap, или только TGraphic?

попробуй переписать DeathDraw:

procedure tform1.DeathDraw;
begin
//на p надо вывести?
CopyTransparentBrush(form1.DXImageList1.Items.Items[9].Picture.bitmap, p,deadkozelX,deadkozelY, form1.DXImageList1.Items.Items[9].TransparentColor);
Form1.DXImageList1.Items.Items[9].Restore;
end;
//только у CopyTransparentBrush в параметрах первый var убери


Cash   (2006-01-19 11:35:00) [24]

Аццкий_рыцарь:)   (19.01.06 09:47) [162]:
... моя машина: ...
Ух-х-х-х-х!
Давненько наверное не грейженая.

Зацени конфиг:
Intel Celeron D360 3.0 GHz (HT+)
ATI x750Pro 128 Md PCI-Ex
1 Gb DDR2 RAM

Тота у меня эти манипуляции с перерисовкой не тормозят! :)))


Cash   (2006-01-19 11:26:00) [25]

Аццкий_рыцарь:)   (19.01.06 10:43) [163]:
... вот насчет носителя ...
Под носителем я понимаю класс, который содержит этот метод или поле.
А вопрос переименоки чисто эстетический! :)

... a:=form1.dxImageList3.Items.Find('mdeadend').Picture.Bitmap; ...
Хм-м, ты же уже создал этот буфер. Зачем тебе его переназначать?
Ты заменишь буфер на бесполезную картинку, которая еще и пустая!
При таком переназначении ты потеряешь ранее созданый объект!
Надо было сделать так:

a.Width := 77;
a.Height := 77;
a.Canvas.Draw(0,0,dxImageList3.Items.Find('mdeadend').Picture.Graphic);

Вроде как этот 'mdeadend' и есть последний кадрик анимации этого монстра?

p.Width := 1024; // ух, сделал бы лучше 800х600, тормоза еще и от этого
p.Height := 768;
p.Canvas.Draw(0,0,dxImageList3.Items.Item[9].Picture.Graphic);


Аццкий_рыцарь:)   (2006-01-19 10:49:00) [26]

MoonLife

насчет примеров...

я полно статей нарыл по DelphiX, но вот про эти проблемы, которые я поднимал в этом топике НИГДЕ НИЧЕГО НЕТ:( если можешь, то вышли вот мыло : iradchenko@bigmir.net


Аццкий_рыцарь:)   (2006-01-19 10:43:00) [27]

Cash

Теперь че-та мертвого монстряка вообще не рисует, а глючит как и раньше :(

вот что я делал :

там где Private формы вставил p,a: TBitMap;

вот насчет носителя Hit... Я че-то непойму, зачем его переименовывать? допустим пускай Hit будет DeathDraw ...

насчет картинки... Я просто  сделал пока что без анимации смерти, все image, которые были с анимацией я просто туда картинку валяющегося монстра вставил.

- вот, что я вставил в FormCreate:
p := TBitMap.Create;
a := TBitMap.Create;

- a:=form1.dxImageList3.Items.Find('mdeadend').Picture.Bitmap;
p.Width := 768;
p.Height := 1024;

- B FormDestroy вставил  
a.Free;
p.Free; (кстати пишет ошибку при закрытии форми Acces violation error, тут закрадываются сомнения, насчет правильности создания мной буферов :) )

-В бывший Hit, теперь DeathDraw вставил:


procedure tform1.DeathDraw;
var
r: TGraphic;
t: TColor;
b: TRect;

begin
r := form1.DXImageList1.Items.Items[9].Picture.Graphic;
t := form1.DXImageList1.Items.Items[9].TransparentColor;
b := bounds(deadkozelX,deadkozelY,77,77);
form1.p.Canvas.Brush.Style := bsClear;
form1.p.Canvas.BrushCopy(b,form1.a,form1.a.Canvas.ClipRect,t);
r.Assign(form1.p);
Form1.DXImageList1.Items.Items[9].Restore;
end;


Аццкий_рыцарь:)   (2006-01-19 09:47:00) [28]


> MonoLife   (19.01.06 06:02) [157]


понимаешь, я игру пишу не для того чтоб повыпендриваться, мол :"я крутой программер". Я пишу чтоб научиться разбираться с проблемами, возникающими при построении игр! Если б я отдельно садился без игры и начал рыть статьи по ДелфиХ, это бы заняло очень много времени. А так я сразу вижу чего плохого есть там, и как это решить :)

> Cash ©   (19.01.06 08:47) [159]


моя машина:

Athlon XP 2200+
Radeon 9600 pro
523 Mb оперативы...

мышка и клава Sven :)

ЭХ!
ща буду пытаться это все воплотить в игруху...


antonn   (2006-01-19 09:36:00) [29]

Cash ©   (19.01.06 8:21) [158]
Он хоть и присуцтвует, а никакой функции не несет!

нужно иметь битмап и работать с пикселами напрямую через scanline, тогда будет скорость (да еще и эффектов, типа прозрачности и черно-белости можно добавить).
кстати, я вот на основе работы со scanline игру на один конкурс писал:
http://an-files.narod.ru/Star_Scroller.rar(1366182 Б)
почти не тормозит на хороших компах;)


>procedure TForm1.DrawKozelDeath(Subj: TKozel);
>var
>r: TGraphic;
>t: TColor;
>b: TRect;
>begin
>r := DXImageList1.Items.Items[9].Picture.Graphic;
>t := Subj.Image.TransparentColor;
>b := bounds(Trunc(Subj.X),Trunc(Subj.Y),77,77);
>p.Canvas.Brush.Style := bsClear;
>p.Canvas.BrushCopy(b,a,a.Canvas.ClipRect,t);
>r.Assign(p);
>Form1.DXImageList1.Items.Items[9].Restore;
> end;

а "напрямую" никак? :) да и вообще, tbitmap юзай


> p.Canvas.Brush.Style := bsClear;

делается всего один раз - и хватит:)


Cash   (2006-01-19 08:51:00) [30]

А если еще подумать, то можно и еще почикать эту процедурку.

procedure TForm1.DrawKozelDeath(Subj: TKozel);
var
  t: TColor;
  b: TRect;
begin
  t := Subj.Image.TransparentColor;
  b := bounds(Trunc(Subj.X),Trunc(Subj.Y),77,77);
  p.Canvas.Brush.Style := bsClear;
  p.Canvas.BrushCopy(b,a,a.Canvas.ClipRect,t);
  DXImageList1.Items.Items[9]..Assign(p);
  DXImageList1.Items.Items[9].Restore;
end;


Cash   (2006-01-19 08:47:00) [31]

Аццкий_рыцарь:)   (18.01.06 22:57) [155]:
Попробуем!
- Для начала перепиши оба буфера в область Private класса формы.
Думается мне, что все классы у тебя находятся в модуле с самой формой.
- Далее, надо сменить носителя процедуры Hit, измени ее название
(DrawDeath или DeathDraw или ... :)), и перепиши в разряд Public класса
формы.
- Момент 3: надо сделать отдельную картинку последнего кадра смерти
этого монстряка. (самый последний кадр размером 77х77)
- Теперь надо поправить процедурку рисования на бэк-е. (приведу в конце)
- Далее, в событии OnCreate и OnDestroy объяви создание и уничтожение
обоих буферов.
- Еще - в OnCreate в буфер кадра смерти сразу загони уже заготовленное
изображенире последнего кадра, предварительно уточнив его размеры.
- А так же, в OnCreate задай сразу размеры буферу бэк-а и помести
в него картинку.
(И так как при проходе нашей процедуры буферы уже созданы, нам нет
нужды создавать их при каждой необходимости)
- И по дконц - надо переписать вызов нашей процедуры из метода DoMove.

Все! Вроде кой какая оптимизация приведена.

А так я бы переписал эту процедуру:

procedure TForm1.DrawKozelDeath(Subj: TKozel);
var
r: TGraphic;
t: TColor;
b: TRect;
begin
r := DXImageList1.Items.Items[9].Picture.Graphic;
t := Subj.Image.TransparentColor;
b := bounds(Trunc(Subj.X),Trunc(Subj.Y),77,77);
p.Canvas.Brush.Style := bsClear;
p.Canvas.BrushCopy(b,a,a.Canvas.ClipRect,t);
r.Assign(p);
Form1.DXImageList1.Items.Items[9].Restore;
end;


Меньше избыточных операторов - больше скорость!

У тебя кстати какой конфиг машины?


Cash   (2006-01-19 08:21:00) [32]

MonoLife   (19.01.06 06:02) [157]:
... чем отличается ...

Отличия там в то, что Bounds возвращает рамку исходя из положения по
X и Y, а так же ширины и длины, которые задаются ы параметрах.
А Rect отдает рамочку, сформированную левой верхней и правой нижней
точками, так же указанными в параметрах.
Применительно к примеру:
bb := bounds(10,10,32,32);
br := Rect(10,10,32,32);
bb = (10,10,42,42);
br = (10,10,32,32);

antonn ©   (19.01.06 05:17) [156]:
... > r: TGraphic;
бяка... ...

И действительно бяка! Там вся работа с графикой через эту самую бяку
налажено!

Ктати точно! Надо бы эти два буфера создавать в конструкторе и
уничтожать через деструктор самого козла. Блин!!!, ну сколько памяти
тогда надо будет!

... это что за график? там битмап есть? ...
Нет там битмапа! Он хоть и присуцтвует, а никакой функции не несет!


MonoLife   (2006-01-19 06:02:00) [33]

По всей видимости, Аццкий_рыцарь, ты лишаешься претензии на индивидуальность твоей будующией игрухи, так как содержание листинга постепенно становится коллективным! :) >... кайфа никакого
не получишь! ;)[90]

Поражаюсь терпению Cash, нравится ему все раззжевывать :) Респект ессно...
to Аццкий_рыцарь> Без примеров трудновато. Ты поищи где-нить простые примеры и описание, посмотри реализацию того-сего... Если совсем ничего не найдешь, я посмотрю у себя материал и вышлю тебе на мыло, если ты, конечно, мне его дашь :).
Вопрос к Cash:
b: TRect;
чем отличается
b := bounds(10,10,32,32); от
b := Rect(10,10,32,32); :)


antonn   (2006-01-19 05:17:00) [34]

Аццкий_рыцарь:)   (18.01.06 22:51) [154]
все сделал, но всеравно глючит когда сразу несколько монстряков умирает :(

а ты побольше используй Canvas.Draw:)


> Items[9].Picture.Graphic

это что за график? там битмап есть?

p := TBitMap.Create;
a := TBitMap.Create;

>p := TBitMap.Create;
>  a := TBitMap.Create;

объяви эти чуда глобально, создавай только при создании формы(или чего там...), а тут используй. Не надо их каждый раз создавать.


> r: TGraphic;

бяка...


> p.Canvas.Draw(0,0,r);

попробуй заменить на CopyTransparentBrush(r,p,0,0,clred); //clred - цвет прозрачности, какой он там у тебя?
из поста [113], вообще все Canvas.Draw позаменяй


>p.Canvas.Brush.Style := bsClear;
>  p.Canvas.BrushCopy(b,a,a.Canvas.ClipRect,t);

CopyTransparentBrush(a,p,b.left,b.top,t);


Аццкий_рыцарь:)   (2006-01-18 22:57:00) [35]

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


Аццкий_рыцарь:)   (2006-01-18 22:51:00) [36]

все сделал, но всеравно глючит когда сразу несколько монстряков умирает :(


Cash   (2006-01-18 20:56:00) [37]

Бр-р-р-р-р-р-р-р!!!
То,что в Hit направляешь - правилдьно, а вот то, что этот Hit на пустом
месте вызвываешь - это и есть причина твоей тормозни (блин, не твоей,
а твоей проги... во! :) )! 8)

Мне на ум приходит другая реализация:
(Помнишь про IsLive: boolean,? Кажется, что ты ее назвал movego, смотри...)

// здесь я говорю, что этот козел должен сдохнуть, точнее начать дохнуть
procedure Tfireball.DoCollision(Sprite: TSprite; var Done: Boolean);
var
 pos :integer;
begin
 if Sprite is Tkozel then begin
   if ((x+15>sprite.x+40)and(x+15<sprite.x+70))and
      ((y+15>sprite.y+35)and(y+15<sprite.y+80)) then begin
     if tkozel(sprite).movego=true then begin
       frags:=frags+1;
       dead;
       tkozel(sprite).DoDie;
     end;
   end;
 end;
end;
// это - метод козла, как умирать.
// Про DeathImage и LiveImage я тоже говорил уже,
// Сделай эти два поля в классе козла и засунь в них
// картинки мертвого и живого монстряка соответственно.
Procedure TKozel.DoDie;
begin
 Z := 1;
 Image := DeathImage;
 AnimPos:=0;
 AnimCount := Image.PatternCount;
 AnimLooped := false;
 AnimSpeed := 15/1000;
 movego:=false;  
end;
// Типа скорая реанимационная помощь! :)
Procedure TKozel.Reanimate;
begin
 Image := LiveImage;
 AnimPos:=0;
 AnimCount := Image.PatternCount;
 AnimLooped := true;
 AnimSpeed := 15/1000;
 movego:=true;
end;
// Вот так я бы сделал процедурку перемещения монстра.
Procedure TKozel.DoMove(MoveCount: Integer);
begin
 inherited DoMove(MoveCount);
 if movego then begin
   // Здесь стандартное живое состояние монстряка, сюда же
   // я бы всавил Collision, а впрочем вот, прямо щас и вставлю!
   Collision;
 end else begin
   // а здесь обработка его подыхания. Дохнет он дохнет... и под конец
   // берет и оставляет о себе память в виде фотки на бэкграунде. :)))
   if AnimPos >= (AnimCount-1) then begin
     Hit;
     Visible := false;
   end;
 end;
end;

// а теперь и сама Hit!
procedure Tkozel.hit;
var
 p,a: TBitMap;
 r: TGraphic;
 t: TColor;
 b: TRect;
begin
 p := TBitMap.Create;
 a := TBitMap.Create;
 r := Form1.DXImageList1.Items.Items[9].Picture.Graphic;
 p.Width := r.Width;
 p.Height := r.Height;
 p.Canvas.Draw(0,0,r);
 with a do begin
 // при вызове Hit мы на все 100% уверены, что текущая картинка у
 // монстряка - DeathImage, а подругому при текущем раскладе не
 // получится! Поэтому далеко не ходя берем инфу прямо из поля Image
   Width := Image.Picture.Graphic.Width;
   Height := Image.Picture.Graphic.Height;
   Canvas.Draw(0,0,Image.Picture.Graphic); // Ну это типа мы рисуем, это ясно.
   // А вот здесь по моим предположениям должно происходить
   // нахождение последниго кадра смерти. Я это только теоретически
   // просчитал, должно выводить правильно.
   Canvas.CopyRect(Bounds(0,0,77,77),a.Canvas,Bounds((AnimCount-1)*77,0,77,77));
   // А-а-а-а-а... это самое то! Надо же правильные размеры уточнить,
   // а не то тормоза будут не в квадрате, а в кубе!!!
   Width := 77;
   Height := 77;
 end;
 t := Image.TransparentColor;
 // лишние переменные скорости не добавят! я убрал две самые не нужные!
 // Round и Trunc очень похожи, только последняя округляет
 // в меньшую сторону, мне просто так нравится болше.
 b := bounds(Trunc(X),Trunc(Y),77,77);
 p.Canvas.Brush.Style := bsClear;
 p.Canvas.BrushCopy(b,a,a.Canvas.ClipRect,t);
 r.Assign(p);
 Form1.DXImageList1.Items.Items[9].Restore;
 a.Free;
 p.Free;
end;


Аццкий_рыцарь:)   (2006-01-18 19:21:00) [38]


// типа, это процедура когда монстр получает повреждения
procedure Tkozel.hit;
var
p,a: TBitMap;
r: TGraphic;
t: TColor;
b: TRect;
xpos,ypos: integer;
begin

xpos:=round(x);
ypos:=round(y);

 AnimCount := Image.PatternCount;
       AnimLooped := false;              
       AnimSpeed := 15 / 1000;
   z:=1 ;
Image := form1.dxImageList3.Items.Find('mdead');
if movego=true then
begin

p := TBitMap.Create;
a := TBitMap.Create;
r := form1.DXImageList1.Items.Items[9].Picture.Graphic;
p.Width := r.Width;
p.Height := r.Height;
p.Canvas.Draw(0,0,r);
with a do begin
  Width := form1.DXImageList3.Items.Items[9].Picture.Graphic.Width;
  Height := form1.DXImageList3.Items.Items[9].Picture.Graphic.Height;
  Canvas.Draw(0,0,form1.DXImageList3.Items.Items[9].Picture.Graphic);
end;

t := form1.DXImageList3.Items.Items[9].TransparentColor;
 b := bounds(xpos,ypos,77,77);

with p.Canvas do begin
  Brush.Style := bsClear;
end;
 p.Canvas.BrushCopy(b,a,a.Canvas.ClipRect,t);
r.Assign(p);
 form1.DXImageList1.Items.Items[9].Restore;

a.Free;
p.Free;

x:=-50000;
y:=-50000;

animlooped:=true;
movego:=true;
end;

 end;

ну, а это, когда  файрбол сталкивается с монстром

procedure Tfireball.DoCollision(Sprite: TSprite; var Done: Boolean);

 var pos :integer;
 begin
  if Sprite is Tkozel then   // see's if what the bullet collided with was an enemy
   begin

   if (x+15>sprite.x+40)and (x+15<sprite.x+70) then
   begin
      if (y+15>sprite.y+35) and (y+15<sprite.y+80) then
   begin

     if tkozel(sprite).movego= true then
     begin
     frags:=frags+1;
      dead;
     end;
   
   tkozel(sprite).hit;

   end;
   end;



кстати, kozel - это монстряк :) я сначала для монстра брал какого-то козерога из диаблы :)


Cash   (2006-01-18 18:29:00) [39]

Аццкий_рыцарь:)   (18.01.06 14:31) [150]:
Покажи, место, где обрабатывается анимация смерти и еще - где
осуществляется вызов процедурки этой.


Аццкий_рыцарь:)   (2006-01-18 14:31:00) [40]

Вот блин. Я когда поставил в игру, то при убийстве монстра все замедляется, а потом снова идет как и шло нормально :( Что тут можно сделать?


Страницы:   1 2 3 4 5 6 7 8 9 10

Наверх

Титульная страница Поиск, карта сайта Написать письмо