PDA

View Full Version : Image change on collision not working



Wizard
28-08-2009, 08:31 AM
Hi, I hope someone can help. I'm using unDelphiX as graphics library. I have a Tlist called MyMen and a car which runs down these men. Once the car collides with a man the man is supposed to die and in it's place a pool of blood must appear. The collision detection seems to work but, for some strange reason, the explode class is not doing what it should, that is to let the pool of blood appear after the man is dead -- see the explode procedure.

I don't know what I'm doing wrong here so I'd appreciate it if someone could look at the code below...maybe I'm missing something.

Thanks in advance!

The Car:
constructor TCar.create(parent:TSprite;startingGas:integer);
begin
inherited create(parent);
self.Image:=form1.dxImageList1.Items[0];
self.Width:=self.image.Width;
self.Height:=self.Image.Height;
self.PixelCheck:=false;
self.x:=170;
self.Y:=240;
self.Z:=0;
fGas:=startingGas;
end;

procedure TCar.doMove(MoveCount : integer);
begin
fGas := fGas - (1 * UpdateGas);
if(fGas<=0) then
self.Moved := False;
if (gas>0) then
begin
if (x > 95) and
(isLeft in form1.DXInput1.states) then x := (x - 16 * updatespeed);
if (x < 490) and
(isright in form1.DXInput1.states) then x := (x + 16 * updatespeed);
end;
if (y < road.y + 250) then
begin
car.Moved := False;
road.Moved := False;
if (form1.fScore >= 7000)then
form1.DXWaveList1.Items.Find('Applause').Play(Fals e);
end;
collision;
Car.OnCollision:=form1.CarCollision;
end;

The Man:

constructor TMan.Create(xPos,yPos:integer;parent: TSprite;sImageList:TDXImageList);
begin
inherited create(parent);
self.x:=xPos;
self.y:=yPos;
self.Image:= sImageList.Items[11];
self.width:=self.image.width;
self.height:=self.image.height;
self.pixelcheck := true;
self.AnimCount := 5;
self.AnimLooped := true;
self.AnimSpeed := 0.12;
self.WalkSpeed := 2 * updatespeed;
fhit := false;
end;

procedure TMan.DoMove(MoveCount: Integer);
begin
AnimStart:=Direction*5;
if Direction=1 then X:=X+WalkSpeed;
if Direction=2 then X:=X+WalkSpeed;
if Direction=3 then X:=X+WalkSpeed;
if Direction=4 then X:=X-WalkSpeed;
if Direction=5 then X:=X-WalkSpeed;
if Direction=6 then X:=X-WalkSpeed;
case random(200) of
100:Direction:=random(7);
end;
if X< 85 then Direction:=2;
if X>500 then Direction:=6;

begin
if (isUp in form1.DXInput1.States) then
Y := y + (2 * updatespeed);
end;
if y > Form1.DXDraw1.Height - 10 then
dead;
end;

The collision procedure:

procedure TForm1.CarCollision(Sender:TObject;var done:Boolean);
begin
if (sender is TMan) then
begin
Man := TMan(sender);

if (not Man.hit) then
begin
Man.hit := true;
Explode := TExplode.Create(dxSpriteEngine1.Engine);
Man.dead;
end;
end
else
if (sender is TDrum) then

The collision class:

Constructor TExplode.Create(Parent: TSprite);
begin
inherited Create(Parent);
self.Image := Form1.DXImageList1.Items[3];
self.X := Man.x;
self.Y := Man.Y;
self.Width := self.Image.Width;
self.Height := self.Image.Height;
self.PixelCheck := True;
self.AnimCount := self.Image.PatternCount;
self.AnimPos := 0;
self.AnimStart := 0;
self.AnimLooped:= True;
end;

procedure TExplode.DoMove(MoveCount: integer);
begin
inherited DoMove(MoveCount);
self.AnimSpeed := 0.07 * UpdateSpeed; //0.06
if (AnimPos >= ((AnimCount-1)-AnimSpeed)) then
self.Dead;
end;

In the PlayingState:

MyMen.Add(TMan.create(random (300), -500,dxSpriteEngine1.Engine,dxImageList1));
MyMen.Add(TMan.create(random (350),-1000,dxSpriteEngine1.Engine,dxImageList1));
MyMen.Add(TMan.create(random (300),-1500,dxSpriteEngine1.Engine,dxImageList1));

if (MyMen.count>0) then
for loop:=MyMen.count-1 downto 0 do
begin
TMan(MyMen[loop]).DoMove(1);
if (TMan(MyMen[loop]).Deaded) then
begin
TMan(MyMen[loop]).free;
MyMen.delete(loop);
end;
end;

DarkBow
28-08-2009, 09:43 AM
Not sure, but I think it might have something to do with how collisions are managed.

Can you tell us what TMan.Dead and TMan.Deaded do?

Wizard
28-08-2009, 10:01 AM
TMan.dead kills the man sprite after collision and TMan.deaded checks if the sprite is killed so that the list can be freed.

Traveler
28-08-2009, 01:27 PM
I don't see any mistakes atm, but I was wondering. Are you also drawing the explosions? I see you are creating the explode object, apart from that there're no moving (if there is any movement) or drawing routines.

Wizard
28-08-2009, 01:41 PM
Movement is done in my _psPlaying state:

dxSpriteEngine1.Dead;
dxSpriteEngine1.Move(1);

Drawing is done in the RenderPlay state:

DXSpriteEngine1.Draw;


All other objects gets drawn but not the explosions.

DarkBow
29-08-2009, 09:53 AM
TMan.dead kills the man sprite after collision and TMan.deaded checks if the sprite is killed so that the list can be freed.


Is the man sprite killed at all?

Your code first created the TExplode code and then calls Man.Dead. Can it be that you are painting the pool of blood and then painting something else over it? Like a "void" sprite to make the Man disappear?

Wizard
29-08-2009, 02:54 PM
It doesn't look like it's the collision routine causing the problem. I did some tests and when my Road is not drawn I can see the pool of blood animation. I'll do some further tests too see if I can fix this. It's definitely something to do with the drawing of the objects.

Wizard
30-08-2009, 08:21 AM
Solved!!! My road.z was 0, I changed it to -10 and now everything is drawn as it should be ::) Thanks for your interest 8)