Ошибка времени выполнения: System.ArgumentException: Недопустимый параметр

Хотел сделать игру на подобие Zombie Smasher для курсовой работы, но в процессе игры она вылетает с ошибкой на строке 77 или вообще просто вылетает без ошибки. Не могу понять в чем проблема. Вот код:

uses GraphABC, ABCObjects, ABCButtons, System.Windows.Forms;
   
const
  Width: integer = 512;
  Height: integer = 512;
  BG: string = 'bg.png';
  ZombieImage: string = 'zombie.png';
  BloodImage: string = 'blood.png';
  MAX_CNT_ZOMBIES: integer = 9;
  
procedure EventTick();                    forward;
procedure SetWindowConfigurations();      forward;
procedure MouseDown(x,y,mb:integer);      forward;
procedure KeyPressed(key: integer);       forward;
procedure UpdateScore();                  forward;
procedure InitZombie();                   forward;
procedure DestroyMenu();                  forward;
procedure InitLabels();                   forward;
procedure GameOver();                     forward;
procedure StartGame();                    forward;
procedure Rules();                        forward;
procedure Menu();                         forward;
  
var score, lives: integer;
    scoreLabel, livesLabel: TextABC;
    TimeOffset: System.TimeSpan;
    GameStartTime: DateTime;
    btn1, btn2, btn3: ButtonABC;
    title: TextABC;
    I: integer;
  
type 
  Zombie = class(Object)
    public
      zspeed: integer;
      zpic: PictureABC;
      alive: boolean;
      constructor Create();
      begin                
        zspeed := Random(4, 10);
        zpic := PictureABC.Create(Random(80, 390), Random(5, 30), ZombieImage);
        alive := true;
        zpic.ToFront;
      end;
      destructor Destroy();
      begin
        if zpic = nil then exit;
        zpic.Destroy();
        zpic := nil;
      end;
      procedure Restart;
      begin
        zpic.MoveTo(Random(80, 390), Random(5, 30));
        zpic.RedrawNow;
      end;
      procedure kill;
      begin
        zpic.ChangePicture(BloodImage);
        zpic.ToBack;
        zspeed := 0;
        alive := false;
        score += Random(10, 20);
      end;
      function Clicked(x,y: integer): boolean;
      begin
        Clicked := false;
        if alive = false then exit;
        if ((zpic.Position.X <= x) and ((zpic.Center.X*2 - zpic.Position.X) >= x)) and 
           ((zpic.Position.Y <= y) and ((zpic.Center.Y*2 - zpic.Position.Y) >= y)) then
          Clicked := true;
        exit;
      end;
      procedure Move;
      begin
        if (zpic = nil) or (alive = false) then exit;    
        if zspeed is integer then 
          zpic.MoveOn(0, 1+zspeed)
        else
          zpic.MoveOn(0, 1);
      end;

  end;
 
var zombies: array [1..MAX_CNT_ZOMBIES] of Zombie;
 
procedure EventTick();
begin
  if (DateTime.Now - GameStartTime) <> TimeOffset then 
  begin
    TimeOffset := DateTime.Now - GameStartTime;
    if (Trunc(TimeOffset.TotalMilliseconds) mod 2) = 0 then
    begin
      if zombies[i] <> nil then
      begin
        if zombies[i].Alive = false then
        begin
          zombies[I].Destroy();
          zombies[I] := nil;
        end
        else if zombies[i].zpic.Position.Y >= Height then
        begin
          zombies[i].Restart();
          Dec(lives);
        end
        else if zombies[i].Alive then
          zombies[i].Move()
      end;
      UpdateScore();
      if I = MAX_CNT_ZOMBIES then I := 1
      else Inc(I);
    end;
  end;
  if (zombies[i] = nil) and ((Trunc(TimeOffset.TotalMilliseconds) mod 99) = 0) then
        zombies[I] := Zombie.Create();
end;
 
