Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Problem mit dynamischer Array und eaccessviolation (https://www.delphipraxis.net/167544-problem-mit-dynamischer-array-und-eaccessviolation.html)

fox67 4. Apr 2012 18:25

Problem mit dynamischer Array und eaccessviolation
 
Hallo ich bin gerade dabei ein Spiel zu Programmieren das ich auf meinem Tascenrechner endeckt habe namens Aspirin.Ziel in dem Spiel ist es so viele Diamanten wie möglich einzusammeln ohne von den Laserstrahlen getroffen zu werden(eigentlich sind es Kugeln :wink: ). Ich habe das ganze jetzt mit zwei dynamischen Arrays versucht zu lösen allerdings sind dann die ganze Zeit diese dämlichen eaccessviolation Meldungen gekommen. Ich hab dann bekonnen alle möglichen Kontrellstrukturen zu lösen hatt auch geklappt es kommt keine Meldung mehr allerdingsbewgt sich ausser der Spielfigur nichts.
Hier sind die Kompletten Programm Datein http://dl.dropbox.com/u/62039624/Aspirin.zip

Zur erklärung : mit Space ist die Pause Taste und die message die kommt enthält Zahlen die ich zum analysieren des Fehlers programmiert hab

CarlAshnikov 5. Apr 2012 11:26

AW: Problem mit dynamischer Array und eaccessviolation
 
Da ich lieder keine Zeit mehr für Erklärungen habe hier mal nur der Quelltext:
Damit konnte ich zumindest 2 Diamanten einsammeln ;-)
Delphi-Quellcode:
procedure TForm1.EngineTimer(Sender: TObject);
var
  Index: word;
begin
  if not Spiel.rPause then
    form1.Caption := 'Aspirin' + ' ' + 'Punkte: ' + inttostr(Spiel.rPunkte);
  if Spiel.rPause then
    form1.Caption := 'Aspirin' + ' ' + 'Pause';
  if Spiel.rPunkte > 0 then
  begin
    if t1 = 1 then
    begin
      //showmessage('Jetzt') ;
      for index := 0 to Spiel.anzahl-1 do //<----- hier lag der Fehler
      begin
        label1.Caption := inttostr(Spiel.anzahl);
        Spiel.shpos[index].Bewegung();
        //Spiel.sh[index].Top := Spiel.shpos[index].rpunkt.Y;
      //  sh2[index].Bewegung;

      end;
    end;
  end;
end;

fox67 5. Apr 2012 11:32

AW: Problem mit dynamischer Array und eaccessviolation
 
Ja aber bewegen tut sich immer noch nichts auser der Spielfigur. Bei der Zeile 179 hab ich vergessen die zwei Schrägstriche rauszumachen die gehören raus.

fox67 5. Apr 2012 22:18

AW: Problem mit dynamischer Array und eaccessviolation
 
Problem gelöst. neues Problem erstanden.
Code:
  case rRichtung of
 1:
  begin
    rpunkt.X:= rpunkt.X +3;
    [B]if rpunkt.Y > form1.Width-33 then rRichtung := 2;[/B]
    form1.Label1.Caption := inttostr(rRichtung);

   // Sleep(25);
  end;
 2: begin
    rpunkt.X:= rpunkt.X -3;

    if rpunkt.X < 0 then rRichtung := 1;
   // Sleep(25);
  end;
  end;
  end;

end;
Was ist an diesem Code falsch? Warum tut er nicht das was er soll.(bezieht sich nur auf das dicke) Normalerweise sollte doch die Richtung auf 2 umschalten sobald rpunkt.y größer als form1.width-33 ist warum tut es das nicht ?

Bummi 5. Apr 2012 22:35

AW: Problem mit dynamischer Array und eaccessviolation
 
weil Du auf Y prüfst ?

fox67 5. Apr 2012 22:38

AW: Problem mit dynamischer Array und eaccessviolation
 
4 augen sehen eindeutig mehr als 2 Vielen dank jetzt hab ich den ganzen abend rumprobiert und auf so was banales bin ich nicht gekommen. Das hatt man von der angeblichen Arbeitserleichterung namens copy+paste :)

