PDA

View Full Version : Access violation error in UnDelphiX



Wizard
28-09-2007, 06:37 AM
Can someone please explain why I'm getting this error and how to fix it,it only happens once in a while for some reason... Thanks for your help.

Error EACCESS VIOLATION with message ACCESS VIOLATION at address 00479966 in DXSprite class :
procedure TSprite.Dead;
begin
if (FEngine <nil> error line here
end;
end;

FEngine.FDeadList.Add(Self); ------ > error line here


My code to kill sprites:


procedure TFormGame.RenderPlay;
begin
DXSpriteEngine.Engine.Collisions;
DXSpriteEngine.engine.Dead;
DXSpriteEngine.Draw;
...

_psStarting &#58; begin
dxSpriteEngine.Engine.Clear;
...

_psPlaying &#58; begin
FormGame.DxdrawGame.Surface.BltFast&#40;0, 0, backscreen.clientrect,1, backscreen&#41;;
DxSpriteEngine.Engine.Move&#40;1&#41;;
if &#40;player.Deaded&#41; and &#40;Lives <0>= 100000&#41; then
begin
fGameState &#58;= _gsEnd;
fEndState&#58;=_esPlaySelected;
formGame.DXWaveList.Items.Find&#40;'BlownUp'&#41;.Play&#40;Fal se&#41;;
DXSpriteEngine.Dead;
dxspriteEngine.Engine.Dead;
formHigh.ShowModal;
end
else
if &#40;Player.Deaded&#41; and &#40;Lives <= 0&#41; then
begin
fGameState&#58;=_gsEnd;
fEndState&#58;=_esPlaySelected;
formGame.DXWaveList.Items.Find&#40;'BlownUp'&#41;.Play&#40;Fal se&#41;;
DXSpriteEngine.Dead;
dxspriteEngine.Engine.Dead;
end
else
RenderPlay;
end;....

seiferalmasy
28-09-2007, 06:41 AM
look at my other thread, jaro and I belieev it is a fault of spriteengine.Clear.

Wizard
28-09-2007, 07:00 AM
Thanks, I thought that I was calling dead in the wrong place or something...Anyway I'm trying your suggestion :

For I:=0 to mainfm.DXSpriteEngine1.Engine.allcount-1 do
begin
mainfm.DXSpriteEngine1.Engine.Items[i].dead;
end;

It seems to work, will do some tests. Will watch this space for updates :-)

Wizard
28-09-2007, 07:42 AM
Ok so I did some tests with seiferalmasy's suggestion to count the items and then call dead but I get the same error :-(

FEngine.FDeadList.Add(Self) in procedure TSprite.Dead;

So, I changed the call to Clear and the error is still there.....must be something wrong in my code? Help please :-)

technomage
28-09-2007, 08:39 AM
For I:=0 to mainfm.DXSpriteEngine1.Engine.allcount-1 do
begin
mainfm.DXSpriteEngine1.Engine.Items[i].dead;
end;




I'm no expert on DelphiX but..

Wouldn't the call to items[i].dead change the value of allcount? or does allcount return a count of all the sprites including dead ones?

If the count changes (i.e reduces by 1 after calling dead) then you need to loop the other way.


For I:= mainfm.DXSpriteEngine1.Engine.allcount-1 downto 0 do
begin
mainfm.DXSpriteEngine1.Engine.Items[i].dead;
end;


This would protect you from accessing indexes that have been removed in a previous iteration of the loop.

Wizard
28-09-2007, 09:23 AM
Thanks technomage, I tried your way (which makes a bit more sense to me) but I get the same error. It is very difficult to see which line of my code is causing it but it shows that the error is in DXSprite:

FEngine.FDeadList.Add(Self) in procedure TSprite.Dead;

So I suppose it must have something to do with the calls to dead?

technomage
28-09-2007, 09:50 AM
I suspect the problem is not in the Dead Method , but that item in the sprite list is not valid. Somehow one of the items in your mainfm.DXSpriteEngine1.Engine.Items list is an invalid instance or nil.

When calling a method on a invalid instance the access violation will appear to be in the method you called (usually when trying to access something that
has not be created/initialized etc). I would check that


For I:= mainfm.DXSpriteEngine1.Engine.allcount-1 downto 0 do
begin
if (mainfm.DXSpriteEngine1.Engine.Items[i] <> nil) then
begin
mainfm.DXSpriteEngine1.Engine.Items[i].dead;
end;
end;


That might help :?:

Wizard
28-09-2007, 10:36 AM
OK :-)

I did as you suggested and after some testing it seems that the error has vanished into thin air :wink:

I am very happy indeed, thanks for your help 8)

seiferalmasy
28-09-2007, 10:54 AM
hmmm I havent had any trouble with the code I used, but I am killing all and creating all in 1 move , after one another.

Your code is probably a better idea.

The way I saw it was I is the number of the item. All count gives the total number and then each will be killed in turn. Allcount must show also dead ones? There is another called count (not allcount) . You are right t.mage, you made a good point!

Hopefully clear will be sorted soon anyway...

Wizard
03-10-2007, 11:23 AM
So the error returned but I managed to pinpoint the problem. I was calling dxSpriteEngine.Engine.Dead, whereas it should be:
dxSpriteEngine.Dead. :D

seiferalmasy
03-10-2007, 06:12 PM
yeah;)