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

Вниз

Как работает этот PixelCheck?   Найти похожие ветки 

 
mudazvon   (2004-10-28 08:48) [0]

Знаю что подобных вопросов было очень много, но я так и не понял почему если я ставлю
PixelCheck := True;
Попиксельный контроль столкновений не работает (только по рамке). Сразу говорю не один из спрайтов не анимируется! И нет вращения спрайтов.

Посмотрите пожалуйста код:
-------------------------

procedure TPlayer.DoMove(MoveCount: integer);
begin
 inherited DoMove(MoveCount);
 if isLeft in Form1.DXInput1.States then X := X-2;
 if isRight in Form1.DXInput1.States then X := X+2;
 if isUp in Form1.DXInput1.States then Y := Y-2;
 if isDown in Form1.DXInput1.States then Y := Y+2;
 Collision;
end;

constructor TPlayer.Create(AParent: TSprite);
begin
 inherited Create(AParent);
 Image := Form1.DXImageList1.Items.Find("Automobile");
 X := 10;
 Y := 165;
 Width := Image.Width;
 Height := Image.Height;
 PixelCheck := True;
end;

procedure TPlayer.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
 if Sprite is TBlok then Dead;
end;
--------------------------------------------------------------------

И размеры указал, и проверку включил (Collision) в DoMove, а он не работает.

Может я где то туплю.


 
ASoft   (2004-10-28 17:34) [1]

Может все же происходит столкновение пикселей, а тебе кажется, что рамкой?


 
mudazvon   (2004-10-29 18:55) [2]

Нет точно не пикселей.

У меня в рамки автомобаль и по бокам много места остаётся 1 см где то. Так вот чтобы не проходить сквозь объекты я и использую DoCollision. При этом видно явно что автомобиль не задевает вообще объект (т.е. сам рисунок), а касается рамка.

Вообще остаётся тогда или делать автомобиль в размер рамки (спрайт каким то мультяшным получится) или самому писать свой метод.

Может в коде ошибка?


 
Falcon(TFsoft) ©   (2004-10-30 15:48) [3]

Я, конечно не уверен, но поробуй постаивть:

procedure TPlayer.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
inherited DoCollision (Sprite, Done);{ может здесь кроется неудача, ведь у меня всё работало, если нет, то пиши здесь, я посмотрю свои старые архивы с исходниками}
if Sprite is TBlok then Dead;
end;


 
RyDmi ©   (2004-10-31 12:49) [4]

У меня такая же проблема, может кто-нибудь всё- таки знает ответ.
Делаю вид сверху и меня объект по ширине больше, чем по длинне, получается очень говнясто. Очень прошу помочь.

To Falcon(TFsoft) © если найдешь в архивах что- нибудь полезное, кинь на мыло ПЛЗ. Заранее спасибо!


 
Falcon(TFsoft) ©   (2004-10-31 15:01) [5]

Доброе время суток все снова.

Ну, вот в архивах я ничего не нашёл, но решил вам всё же помочь, так как сам иногода спрашиваю тут на форумах, и я как и вы хочу получиьт исчерпывающий ответ, да ещё и с исходниками, то панацея выглядит приблезительно вот так:

unit Main_Unit;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs,
 DXClass, DXSprite,  DXDraws, DXInput;

type
 TMFrm = class(TDXForm)
   DXDraw: TDXDraw;
   DXImageList: TDXImageList;
   DXEngine: TDXSpriteEngine;
   DXTimer: TDXTimer;
   DXInput: TDXInput;
   procedure DXDrawInitialize(Sender: TObject);
   procedure DXDrawFinalize(Sender: TObject);
   procedure DXTimerActivate(Sender: TObject);
   procedure DXTimerDeactivate(Sender: TObject);
   procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
   procedure FormCreate(Sender: TObject);
   procedure FormKeyDown(Sender: TObject; var Key: Word;
     Shift: TShiftState);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
 TMonoSprite = class(TImageSprite)
     speed : Double;// скорость движение
     MoveCount : Double;// для столкновения, не обязателен, если вы сами будете решать столкновения...
     Procedure DoMove(MoveCount: Integer); override;
     procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
  end;
var
 MFrm: TMFrm;
 FMoveModel :TMonoSprite;// спрайт игрока

implementation

{$R *.dfm}

Procedure TMonoSprite.DoMove(MoveCount: Integer);
var
 dx, dy  : Single;
begin
  inherited DoMove(MoveCount);
   if isLeft in Mfrm.DXInput.States then
     begin
       dx:=-speed;
     end;

   if isRight in Mfrm.DXInput.States then
     begin
       dx:=speed;
     end;

   if isUp in Mfrm.DXInput.States then
     begin
        dy:=-speed;
     end;
   if isDown in Mfrm.DXInput.States then
     begin
       dy:=speed;
     end;

   x := x+dx*0.01*MoveCount;
   y := y+dy*0.01*MoveCount;
   Self.MoveCount := MoveCount;//для стокновения...
   Collision;
end;

procedure TMonoSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
  inherited DoCollision (Sprite, Done);
  if Sprite is TImageSprite then// если стакиваемя значит...
     begin
//расшифровка позже в тексте
        Self.X := Self.X+abs(Self.X-Sprite.X)/(Self.X-Sprite.X)*speed*0.01*MoveCount;
        Self.y := Self.y+abs(Self.y-Sprite.y)/(Self.y-Sprite.y)*speed*0.01*MoveCount;
     end;
end;