Sir Rufo 5. Apr 2012 23:54

AW: Problem mit dynamischer Array und eaccessviolation
 
Du solltest auf Zugriffe wie
Delphi-Quellcode:
form1
verzichten.
Innerhalb der Form-Methoden kannst du die Eigenschaften direkt ansprechen
Delphi-Quellcode:
Width
oder auch mit
Delphi-Quellcode:
Self.Width
. Denn ein Umbenennen der Form (z.B. in etwas Sinnvolles wie
Delphi-Quellcode:
FSpiel
) haut dir den Code auseinander, genauso, wenn du eine weitere Instanz der Form erzeugst.

In deiner Anwendung hast du diese Routine innerhalb von
Delphi-Quellcode:
TPunkt
. Dort hast du ein Feld
Delphi-Quellcode:
Fenster
, welches wohl auf die Form verweisen soll, dann benutze das Feld doch auch ;)

Weiterhin fällt mir auf, dass du mit
Delphi-Quellcode:
Width - 33
arbeitest ... möchtest du den Rand des Fensters berücksichtigen?
Entweder fragst du die Form und das System, wie breit der Rand denn wirklich ist, oder (viel einfacher) du nimmst
Delphi-Quellcode:
ClientWidth
, das ist exakt die innere Breite ohne Rand :) - analog gibt es dazu natürlich auch
Delphi-Quellcode:
ClientHeight
Delphi-Quellcode:
case rRichtung of
 1:
  begin
    rpunkt.X:= rpunkt.X +3;
   
    if rpunkt.Y > Fenster.ClientWidth
    then
      rRichtung := 2;

  end;
 2:
  begin
    rpunkt.X:= rpunkt.X -3;

    if rpunkt.X < 0 then rRichtung := 1;
   // Sleep(25);
  end;
end;

Fenster.Label1.Caption := inttostr( rRichtung );

// Sleep(25);
und den gesamten Code bekommt man auch noch kürzer:
Delphi-Quellcode:
// rRichtung ist entweder 1 oder -1
rPunkt.X := rPunkt.X + rRichtung * 3;

if ( rPunkt.X < 0 ) or ( rPunkt.X > Fenster.ClientWidth ) then
  rRichtung := - rRichtung;

Fenster.Label1.Caption := inttostr( rRichtung );

// Sleep(25);

himitsu 6. Apr 2012 08:10

AW: Problem mit dynamischer Array und eaccessviolation
 
Und das du unbedingt noch machen solltest, wenn du eigenartige Reaktionen bekommst, beim Zugriff auf ein Array:

Die Bereichsprüfung in deinen Projektoptionen aktivieren
oder http://docwiki.embarcadero.com/RADSt...erpr%C3%BCfung

fox67 6. Apr 2012 11:20

AW: Problem mit dynamischer Array und eaccessviolation
 
width-33 hat den Sinn das der kreis nicht vom Fenster verschwindet(natürlich wäre clientwidth sinnvoller). Tja ich hab wohl vergessen das ich form1 bereits als Fenster deklariert habe. Diene Idee ist schlau mit den Vorzeichen darauf wärer ich kar nicht gekommmen vielen dank :)

fox67 6. Apr 2012 13:57

AW: Problem mit dynamischer Array und eaccessviolation
 
