![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DoCollision B DelphiX [Delphi, DelphiX, Windows]
Аццкий_рыцарь:) © (2005-12-29 14:07:00)
Страницы: < 1 2 3 4 5 6 7 8 9 10 >
когда спрйт анимируется, то 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]Вот блин. Я когда поставил в игру, то при убийстве монстра все замедляется, а потом снова идет как и шло нормально :( Что тут можно сделать?