webForumDet fria alternativet

list.Delete()

5 svar · 162 visningar · startad av Alpha II

Alpha IIMedlem sedan maj 20002 579 inlägg
#1

Varför får jag felet "List index out of bounds (xxx)" i den här koden:

procedure BackgroundAnim;
var
  I : Integer;
  AStar : PStar;
begin
    if Starfield.Count < 256 then begin
      New(AStar);
      AStar^.X := 640 / 2;
      AStar^.Y := 480 / 2;
      AStar^.VelX := (Random(256)-128)/100;
      AStar^.VelY := (Random(256)-128)/100;

      Starfield.Add(AStar);
    end;

    Anim := 0;
    for I := 0 to Starfield.Count-1 do begin
      AStar := Starfield.Items[I];
      AStar^.X := AStar^.X + AStar^.VelX;
      AStar^.Y := AStar^.Y + AStar^.VelY;
      MainForm.DXDraw.Surface.Canvas.Pixels[Round(AStar^.X), Round(AStar^.Y)] := clWhite;

      if ((AStar^.X < 0) or (AStar^.X > 640)) or
         ((AStar^.Y < 0) or (AStar^.Y > 480)) then
         Starfield.Delete(I); [b]<--- Det är här felet uppstår!!!!!!!!!!![/b]
  end;

  MainForm.DXDraw.Surface.Canvas.Release;
end;
Marcus EMedlem sedan maj 20021 294 inlägg
#2

Därför att om du tar bort ett item ändras indexet för alla som kommer efteråt. Du måste därför minska I med ett efteråt, eller gå från Count-1 till 0 istället.

Alpha IIMedlem sedan maj 20002 579 inlägg
#3

Jag gjorde en while slinga istället.
Man kan inte ändra I i loopen.
Hur går man från Count-1 -> 0?

Marcus EMedlem sedan maj 20021 294 inlägg
#4

kanske
for I := Starfield.Count-1 to 0 do begin

Jag kan inte Pascal, utan har endast använt VCL i BCB.

Alpha IIMedlem sedan maj 20002 579 inlägg
#5

tror jag har testat det och det har inte fungerat, men jag är inte säker

jtMedlem sedan juni 2000326 inlägg
#6

Använd downto istället för to.

Genererad på 381 ms · cache AV · v20260730165559-full.f96bc7eb