So nach dem der erste Teil jetzt fertig ist hab ich mich an den zweiten gemacht und es hatt sich wieder ein fehler eigeschlichen. Beim zweiten teil des spieles geht es darum vor der Polizei zu entwischen.
Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm2 = class;
  TPolizei = class;
  TSpiel2 = class;

  TPolizei = class(Tobject)
    private
      { Private-Deklarationen }
      Fenster : TForm2;


     rpunkt : TPoint;

     Haupt : Tspiel2;
    public
      { Public-Deklarationen }


      procedure Bewegung();
  end;

  TSpiel2 = class
   private
    { Private-Deklarationen }
    rSpielfigur : TImage;

    rPause     : Boolean;
    rDiamant   : Timage;
    Polizei      : TPolizei;
    rkollison1   : Tshape;
    sh          : array of TImage;
    shpos       : array of TPolizei;
    rZeit       : Integer;

    anzahl      : integer;
    Fenster     : Tform2;

  public
    { Public-Deklarationen }
    procedure Polizeierstellen();

    procedure Erstellen();


    constructor Create;
    destructor Destroy; override;
  end;


  TForm2 = class(TForm)
    Engine: TTimer;
    kollision: TTimer;
    Special: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Onclose(Sender: TObject; var Action: TCloseAction);
    procedure OnkeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure EngineTimer(Sender: TObject);
    procedure kollisionTimer(Sender: TObject);
    procedure SpecialTimer(Sender: TObject);
  private
    { Private-Deklarationen }
    Spiel2 : Tspiel2;
    Laser : TPolizei;
    Aktiv : Boolean;
    Zeit : String;
    z1,z2 : integer;
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;
   T,T1 : integer;
  X : integer;
  F : integer;

implementation

{$R *.dfm}

procedure TPolizei.Bewegung;
begin
  if haupt.rSpielfigur.Top < rpunkt.Y then rpunkt.Y := rpunkt.Y -1;
  if haupt.rSpielfigur.Top > rpunkt.Y then rpunkt.Y := rpunkt.Y +1;
  if haupt.rSpielfigur.Left < rpunkt.X then rpunkt.X := rpunkt.X -1;
  if haupt.rSpielfigur.Left > rpunkt.X then rpunkt.X := rpunkt.X +1;
 
 
end;

constructor Tspiel2.Create;
begin
   Polizei := TPolizei.Create;
   rkollison1 := TShape.create(nil);

  rkollison1.Parent := fenster;

  rkollison1.Visible:= false;

  rSpielfigur := Timage.Create(nil);
  rSpielfigur.Picture.Bitmap.LoadFromFile(ExtractFilePath(Application.ExeName) + '\Bilder\rechts.bmp');
  rSpielfigur.Top:= 0;
  rSpielfigur.Left:= 30;
  rSpielfigur.AutoSize := true;
  rSpielfigur.Picture.Bitmap.TransparentColor := clyellow;
  rSpielfigur.Picture.Bitmap.Transparent := true;
  rSpielfigur.Transparent:=true;
  rSpielfigur.Parent := fenster;
  rkollison1.Height := rSpielfigur.Height;
  rkollison1.Width := rSpielfigur.Width -13;

  T:= 1;
  F := 1;
  Polizeierstellen;
end;
procedure TForm2.EngineTimer(Sender: TObject);
var
index : word;
begin
If not Spiel2.rPause then form2.Caption := 'Aspirin'+' '+ Zeit ;
If Spiel2.rPause then form2.Caption := 'Aspirin'+' '+'Pause';
if Spiel2.rZeit > 0  then
begin
if t1 = 1 then
begin
//showmessage('Jetzt') ;
for index := 0 to Spiel2.anzahl-1 do
 begin

 Spiel2.shpos[index].Bewegung();

  Spiel2.sh[index].Top := Spiel2.shpos[index].rpunkt.Y;
  Spiel2.sh[index].Left := Spiel2.shpos[index].rpunkt.X;
//  sh2[index].Bewegung;

  end;
end;
end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
Zeit := '2:00';
form2.Width := 800;
form2.Height := 600;

Spiel2 := TSpiel2.Create;
Spiel2.rPause := true;

Form2.DoubleBuffered:=True;
end;

procedure TForm2.kollisionTimer(Sender: TObject);
var
index : word;
r : Trect;
begin
if t1 = 1 then
 begin
for index := 0 to Spiel2.anzahl-1 do
 begin
     if intersectrect(r, Spiel2.rkollison1.BoundsRect, Spiel2.sh[index].BoundsRect ) then
     begin
     showmessage('Sie wurden erwischt');
     application.Terminate;
     end;
  end;
 end;