procedure TMfrm.FormCreate(Sender: TObject);
begin
 Randomize;

 DXImageList.Items.MakeColorTable;

 DXDraw.ColorTable := DXImageList.Items.ColorTable;
 DXDraw.DefColorTable := DXImageList.Items.ColorTable;
 DXDraw.UpdatePalette;

 with TMonoSprite.Create(DXEngine.Engine) do
 begin
 Image := DXImageList.Items.Find("Obj1");
 X := 25;
 Y := 25;
 Width := Image.Width;
 Height := Image.Height;
     speed := 10;
     PixelCheck := true;
 end;

   With TImageSprite.Create(DXEngine.Engine) do
   begin
     Image := DXImageList.Items.Find("Obj2");
 X := 160;
 Y := 60;
 Width := Image.Width;
 Height := Image.Height;
     PixelCheck := true;
   end;
end;

// ДАЛЕЕ туфта... другими словами то, что есть во всех приложения
procedure TMfrm.DXTimerActivate(Sender: TObject);
begin
 Caption := Application.Title;
end;

procedure TMfrm.DXTimerDeactivate(Sender: TObject);
begin
 Caption := Application.Title + " [Pause]";
end;

procedure TMfrm.DXTimerTimer(Sender: TObject; LagCount: Integer);
begin
 if not DXDraw.CanDraw then exit;

 DXInput.Update;

 DXEngine.Move(LagCount);
 DXEngine.Dead;

 DXDraw.Surface.Fill(0);
 DXEngine.Draw;

 with DXDraw.Surface.Canvas do
 begin
   Brush.Style := bsClear;
   Font.Color := clWhite;
   Font.Size := 8;
   Textout(0, 0, "FPS: "+inttostr(DXTimer.FrameRate));
 Textout(0, 10, "Sprite: "+inttostr(DXEngine.Engine.AllCount));
 Textout(0, 20, "Draw: "+inttostr(DXEngine.Engine.DrawCount));
   Release;
 end;

 DXDraw.Flip;
end;

procedure TMfrm.FormKeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 if Key=VK_ESCAPE then
 Close;

 if (ssAlt in Shift) and (Key=VK_RETURN) then
 begin
   DXDraw.Finalize;

   if doFullScreen in DXDraw.Options then
   begin
     RestoreWindow;

     DXDraw.Cursor := crDefault;
     BorderStyle := bsSizeable;
     DXDraw.Options := DXDraw.Options - [doFullScreen];
   end else
   begin
     StoreWindow;

     DXDraw.Cursor := crNone;
     BorderStyle := bsNone;
     DXDraw.Options := DXDraw.Options + [doFullScreen];
   end;

 DXDraw.Initialize;
 end;
end;

procedure TMfrm.DXDrawFinalize(Sender: TObject);
begin
 DXTimer.Enabled := False;
end;

procedure TMfrm.DXDrawInitialize(Sender: TObject);
begin
 DXTimer.Enabled := True;
end;

end.



Расшифрую, то что обещал:

Self.X := Self.X+abs(Self.X-Sprite.X)/(Self.X-Sprite.X)*speed*0.01*MoveCount;


Это не сто иное как перемещения спрайта, отталкивание, от объекта на который он налител.

Тоесть Self.X := Self.X + dx - меняем координату на некоторую величину

dx=Направление*скорость

Направление = abs(Self.X-Sprite.X)/(Self.X-Sprite.X) - и равняется либо +1 либо -1

Сокрость = speed*0.01*MoveCount - скорость*коэфициент коррекции по скорости компа, другими словами корреция по ФПС.

Подводя итог ответа можна сказать, что для проверки попиксельного столкновения необходимо просто включить PixelCheck := true; у обоих спрайтов (или хотя бы у одного).

Привемр с ехе я выложу по ссылке:
www.tfsoft.nm.ru/downloads/test2.zip


 
mudazvon   (2004-11-01 07:04) [6]

Мистика какая то. Код просматриваю этот, также и я делал, но ничего не получается:
включал PixelCheck := True; в конструкторе класса.

Пробовал для двух классов PixelCheck := True; делать:
для TPlayer и TBuilding. Тогда получится что автомобиль вообще сквозь препятствие проходит, не вызывая DoCollision.

Сейчас посмотрю твой пример Test2.zip


 
mudazvon   (2004-11-01 07:16) [7]

Я понял почему не работает PixelCheck. Я смело заявляю это DelphiX. У меня он для Delphi 7, очевидно там в модуле нет этого свойства и в методе оно не учитывается.

Сейчас я проверил Test2.zip: exe файл работает как и положено - проверяет по пикселям. Я откомпилировал проект, и у меня стал ошибочно работать - проверяет по рамке, а не по пикселям!

Теперь нужно модуль правильный добыть, где DoCollision вместе с PixelCheck работате.

Если у кого есть дайте ссылку.


 
RyDmi ©   (2004-11-02 00:23) [8]

To All: если будет исходник ПЛЗ киданите на мыло: rydmi@yandex.ru


 
Falcon(TFsoft) ©   (2004-11-02 00:53) [9]

Исходники на
www.tfsoft.nm.ru/downloads/test2.zip
Но сайт не про программёрство, ну точнее не совсем про то :)



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

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

Наверх




Память: 0.5 MB
Время: 0.033 c
14-1105789941
Ilya___
2005-01-15 14:52
2005.02.06
ошибка: Invalid variant operation. >


3-1104748932
UVV
2005-01-03 13:42
2005.02.06
последовательность в Oracle


14-1105815708
Вадя
2005-01-15 22:01
2005.02.06
Webcam


9-1099659971
Flex
2004-11-05 16:06
2005.02.06
Где можно скачать библеотеку Delphix?


1-1105983132
serko
2005-01-17 20:32
2005.02.06
CheckBox