During the procedure, TimerMoveTimer gives me an error (meaning popup with Access Wiolation).

 unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; type ClassPanzer=class(TObject) x,y,hp:integer; Bmp:TBitmap; end; TFormGame = class(TForm) ImageGround: TImage; TimerSpawn: TTimer; TimerMove: TTimer; TimerShoot: TTimer; ButtonSender: TButton; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure TimerSpawnTimer(Sender: TObject); procedure TimerMoveTimer(Sender: TObject); end; var FormGame: TFormGame; PanzerFaust:array of ClassPanzer; PanzerToRight,PanzerToUp,PanzerToLeft,PanzerToDown,BitMapGround,BitMapRoad,BitMapBaseSovjet,BitMapBaseNazi:TBitmap; WaveCount,Gold,EnemyCounter:integer; implementation {$R *.dfm} procedure TFormGame.FormClose(Sender: TObject; var Action: TCloseAction); var Counter1:integer; begin // PanzerToRight.Free; PanzerToUp.Free; PanzerToLeft.Free; PanzerToDown.Free; BitMapGround.Free; BitMapRoad.Free; BitMapBaseSovjet.Free; BitMapBaseNazi.Free; // for Counter1:=1 to Length(PanzerFaust) do PanzerFaust[Counter1].Free; // end; procedure TFormGame.FormCreate(Sender: TObject); var counter1,counter2, counter3 :integer; begin // procedure begin EnemyCounter:=1; counter3:=1; PanzerToRight:=TBitmap.Create; PanzerToRight.LoadFromFile('PanzerToRight.bmp'); // PanzerToUp:=TBitmap.Create; PanzerToUp.LoadFromFile('PanzerToUp.bmp'); // PanzerToLeft:=TBitmap.Create; PanzerToLeft.LoadFromFile('PanzerToLeft.bmp'); // PanzerToDown:=TBitmap.Create; PanzerToDown.LoadFromFile('PanzerToDown.bmp'); // BitMapGround:=TBitmap.Create; BitMapGround.LoadFromFile('Ground.bmp'); // BitMapRoad:=TBitmap.Create; BitMapRoad.LoadFromFile('Road.bmp'); // BitMapBaseSovjet:=TBitmap.Create; BitMapBaseSovjet.LoadFromFile('SovjetBase.bmp'); // BitmapBaseNazi:=TBitmap.Create; BitMapBaseNazi.LoadFromFile('NaziBase.bmp'); for counter1:=1 to 20 do for counter2:= 1 to 20 do ImageGround.Canvas.Draw(counter2*50-50,counter1*50-50,BitMapGround); // for counter1:=1 to 10 do for counter2:= 1 to 20 do ImageGround.Canvas.Draw(Counter2*50-50,counter1*100-50,BitMapRoad); // counter3:=100; for counter1:=1 to 5 do begin ImageGround.Canvas.Draw(950,counter3,BitMapRoad); counter3:=counter3+200; end; // counter3:=200; for counter1:=1 to 4 do begin ImageGround.Canvas.Draw(0,counter3,BitMapRoad); counter3:=counter3+200; end; // ImageGround.Canvas.Draw(0,050,BitMapBaseNazi); ImageGround.Canvas.Draw(0,950,BitMapBaseSovjet); // WaveCount:=1; ButtonSender.Click; TimerSpawn.Enabled:=true; //procedure end end; // procedure TFormGame.TimerMoveTimer(Sender: TObject); var counter:integer; begin for counter:= 0 to WaveCount*50 div 4 do begin if ((PanzerFaust[Counter].y=50) or (PanzerFaust[Counter].y=250) or (PanzerFaust[Counter].y=450) or (PanzerFaust[Counter].y=650) or (PanzerFaust[Counter].y=850)) and (Panzerfaust[Counter].x<950) and (PanzerFaust[Counter].x>50) then begin; PanzerFaust[Counter].Bmp:=PanzerToRight; ImageGround.Canvas.Draw(PanzerFaust[Counter].x,PanzerFaust[Counter].y,BitMapRoad); Panzerfaust[Counter].x:=PanzerFaust[Counter].x+2; ImageGround.Canvas.Draw(PanzerFaust[Counter].x,PanzerFaust[Counter].y,PanzerToRight); end; end; end; procedure TFormGame.TimerSpawnTimer(Sender: TObject); begin if EnemyCounter<=WaveCount*50 div 4 then begin SetLength(Panzerfaust,EnemyCounter); PanzerFaust[EnemyCounter].x:=60; PanzerFaust[EnemyCounter].y:=50; PanzerFaust[EnemyCounter].hp:=100; PanzerFaust[EnemyCounter].bmp:=PanzerToRight; ImageGround.Canvas.Draw(PanzerFaust[EnemyCounter].x,PanzerFaust[EnemyCounter].y,PanzerFaust[EnemyCounter].bmp); EnemyCounter:=EnemyCounter+1; TimerMove.Enabled:=true; end; end; end. 
  • 3
    for some important purpose in which you insert the unformatted code again? And you already seemed advised to put a break on the desired method, and step by step to catch the error. - teran
  • 2
    Make sure once again that WaveCount*50 div 4 will not take you beyond the array. And install RangeCheck , as stated, in the compilation settings. - teran
  • To be honest, in any attempt to debag my eyes, I run up ... Frankly, I teach computer science at school, I hardly can use it ... Therefore, for me, all terms are fundamentally new - Smartass
  • And why are there eyes scatter? Just being at a specific point determine in the variables you need are the data you need? If these objects will be enough for you to see that they are NOT nil or nil if you are sure of it! - JVic
  • 1. in an array (except for strings, in some cases), the reckoning goes not from 1 but from 0. 2. PanzerFaust: array of ClassPanzer; - where is your array element initialization? - rareMax

1 answer 1

Access violation error is almost always the result of a call to a non-initialized memory area.

In the TimerMoveTimer method, a potentially dangerous place from this point of view is the PanzerFaust array and its elements.

And in the above code, there is nowhere to initialize the array elements.

In general, the error should have appeared in the TimerSpawnTimer method on the line PanzerFaust [EnemyCounter] .x: = 60; because memory for the object has not been allocated.