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

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

doCollision [Delphi, Windows]


TButton ©   (2003-08-30 14:45:00) 

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


MeF88   (2003-09-01 18:29:00) [1]

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


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

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


MeF88   (2003-08-31 23:35:00) [3]

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


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


{ 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.


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


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

вот код юнита, замените свой на данный:
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=reltime)and(amo>0) then
 begin
   with TBullet.Create(Engine) do
   begin
     PixelCheck := True;
     Image := form1.dxImageList1.Items.Find('Pula');
     //×òîáû ïóëÿ ñîçäàâàëàñü îêîëî íàøåãî îáúåêòà
     X:=Self.X+Self.Width/2{+cos(DegToRad(360-AnimPos*30))*20};
     //×òîáû ïóëÿ ñîçäàâàëàñü îêîëî íàøåãî îáúåêòà
     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


TButton   (2003-08-31 02:50:00) [6]

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


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

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


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

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


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

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

вобщем дело было так.
я тоже сначала долго не мог врубиться, почему же пули убиваются, а мишень не убивается :)
минут 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-30 23:11:00) [10]

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


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

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


TButton   (2003-08-30 22:14:00) [12]

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


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

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


TButton   (2003-08-30 21:36:00) [14]

сначала я подумал что забыл про оверрайд, но мои подозрения не оправдались. пересмотрев код я не нашел существенных отличий
(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:13:00) [15]

все время происходит 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 19:07:00) [16]

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


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

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

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


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

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


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

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


Наверх

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