end;


procedure TForm2.Onclose(Sender: TObject; var Action: TCloseAction);
begin
Spiel2.Free;

end;

procedure TForm2.OnkeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if not Spiel2.rPause then
begin
  case key of
  vk_down: begin
             if  Spiel2.rSpielfigur.Top< 520 then
              begin
             Spiel2.rSpielfigur.Top := Spiel2.rSpielfigur.Top + 4;
             Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top;
             Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8;
              end;
           end;
  vk_up: begin
         if not Spiel2.rSpielfigur.Top<0 then
         begin
         Spiel2.rSpielfigur.Top := Spiel2.rSpielfigur.Top -4;
         Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top;
         Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8;
         end;
         end;
  vk_left: begin
           if not Spiel2.rSpielfigur.Left<0 then
           begin
           Spiel2.rSpielfigur.Left:= Spiel2.rSpielfigur.Left -4;
           Spiel2.rSpielfigur.Picture.Bitmap.LoadFromFile(ExtractFilePath(Application.ExeName) + '\Bilder\links.bmp');
           Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top;
           Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8;
           end;
           end;
  vk_right: begin
           if  Spiel2.rSpielfigur.Left < 730 then
           begin
            Spiel2.rSpielfigur.Left:= Spiel2.rSpielfigur.Left +4;
            Spiel2.rSpielfigur.Picture.Bitmap.LoadFromFile(ExtractFilePath(Application.ExeName) + '\Bilder\rechts.bmp');
            Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top;
            Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8;

           end;
            end;


  end;
end;
if key = vk_space then
begin
case   T of
0: begin
   Spiel2.rPause :=true;
   T:=1;
   end;
1: begin
   Spiel2.rPause := false;
   T:=0;
   end;

 end;
end;
end;

procedure TForm2.SpecialTimer(Sender: TObject);
var

sl: TStrings;
r : integer;

begin
spiel2.rZeit:= spiel2.rZeit +1;

   sl := TStringlist.Create;
   sl.Delimiter := ':';
   sl.DelimitedText := Zeit;
   z1 := strtoint(sl[0]);
   z2 := strtoint(sl[1]);
   if z2 = 0  then
   begin
   z1 := z1 -1;
   z2 := 59;
   end;
   z2:= z2-1;
   Zeit := inttostr(z1)+ ':' + inttostr(z2);
   sl.Free;
   r := r+1;
   if r=15 then
   begin
   Spiel2.Polizeierstellen;
   r:=0;
   end;

if spiel2.rZeit = 7200 then Special.Enabled:= false;

end;

destructor Tspiel2.Destroy;
begin
  rSpielfigur.Free;

Polizei.Free;
setlength(sh, 0);
setlength(shpos, 0);
end;

procedure Tspiel2.Erstellen;
begin
   shpos[anzahl]:= TPolizei.Create;
   shpos[anzahl].Bewegung;
   shpos[anzahl].rpunkt.X := 400;
   shpos[anzahl].rpunkt.Y := 600;
   sh[anzahl] := TImage.Create(nil);
   sh[anzahl].Parent:= form2;
   sh[anzahl].Top := 600;
  sh[anzahl].Left := 400;
  sh[anzahl].Picture.Bitmap.LoadFromFile(extractfilepath(application.ExeName) + '\Bilder\Polizei_rechts.bmp');
  sh[anzahl].AutoSize:=true;
  sh[anzahl].Picture.Bitmap.TransparentColor:= clwhite;
  sh[anzahl].Picture.Bitmap.Transparent :=true;
  sh[anzahl].Transparent:=true;
  t1 := 1;

end;

procedure TSpiel2.Polizeierstellen;
begin
 t1 := 0;
  x :=length(shpos);
 //showmessage(inttostr(x)+ ' ' + inttostr(length(shpos))+ ' '+ inttostr(anzahl)+ ' ' + inttostr(length(sh)));
 setlength(sh,x+1);
 setlength(shpos, x+1);


 erstellen;
 if length(shpos)>0 then anzahl := length(shpos);

end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:37 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz