Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Exception Fehler beim neuem Zeichnen (https://www.delphipraxis.net/176320-exception-fehler-beim-neuem-zeichnen.html)

Karvus 27. Aug 2013 09:12

Delphi-Version: XE2

Exception Fehler beim neuem Zeichnen
 
Hallo Delphi-Praxis Gemeinde!

Ich weiß nicht wie das bei euch üblich ist, aber da das mein erster Post ist: Moin ich bin der Karvus und werde euch demnächst öfter mit Fragen nerven weil ich im Zuge meiner Ausbildung aktuell Delphi lerne :thumb:

Nun zu meinem Problem bzw. erstmal zum Background:
Ich versuche aktuell als "Fingerübung" ein Vier Gewinnt spiel nach diesem Tutorial zu programmieren. Aktuell bin ich dabei die "Spielsteine" durch einen klick ins Feld zu bekommen (im Tutorial übrigens hier falls sich unbedingt wer einlesen will :) ). Das mache ich mit dem MouseDown Ereignis der Paintbox. Soweit alles klar und von mir denke ich auch verstanden.
Jetzt zum Problem:
Wenn ich meinen Code compilieren will funktioniert auch alles ganz super. Bis mein Resize Ereignis der Form aufgerufen wird, ich also das Fenster bewege, in dem wiederum nur die Methode GroessenEinstellungenAnpassen
Delphi-Quellcode:
procedure TForm1.GroessenEinstellungenAnpassen;
begin
  FGrafik.Width := pbxAnzeigeflaeche.Width;   //Größe verstellen
  FGrafik.Height := pbxAnzeigeflaeche.Height;
  FLinks := FGrafik.Width div 2 - FSpielfeldBreite div 2 * FFelderbreite;
  FUnten := FGrafik.Height div 2 + FSpielfeldHoehe div 2 * Ffelderbreite;

  SymbolErstellen(FFelderbreite-1, sSpieler1);
  SymbolErstellen(FFelderbreite-1, sSpieler2);
  SymbolErstellen(1, sLeer);
end;
aufgerufen wird (weswegen der Satz im nachhinein garnicht so nötig ist :oops:...). Da kommt der Fehler

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project1.exe ist eine Exception der Klasse $C0000005 mit der Meldung 'access violation at 0x005b41d8: read of address 0x00fcc1e4' aufgetreten.
---------------------------
Anhalten Fortsetzen Hilfe
---------------------------


Wenn ich jetzt aber "anhalte" erscheint mein Fehler aber in Zeile 124
Delphi-Quellcode:
FGrafik.Canvas.Draw(FLinks + i* FFelderbreite+1,
      FUnten - (j+1) * FFelderbreite + 1, FSpielerBmp[FSpielfeld[i,j]]);
und das ist in einer ganz anderen funktion :wiejetzt: . Die beiden haben doch nichts miteinander zu tun, außer dass sie bei FGrafik verwenden oder?

Hoffe ihr könnt mir helfen.

P.S.:
Wenn starte kommt die manchmal auch direkt aber nicht immer was ich noch weniger versteh.

Hier ist der Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TFeldbesetzung = (sLeer, sSpieler1, sSpieler2);
  TForm1 = class(TForm)
    Panel1: TPanel;
    pnlSpieler: TPanel;
    pbxAnzeigeflaeche: TPaintBox;
    btNeu: TButton;
    btLaden: TButton;
    btSpeichern: TButton;
    btEinstellungen: TButton;
    btBeenden: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure pbxAnzeigeflaechePaint(Sender: TObject);
    procedure btNeuClick(Sender: TObject);
    procedure pbxAnzeigeflaecheMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private-Deklarationen }
    FSpielfeld: array [0..6, 0..5] of TFeldBesetzung;
    FGrafik : TBitmap;
    FLinks, FUnten : Integer;
    FSpielfeldBreite,FSpielfeldHoehe, FFelderBreite : Integer;
    FSpielerFarbe: array[TFeldBesetzung] of TColor;
    FSpielerbmp: array[TFeldBesetzung] of TBitmap;
    FSpielerName: array[TFeldBesetzung] of string;
    FAktiverSpieler: TfeldBesetzung;
    Spielaktiv: boolean;

    procedure GitterZeichnen (breite, hoehe, feldbreite: Integer);
    procedure Darstellen;
    procedure GroessenEinstellungenAnpassen;
    procedure SymbolErstellen (breite: Integer; spieler : TFeldBesetzung);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.btNeuClick(Sender: TObject);
var
i,j : Integer;
begin                                     //Felder als leer deklarieren
  for i := 0 to FSpielfeldBreite - 1 do
    begin
  for j := 0 to FSpielfeldhoehe - 1 do
    FSpielfeld[i,j] := sLeer;
    end;
  Spielaktiv := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FGrafik := TBitmap.Create;      //Bitmap erstellen
  FSpielfeldbreite :=7;
  FSpielfeldhoehe := 6;
  FFelderBreite := 25;

  FSpielerBmp[sSpieler1] := TBitmap.Create;  //3 Bitmaps für jeweilige Spieler und leer im Array
  FSpielerBmp[sSpieler2] := TBitmap.Create;
  FSpielerBmp[sLeer] := Tbitmap.Create;
  FSpielerFarbe[sLeer] := clWhite;
  FSpielerFarbe[sSpieler1] := clGreen;
  FSpielerFarbe[sSpieler2] := clRed;
  FSpielerName[sLeer] := 'Leer';
  FSpielerName[sSpieler1] := 'Spieler 1';
  FSpielerName[sSpieler2] := 'Spieler 2';

  if random(1) =0 then                         //Zufälliger aktiver Spieler
   FAktiverSpieler := sSpieler1
  else
   FAktiverSpieler := sSpieler2;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
FGrafik.Free;
FSpielerBmp[sSpieler1].Free;
FSpielerBmp[sSpieler2].Free;
FSpielerBmp[sLeer].Free;
end;

procedure TForm1.GroessenEinstellungenAnpassen;
begin
  FGrafik.Width := pbxAnzeigeflaeche.Width;   //Größe verstellen
  FGrafik.Height := pbxAnzeigeflaeche.Height;
  FLinks := FGrafik.Width div 2 - FSpielfeldBreite div 2 * FFelderbreite;
  FUnten := FGrafik.Height div 2 + FSpielfeldHoehe div 2 * Ffelderbreite;

  SymbolErstellen(FFelderbreite-1, sSpieler1);
  SymbolErstellen(FFelderbreite-1, sSpieler2);
  SymbolErstellen(1, sLeer);
end;

procedure TForm1.Darstellen;
var
I,j : Integer;
begin
  FGrafik.Canvas.Pen.Color := clBlack;           //Weißes Feld zeichnen
  FGrafik.Canvas.Brush.Color := clWhite;
  FGrafik.Canvas.Rectangle(0,0,FGrafik.Width, FGrafik.Height);

  GitterZeichnen(FSpielfeldBreite, FSpielfeldHoehe, FFelderBreite); //Gitter erstellen & auf der Paintbox zeichnen
  pbxAnzeigeflaeche.Canvas.Draw(0,0,FGrafik);

  for I := 0 to FSpielfeldBreite - 1 do
   Begin
      FGrafik.Canvas.Draw(FLinks + i* FFelderbreite+1,
      FUnten - (j+1) * FFelderbreite + 1, FSpielerBmp[FSpielfeld[i,j]]);
   end;

end;

