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

Вниз

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

 
TButton ©   (2003-08-30 14:45) [0]

что-то я етот SpriteEngine непонимаю... надо чтоб при столкновении спрайт убился, написал следущее:
procedure TBullet.DoCollision(Sprite: TSprite; var Done: boolean);
begin
 Dead;
 Done:=true;
 Collision;
end;
догадываюсь что что-то не правильно, но никак не пойму что... хотя беспокоит меня не столько код, сколько то что он не выполняется, поставил я на него брейкпоинты и так и не дождался брейков... вот... если нужны еще подробности и разъяснения...


 
Карлсон ©   (2003-08-30 17:29) [1]

посмотрите вот тут http://www.gamedev.ru/coding/20532.shtml
там как раз то, что вам нужно :)


 
TButton ©   (2003-08-30 18:17) [2]

посмотрел :/... но не понял... а жаль...
вобщем очень хотелось бы узнать когда вызывается DoCollision нетод спрайта, происходит ли это автоматом или вызов проверки колизий возложен на меня :) о загнул!


 
pavel_k   (2003-08-30 18:50) [3]

Чтобы DoCollision выполнялся надо в DoMove писать:
(...)
Collision;
(...)

В этот момент столкновение и проверяется.


 
TButton ©   (2003-08-30 19:07) [4]

ясно... ща попробуем...
"трудно читать (скудный) хелп на английском, написаный японцем..." (с)


 
Карлсон ©   (2003-08-30 21:13) [5]

все время происходит PixelCheck или как там его - проверяются все спрайты на присутствие столкновения.
если два или более спрайтов сталкиваются, то инициируется Collision.
в DoCollision для нужного спрайта нужно указать проверку для какого спрайта делать.
т.е. есть класс пули.
у него есть DoCollision.
в нем просто нужно написать проверку на столкновение с каким классом осуществлять.

вот объявление класса TPlayerSprite = class(TImageSprite)
  private
   lngpolet:integer;
   oldlngpolet:integer;
 protected
   procedure DoMove(MoveCount: Integer); override;
   //добавляем
   procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
 end;
для DoCollision надо писать override, надеюсь понятно?

а вот что нас интересует(то что нужно было вам написать) procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
 if Sprite is TPlayerFa then Dead;
 Collision;
end;


или че-то не так? :)
все выше описанное - мое понимание проблемы.


 
TButton ©   (2003-08-30 21:36) [6]

сначала я подумал что забыл про оверрайд, но мои подозрения не оправдались. пересмотрев код я не нашел существенных отличий
(procedure TTarget.DoCollision(Sprite: TSprite; var Done: boolean);
begin
 if Sprite is TBullet then
 begin
   points:=points+10;
   Dead;
 end;
 Collision;
end;)

тут в голову мне закралась гениальная мысль: а что если пуля пролетает мишени насквозь (т.е. в пред. кадре она перед мишенью а в следущем - позади нее). постучав по клавишам я заставил пули лететь со скорость 1 пиксель за ход. f9. подхожу к мишени на минимальное расстояние. даю очередь. из плеерспрайта ползут пиксели пуль. и мееедлено-мееедлено проползают по мишени, причем и мишень и пули продолжают на зло мне радоваться жизни. тут я погрузился в полнейшее уныние и решил излить душу на форуме...


 
Карлсон ©   (2003-08-30 21:56) [7]

дааа...
занятный случай :)
а PixelCheck то вообще включен?
и для пуль и для мишени и для игрока?
у меня лично был глюк со стрельбой под углом.
примерно под 45 градусов все пули просто пролетали насквозь через мишень :)
так и не удалось побороть :)


 
TButton ©   (2003-08-30 22:14) [8]

пиксельчек везде включен, хотя мишени ето фиолетово, она квадратная... т.е. прямоугольная...


 
Карлсон ©   (2003-08-30 22:49) [9]

гм.
может вышлете мне код на мыло?
если смогу - посмотрю :)


 
TButton ©   (2003-08-30 23:11) [10]

да запраста :)


 
Карлсон ©   (2003-08-31 00:00) [11]

гы гы гы :)
с вас пиво :) (шучу, я не пью :)

