Yep - whatever is going wrong doesn't appear to be connected (at least entirely) with what you've posted so far - I will note however that :
Code:
freeandnil(bullets[i]);
if i=numofbullets-1 then
dec(numofbullets)
else
begin
for j:=i+1 to numofbullets-1 do
bullets[j-1]:=bullets[j];
dec(numofbullets);
end;
is convoluted and a mess - why free the bullet at all? just fill your array with created bullet objects and just have a new boolean property of TBullet called 'active'. Then you can simply do :
Code:
{go through the array and create a TBullet object with 'active' set to false for all objects as part of your game initialization}
if (plshoot=true) and (plcanshoot=true) then
begin
I := 0;
while Bullet[I].active do
I := I + 1;
if I > high(Bullet) then exit;
Bullet[I].active := true;
Bullet[I].Xplace := Player.Left;
Bullet[I].Yplace := Player.Top;
end;
for I := 0 to numofbullets-1 do
if bullets[I].active then
begin
bullet[I].YPlace := bullet[I].YPlace-4;
if bullet[I].YPlace < 10 then
bullet[I].Active := false;
end;
Then go through the array and only render 'active' bullets - yes you'll be skipping over 'inactive' bullets but that's still loads faster than constantly creating/destroying objects.
An optimization of this would to be to treat the array like a ring-buffer - then by its very nature the start index is the oldest active bullet and the end index is the newest bullet - only iterate over these - still you'll itterate over some inactive bullets but it'll be much faster than constantly keeping the array tightly packed - you could also use a linked list but really unless you've got thousands of bullets there's no need to care performance wise.
There are various reasons why you'd want to keep an array tightly packed - perhaps it needs to be kept sorted (but there are better structures such as linked lists) or perhaps you have a need to copy a continuous block of memory for some reason (uploading vertex data to a GPU) but you don't need either of these.
Also bare in mind that there's no reason you can't have two container structures - a flat array and a linked list - scan the flat array for an inactive bullet - set it to active and add a reference to a linked list. If the bullet is to be 'destroyed' set it to inactive and remove it from the linked list - this way you have a flat array for 'storage' and the linked list for optimal iteration over active elements (linked lists are slow to index but are very fast for deletions/insertions - especially in your case where you delete from anywhere in the list but only add to the end)
Even better have two linked lists - an active one and an inactive one - then you no longer have to scan for an active bullet or create one - you just remove one from the inactive list and add it to the active list and visa versa - a slow object creating, array shuffling operation becomes a case of setting a few pointers.
--
But : these are only suggestions to think about - it's overkill at this stage - as SilverWarrior suggests we'd need to see basically all of your code to tell you what's wrong.
Bookmarks