procedure TForm1.pbxAnzeigeflaecheMouseDown(Sender: TObject; //erkennt wo Stein gesetzt werden soll
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i, spalte, zeile: Integer;
  begin                                                     //erkennt Spalte
   spalte := (x - FLinks) div FFelderBreite;
   if (spalte > FSpielfeldbreite-1) or (x < FLinks) then Exit;

   i := 0;
   while FSpielfeld[spalte,i] <> sLeer do                   //erkennt Zeile
    begin
     Inc(i);
     if i > FSpielfeldHoehe - 1 then Exit;
    end;
   zeile := i;

   FSpielfeld [spalte, zeile] := FAktiverSpieler;           //setzt Stein des aktiven Spielers

   if SpielAktiv then                                       //Spieler wechseln
    begin
      if FAktiverSpieler = sSpieler1 then
         FAktiverSpieler := sSpieler2
      else
         FAktiverSpieler := sSpieler1;
    end;

   Darstellen                                              //Grafische Ausgabe des Zuges
end;

procedure TForm1.pbxAnzeigeflaechePaint(Sender: TObject);
begin
Darstellen;
end;

procedure TForm1.SymbolErstellen (breite: Integer; spieler : TFeldBesetzung);
begin
  FSpielerBmp [spieler].Width := breite;       //Größe der Kreise einstellen
  FSpielerBmp [spieler].height := breite;

  FSpielerBmp[spieler].Canvas.Pen.Color := clWhite;      //Felder leeren
  FSpielerBmp[spieler].Canvas.Brush.Color := clWhite;
  FSpielerBmp[spieler].Canvas.Rectangle(0, 0,breite, breite);

  FSpielerBmp[spieler].Canvas.Pen.Color := FSpielerFarbe[spieler]; //Kreis in Spielerfarbe erstellen
  FSpielerBmp[spieler].Canvas.Brush.Color := FSpielerFarbe[spieler];
  FSpielerBmp[spieler].Canvas.Ellipse(0, 0, breite, breite)

end;

procedure TForm1.FormResize(Sender: TObject);
begin
GroessenEinstellungenAnpassen
end;

procedure TForm1.GitterZeichnen(breite, hoehe, feldbreite: Integer);
var
i : Integer;
begin
  FGrafik.Canvas.Pen.Color := clBlack;
  for i := 0 to hoehe do
    begin
      FGrafik.Canvas.MoveTo(FLinks, Funten - i * feldbreite);
      FGrafik.Canvas.LineTo(FLinks + breite * feldbreite, FUnten - i * feldbreite)
    end;
  for i := 0 to breite do
    begin
      FGrafik.Canvas.MoveTo(FLinks + i*feldbreite, FUnten - hoehe * feldbreite);
      FGrafik.Canvas.LineTo(FLinks + i*feldbreite, FUnten);
    end;
end;


end.
Link zum Crosspost: http://forum.delphi-treff.de/index.p...656#post435656

baumina 27. Aug 2013 09:27

AW: Exception Fehler beim neuem Zeichnen
 
Delphi-Quellcode:
procedure TForm1.Darstellen;
var
 I,j : Integer;
begin
   FGrafik.Canvas.Pen.Color := clBlack; //Weißes Feld zeichnen
   FGrafik.Canvas.Brush.Color := clWhite;
   FGrafik.Canvas.Rectangle(0,0,FGrafik.Width, FGrafik.Height);

   GitterZeichnen(FSpielfeldBreite, FSpielfeldHoehe, FFelderBreite); //Gitter erstellen & auf der Paintbox zeichnen
   pbxAnzeigeflaeche.Canvas.Draw(0,0,FGrafik);

   for I := 0 to FSpielfeldBreite - 1 do
    Begin
       FGrafik.Canvas.Draw(FLinks + i* FFelderbreite+1,
       FUnten - (j+1) * FFelderbreite + 1, FSpielerBmp[FSpielfeld[i,j]]);
    end;

end;
Die lokale Variable j wird nicht initialisiert.

DeddyH 27. Aug 2013 09:31

AW: Exception Fehler beim neuem Zeichnen
 
Das sollte der Compiler auch melden. Im Übrigen empfehle ich http://www.delphipraxis.net/41047-tu...ortgeschr.html.

Karvus 27. Aug 2013 09:44

AW: Exception Fehler beim neuem Zeichnen
 
@baumina: stimmt :wall: danke!

Zitat:

Zitat von DeddyH (Beitrag 1226382)
Das sollte der Compiler auch melden.[/URL].

Danke das hätte mich jetzt wirklich weitergebracht.

Zitat:

Zitat von DeddyH (Beitrag 1226382)

Das werde ich mir jetzt erstmal durchlesen bevor ich weitermache, danke.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:39 Uhr.

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