вобщем дело было так.
я тоже сначала долго не мог врубиться, почему же пули убиваются, а мишень не убивается :)
минут 20 смотрел и ничего не мог понять :)
наконец доперло.
дело в том, что когда пуля сталкивается с мишенью и происходит PixelCheck, то первым обрабатывается столкновение пули и мишени. тут же инициализируется убийство пули и она исчезает. а далее PixelCheck"а для мишени просто не происходит и соответственно она не убивается. Видимо это так.

сделав такие вот изменения в коде:

...
var
 Form1: TForm1;
 pl:TPlayerSprite;
 tgt:TTarget;
 points:integer;
...
procedure TBullet.DoCollision(Sprite: TSprite; var Done: boolean);
begin
 if Sprite is TTarget then
   begin
   tgt.Dead;
   points:=points+10;
   Dead;
 end;
end;
...
 tir:=false;
 end;
 tgt:=TTarget.Create(DXSpriteEngine1.Engine);
 with tgt do
 begin
   PixelCheck:=True;
...
procedure TTarget.DoCollision(Sprite: TSprite; var Done: boolean);
begin
 inherited;
 Collision;
 //Done:=true;
end;
...


надеюсь все понятно :)
за абсолютную грамотность написанного не ручаюсь, может можно и проще, но это первое, что пришло в голову %)


 
TButton ©   (2003-08-31 00:59) [12]

блин... не работает:) колизия непроисходит! :) вопрос: почему???


 
Карлсон ©   (2003-08-31 01:31) [13]

так, это не прикол???
что опять не так?
вы весь код заменили, где я указал?
да, я компилировал на UnDelphiX и выдалось несколько эрроров насчет не указанных значений PatternIndex и Alpha. Первые выставил "0", а последние - "255".


 
TButton ©   (2003-08-31 02:50) [14]

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


 
Карлсон ©   (2003-08-31 12:35) [15]

вот код юнита, замените свой на данный:
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 DXClass, ExtCtrls, DXInput, DXSounds, StdCtrls, DXDraws, DXSprite, Math;