procedure SetWindowConfigurations();
begin
  Window.Title := 'Zombie Smash';
  Window.IsFixedSize := true;
  Window.Width := Width;
  Window.Height := Height;
  Window.Fill(BG);
end;
 
procedure MouseDown(x,y,mb:integer);//нажали кнопку мыши
begin 
  for var i := 1 to MAX_CNT_ZOMBIES do 
    if zombies[i] <> nil then
      if zombies[i].Clicked(x,y) then
      begin
        zombies[i].kill();    
      end;
end;

procedure KeyPressed(key: integer);
begin
  case key of
    VK_Escape: 
      Window.Close; 
    else;
   end;
end;
 
procedure UpdateScore();
begin
  scoreLabel.Text := $'Score: {score}';
  livesLabel.Text := $'Lives: {lives}';
end;
 
procedure InitZombie();
begin
    zombies[1] := Zombie.Create();
end;
 
procedure DestroyMenu();
begin
  title.Destroy;
  btn1.Destroy;
  btn2.Destroy;
  btn3.Destroy;
end;
 
procedure InitLabels();
begin
  
  score := 0;
  lives := 3;
  
  scoreLabel := TextABC.Create(10, 10, 20, $'Score: {score}', clCoral);
  livesLabel := TextABC.Create(10, 30, 20, $'Lives: {lives}', clCoral);
end;
 
procedure GameOver();
begin
  LockDrawingObjects;
  
  livesLabel.Text := 'GAME OVER';
  livesLabel.FontSize := 40;
  livesLabel.MoveTo(100, 180);
  livesLabel.Color := clRed;
  livesLabel.ToFront;
  livesLabel.FontStyle := FontStyleType.fsBold;
  
  scoreLabel.Text := $'Total Score: {score}';
  scoreLabel.FontSize := 30;
  scoreLabel.MoveTo(110, 240);
  scoreLabel.Color := clGreen;
  scoreLabel.ToFront;
  livesLabel.FontStyle := FontStyleType.fsBold;
  
  RedrawObjects();
end;
 
procedure StartGame();
begin

  DestroyMenu();
  InitZombie();
  InitLabels();

  GameStartTime := DateTime.Now;
  i := 1;
  //UnLockDrawingObjects();
  while lives > 0 do
  begin
    EventTick();
  end;

  // Игра окончена
  GameOver();

end;
 
 procedure Rules();
 begin
   var msg := $'Все что тебе предстоит делать это нажимать на бегущих сверху вниз зомби.{chr(10)}И за это зарабатывать очки.{chr(10)}Игра будет продолжаться пока ты не проиграешь.';
   MessageBox.Show(msg,'Правила', MessageBoxButtons.OK);
 end;
 
procedure Menu();
begin
 
  UnLockDrawingObjects;//LockDrawingObjects;
  title := TextABC.Create(Width div 2 - 130, 70, 40, $'  ZOMBIE{Chr(10)}SMASHER', GColor.Red);
  btn1 := ButtonABC.Create(Width div 2 - 50, Height div 2, 100, 30, 'Играть', GColor.Gainsboro);
  btn2 := ButtonABC.Create(Width div 2 - 50, Height div 2 + 60, 100, 30, 'Правила', GColor.Gainsboro);
  btn3 := ButtonABC.Create(Width div 2 - 50, Height div 2 + 120, 100, 30, 'Выйти', GColor.Gainsboro);
  //RedrawObjects;
  
  btn1.OnClick := ()->System.Threading.Thread.Create(StartGame).Start();
  btn2.OnClick := Rules;
  btn3.OnClick := Window.Close;
  
end;
 
begin
  
  SetWindowConfigurations();
  
  OnMouseDown := MouseDown;
  OnKeyDown := KeyPressed;
  
  Menu();
  
end.

Игра жутко лагает, вылетает когда захочет, и иногда даже не запускается с первого раза.


Ответы (0 шт):