type
 TPlayerSprite = class(TImageSprite)
 protected
   amo: integer;    // current ammo
   ang: real;       // direction
   rel: integer;    // reloading progress
   maxamo: integer; // max ammo
   reltime: real;   // reloadin" total
   reloading: integer;
   dorel:boolean;
   early:boolean;
   sound:string;    // shot sound
   canmove:boolean;
   tir:boolean;
   procedure DoMove(MoveCount: integer); override;
 end;

 TBullet = class(TImageSprite)
 protected
   dist,
   ang,
   vel,
   dam:real;
   procedure DoCollision(Sprite: TSprite; var Done:boolean); override;
   procedure DoMove(MoveCount: integer); override;
 public
  //constructor Create(AParent: TSprite); override;
  //destructor Destroy; override;
 end;

 TTarget = class(TImageSprite)
 protected
   procedure DoCollision(Sprite: TSprite; var Done:boolean); override;
   procedure DoMove(MoveCount: integer); override;
 public
 end;

 TForm1 = class(TDXForm)
   DXInput1: TDXInput;
   DXTimer1: TDXTimer;
   DXWaveList1: TDXWaveList;
   DXSound1: TDXSound;
   DXDraw1: TDXDraw;
   DXImageList1: TDXImageList;
   DXSpriteEngine1: TDXSpriteEngine;
   procedure DXTimer1Timer(Sender: TObject; LagCount: Integer);
   procedure FormCreate(Sender: TObject);
   procedure DXDraw1Initialize(Sender: TObject);
   procedure DXDraw1Finalize(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   ang:real;
   rel:integer;
   amo:integer;
   fps:integer;
 end;

var
 Form1: TForm1;
 tgt:TTarget;
 pl:TPlayerSprite;
 points:integer;

implementation

{ TBullet }

{constructor TBullet.Create(AParent: TSprite);
begin
Collision;
end;

destructor TBullet.Destroy;
begin
 inherited Destroy;
end;
}
procedure TBullet.DoCollision(Sprite: TSprite; var Done: boolean);
begin
 Dead;
 tgt.Dead;
end;

procedure TBullet.DoMove(MoveCount: integer);
begin
 inherited DoMove(MoveCount);
 if dist>600 then Dead;
 x:=x+cos(DegToRad(ang))*vel;
 y:=y+sin(DegToRad(ang))*vel;
 dist:=dist+vel;
 Collision;
end;

{TPlayerSprite}
procedure TPlayerSprite.DoMove(MoveCount: integer);
begin
 inherited DoMove(MoveCount);
 // movin" cursor
 ang:=ang+form1.DXInput1.Mouse.X/3;
 if ang>360 then ang:=ang-360;
 if ang<0 then ang:=ang+360;
 form1.caption:=FloatToStr(ang);
 AnimPos:=12-(Round(ang) div 30 mod 12);
 rel:=rel+MoveCount;
 reloading:=reloading+MoveCount;
 // movin" player
 if (isLeft in Form1.DXInput1.States)and canmove then
 begin
   x:=x+cos(DegToRad(360-AnimPos*30-90))*3;
   y:=y+sin(DegToRad(360-AnimPos*30-90))*3;
 end;
 if (isRight in Form1.DXInput1.States)and canmove then
 begin
   x:=x+cos(DegToRad(360-AnimPos*30+90))*3;
   y:=y+sin(DegToRad(360-AnimPos*30+90))*3;
 end;
 if (isUp in Form1.DXInput1.States)and canmove then
 begin
   x:=x+cos(DegToRad(360-AnimPos*30))*3;
   y:=y+sin(DegToRad(360-AnimPos*30))*3;
 end;
 if (isDown in Form1.DXInput1.States)and canmove then
 begin
   x:=x+cos(DegToRad(360-AnimPos*30))*-3;
   y:=y+sin(DegToRad(360-AnimPos*30))*-3;
 end;
 if tir then
   if y<600-image.height then y:=600-image.height;
 // shotin"
 if (isButton1 in Form1.DXInput1.Mouse.States)and(rel>=reltime)and(amo>0) then
 begin
   with TBullet.Create(Engine) do
   begin
     PixelCheck := True;
     Image := form1.dxImageList1.Items.Find("Pula");
     //&#215;&#242;&#238;&#225;&#251; &#239;&#243;&#235;&#255; &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#235;&#224;&#241;&#252; &#238;&#234;&#238;&#235;&#238; &#237;&#224;&#248;&#229;&#227;&#238; &#238;&#225;&#250;&#229;&#234;&#242;&#224;
     X:=Self.X+Self.Width/2{+cos(DegToRad(360-AnimPos*30))*20};
     //&#215;&#242;&#238;&#225;&#251; &#239;&#243;&#235;&#255; &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#235;&#224;&#241;&#252; &#238;&#234;&#238;&#235;&#238; &#237;&#224;&#248;&#229;&#227;&#238; &#238;&#225;&#250;&#229;&#234;&#242;&#224;
     Y:=Self.Y+Self.Height/2{+sin(DegToRad(360-AnimPos*30))*20};
     Width := Image.Width;
     Height := Image.Height;
     ang:=360-Self.AnimPos*30;
     dist:=0;
     vel:=10;
   end;
   Form1.DXWaveList1.Items.Find(sound).Play(false);
   rel:=0;
   reloading:=0;
   dorel:=false;
   Dec(amo);
   early:=true;
   points:=points-1;
   if points<0 then points:=0;
 end
 else
   early:=false;
 // and reloadin"
 if (isButton2 in Form1.DXInput1.Keyboard.States)and not(isButton1 in Form1.DXInput1.Mouse.States)and not dorel and (amo<>maxamo) then
 begin
   reloading:=0;
   dorel:=true;
   Form1.DXWaveList1.Items.Find("relstart").Play(false);
 end;
 if (reloading>=40)and dorel then
 begin
   amo:=maxamo;
   dorel:=false;
   Form1.DXWaveList1.Items.Find("relend").Play(false);
 end;
 Collision;
end;

{$R *.DFM}

procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
 //Caption:=IntToStr(LagCount);
 DXInput1.Update;
 DXSpriteEngine1.Move(LagCount);
 DXSpriteEngine1.Dead;
 DXDraw1.Surface.Fill(0);
 DXSpriteEngine1.Draw;
 DXImageList1.Items.Find("weap").DrawAdd(DXDraw1.Surface,rect(0,0,64,40 ),0,255);

 DXImageList1.Items.Find("digits").DrawAdd(DXDraw1.Surface,rect(0,44,16 ,68),(pl.amo div 100),255);
 DXImageList1.Items.Find("digits").DrawAdd(DXDraw1.Surface,rect(20,44,3 6,68),(pl.amo div 10 mod 10),255);
 DXImageList1.Items.Find("digits").DrawAdd(DXDraw1.Surface,rect(40,44,5 6,68),(pl.amo mod 10),255);

 DXImageList1.Items.Find("digits").DrawAdd(DXDraw1.Surface,rect(744,0,7 60,24),(points div 100),255);
 DXImageList1.Items.Find("digits").DrawAdd(DXDraw1.Surface,rect(764,0,7 80,24),(points div 10 mod 10),255);
 DXImageList1.Items.Find("digits").DrawAdd(DXDraw1.Surface,rect(784,0,8 00,24),(points mod 10),255);

 with DXDraw1.Surface.Canvas do
 begin
 Font.Color:=clLime;
 Brush.Style:=bsClear;
 TextOut(0,0,IntToStr(DXTimer1.FrameRate));
 Release;
 end;

 DXDraw1.Flip;
 if isButton32 in DXInput1.Keyboard.States
   then Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 pl:=TPlayerSprite.Create(DXSpriteEngine1.Engine);
 with pl do
 begin
   PixelCheck:=True;
   Image:=Form1.DXImageList1.Items.Find("Player");
   AnimCount:=Image.PatternCount;
   AnimLooped:=false;
   AnimPos:=0;
   x:=400-image.width div 2;
   y:=600-image.height;
   width:=Image.Width;
   height:=Image.Height;
   ang:=270;
   rel:=0;
   dorel:=true;
   amo:=0;
   reltime:=50/10;
   maxamo:=30;
   sound:="shot";
   canmove:=true;
   tir:=false;
 end;
 tgt:=TTarget.Create(DXSpriteEngine1.Engine);
 with tgt do
 begin
   PixelCheck:=True;
   Image:=Form1.DXImageList1.Items.Find("target");
   x:=400;
   y:=80;
   width:=Image.Width;
   height:=Image.Height;
 end;

 ShowCursor(false);
end;


 
Карлсон ©   (2003-08-31 12:36) [16]


{ TTarget }

procedure TTarget.DoCollision(Sprite: TSprite; var Done: boolean);
begin
end;

procedure TTarget.DoMove(MoveCount: integer);
begin
inherited DoMove(MoveCount);
end;

procedure TForm1.DXDraw1Initialize(Sender: TObject);
begin
DXTimer1.Enabled:=True;
end;

procedure TForm1.DXDraw1Finalize(Sender: TObject);
begin
DXTimer1.Enabled:=False;
end;

end.


у меня работает.
насчет пролета пуль раньше, действительно некоторые пролетают из-за того, что они в разных кадрах.
данный код у меня работает :)
попробуйте, пишите обо всех ошибках и ворнингах.


 
MeF88 ©   (2003-08-31 23:35) [17]

Кстати, я никогда не пользовался DoCollusion. Поэтому таких проблем не возникало...


 
Карлсон ©   (2003-09-01 13:10) [18]

2 MeF88 ©   (31.08.03 23:35) [17]
а какая альтернатива?


 
MeF88 ©   (2003-09-01 18:29) [19]

Да я сам: ручками, ручками по ширине, высоте, координатам...



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

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

Наверх




Память: 0.53 MB
Время: 0.109 c
3-1077476512
kba
2004-02-22 22:01
2004.03.28
Kak s TUPDATESQL da update BLOB


7-1071935855
саша
2003-12-20 18:57
2004.03.28
осциллограф на базе компа


1-1078829136
Q
2004-03-09 13:45
2004.03.28
компонент для работы с dbf


14-1078380197
Rouse_
2004-03-04 09:03
2004.03.28
С Днем Рождения 4 Марта


1-1078845534
Dina
2004-03-09 18:18
2004.03.28
Чем Round отличается от RoundTo ?