Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Probleme bei Leveleditor (Grid in Array speichern) (https://www.delphipraxis.net/51666-probleme-bei-leveleditor-grid-array-speichern.html)

Red six 16. Aug 2005 21:20


Probleme bei Leveleditor (Grid in Array speichern)
 
Tag leute!


Ich bin grade dabei einen Leveleditor für mein 2D Spiel zu bauen. Ich hab eine ScrollBoxEx (Die ich in diesem Forum gefunden habe, Danke an dieser Stelle) in der eine PaintBox ist auf welche ein Raster gezeichnet wird. Auf klick wird ermittelt in welchem Kästchen die Maus ist (hab ich villeicht etwas kompliziert gemacht aber es geht), dann soll auf Knopfdruck ein Bild in das entsprechende kästchen gezeichnet werden. Dieses wird auch in einem Array gespeichert damit es nicht verschwindet wenn das Raster neu gezeichnet wird. Nun hab ich aber das Problem dass wenn ich mehrere Bilder einfüge manche von ihnen wieder verschwinden... Da muss irgentwo ein Fehler im Array sein! Außerdem bekomme ich beim Beenden den Fehler "Ungültige Zeigeroperation"... Wäre super wenn sich jemand kurz zeitnehmen würde und das ganze mal anschauen würde :thumb:


Ich stell einfach den ganzen source rein!

Delphi-Quellcode:

unit main;

interface

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

type
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    Datei1: TMenuItem;
    Neu1: TMenuItem;
    ffnen1: TMenuItem;
    Speichern1: TMenuItem;
    Speicherunter1: TMenuItem;
    LevelScroller: TScrollBoxEx;
    Grid: TPaintBox;
    MenuPanel: TPanel;
    _xypos: TLabel;
    Label1: TLabel;
    ObjectList: TImageList;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure GridMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure LevelScrollerVScroll(Sender: TObject; Position: Integer);
    procedure LevelScrollerHScroll(Sender: TObject; Position: Integer);
    procedure FormActivate(Sender: TObject);
    procedure DrawGrid;
    function CheckX(X: Integer): Integer;
    function CheckY(Y: Integer): Integer;
    procedure DrawImage(X, Y, ImageIndex: Integer);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type ObjectRec = Record
  X, Y: Integer;
  Filled: Boolean;
  ImageIndex: Integer;
end;


var
  MainForm: TMainForm;
  xPos, yPos: Integer;
  ObjectArray: Array of ObjectRec;

implementation

{$R *.dfm}

procedure TMainForm.DrawGrid;
var
  x, y, i, pixX, pixY: Integer;
  Clear: TRect;
begin
  //GRID

  Grid.Refresh;

  i := 0;

  Clear.Left := 0;
  Clear.Top := 0;
  Clear.Right := Grid.Width;
  Clear.Bottom := Grid.Height;

  Grid.Canvas.Rectangle(Clear);
  Grid.Canvas.Brush.Color := clAppWorkSpace;
  Grid.Canvas.FillRect(Clear);

  for x := 0 to Grid.Width do
  begin
    Grid.Canvas.MoveTo(i, 0);
    Grid.Canvas.LineTo(i, Grid.Height);
    inc(i, 20);
  end;

  i := 0;

  for y := 0 to Grid.Height do
  begin
    Grid.Canvas.MoveTo(0, i);
    Grid.Canvas.LineTo(Grid.Width, i);
    inc(i, 20);
  end;


  //GRID

  //ADD IMAGES

  for i := 0 to (Grid.Width div 20 * Grid.Height div 20) do
  begin
    if ObjectArray[i].Filled = True then
      DrawImage(ObjectArray[i].X, ObjectArray[i].Y, ObjectArray[i].ImageIndex);
  end;

  //ADD IMAGES


  // HIGHLIGHT

  Grid.Canvas.Pen.Color := clYellow;

  pixX := xPos * 20;
  pixY := yPos * 20;

  Grid.Canvas.MoveTo(pixX, pixY);
  Grid.Canvas.LineTo(pixX, pixY+20);
  Grid.Canvas.LineTo(pixX+20, pixY+20);
  Grid.Canvas.LineTo(pixX+20, pixY);
  Grid.Canvas.LineTo(pixX, pixY);
 
  Grid.Canvas.Pen.Color := clBlack;

  //HIGHLIGHT
end;

procedure TMainForm.FormActivate(Sender: TObject);
begin
  DrawGrid;
end;

procedure TMainForm.LevelScrollerHScroll(Sender: TObject; Position: Integer);
begin
  DrawGrid;
end;

procedure TMainForm.LevelScrollerVScroll(Sender: TObject; Position: Integer);
begin
  DrawGrid;
end;

function TMainForm.CheckX(X: Integer): Integer;
var a, b, i, counter: Integer;
begin
  a := 0;
  b := 20;
  Counter := 0;
 
  for i := 0 to Grid.Width do
  begin
    if (X > a) and (X < b) then
      Result := Counter;
    inc(Counter, 1);
    inc(a, 20);
    inc(b, 20);
  end;
end;

function TMainForm.CheckY(Y: Integer): Integer;
var a, b, i, Counter: Integer;
begin
  a := 0;
  b := 20;
  Counter := 0;

  for i := 0 to Grid.Height do
  begin
    if (Y > a) and (Y < b) then
      Result := Counter;
    inc(Counter, 1);
    inc(a, 20);
    inc(b, 20);
  end;
end;

procedure TMainForm.GridMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  _xypos.Caption := 'X: ' + IntToStr(CheckX(X)) + ' Y: ' + IntToStr(CheckY(Y));
  xPos := CheckX(X);
  yPos := CheckY(Y);
  DrawGrid;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
  ObjectList.Draw(Grid.Canvas, xPos*20, yPos*20, 0);
  ObjectArray[xPos*yPos].Filled := True;
  ObjectArray[xPos*yPos].X := xPos;
  ObjectArray[xPos*yPos].Y := yPos;
  ObjectArray[xPos*yPos].ImageIndex := 0;
end;

procedure TMainForm.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  SetLength(ObjectArray, (Grid.Width div 20 * Grid.Height div 20));
 
  for i := 0 to (Grid.Width div 20 * Grid.Height div 20) do
  begin
    ObjectArray[i].X := 0;
    ObjectArray[i].Y := 0;
    ObjectArray[i].Filled := False;
    ObjectArray[i].ImageIndex := 0;
  end;
 
end;


procedure TMainForm.DrawImage(X, Y, ImageIndex: Integer);
begin
  ObjectList.Draw(Grid.Canvas, X*20, Y*20, ImageIndex);
end;

end.
Danke :coder:

CLRS530 17. Aug 2005 10:45

Re: Probleme bei Leveleditor (Grid in Array speichern)
 
Hab es jetzt nur mal gerade überflogen.
Ich kenne solche Fehler, grenz das doch mal ein bisschen ein.
d.h. gucke einmal beim neuzeichnen ob das array richtig gefüllt ist, so kannst du dann mit Gewissheit sagen, das es beim zeichnen passiert, ansonsten kannst du eben feststellen das das adden in das array nicht funktioniert

Red six 17. Aug 2005 11:21

Re: Probleme bei Leveleditor (Grid in Array speichern)
 
Gut und woher kommen diese ganzen Pointer Errors?

Muss ja auch irgentwo am Array liegen :corky:

CLRS530 17. Aug 2005 11:41

Re: Probleme bei Leveleditor (Grid in Array speichern)
 
Was soll denn daran liegen, gehe doch erst einmal dme Fehler mit den verschwindenden Bildern nach, du scheinst da ja irgendwas falsch zu machen.
Dann löst sich vielleicht auch das andere Problem.

Bei so grossen Sachen wo irgendwer einen Fehler findne soll, wirst du nicht viele Antworten erhalten, man muss sich ja auch erst einmal reindenken was du da machst.

Red six 17. Aug 2005 11:58

Re: Probleme bei Leveleditor (Grid in Array speichern)
 
Ja aber ich hab überhaupt keinen durchblick mehr :gruebel:

Das überprüfen funktioniert auch nicht (Hab in ner Listbox einfach immer [i] = 1 oder 0, Filled oder nicht Filled) aber das geht auch nicht... Voll doof :cry:

CLRS530 17. Aug 2005 18:16

Re: Probleme bei Leveleditor (Grid in Array speichern)
 
Achso das Ding verstehe ich jetzt, aber das ist doch doof, wieso machst du das.
Der Eintrag ist doch überflüssig und gerade wenn man mehrere Elemente in den Speicher läd sollte man darauf achten das zu vermeiden.
Gehe doch am Anfang dein ganzes Array durch und setze es auf 0 bzw ""
Dann kannst du doch sehen ob es gefüllt ist oder nicht.

Ich würde es sowieso an dieser Stelle eher mit einer verketteten Liste machen Anstatt mit einem Array.
Vorteil davon, 1. du kannst das Feld, falls du das einmal möchtest vergrössern, das ginge zwar mit Dynamischen Arrays auch, die haben aber einige Nachteile.
2. verbraucht es sehr viel weniger Speicher, da du ja nur für die Felder einen Eintrag erzeugen musst, in denen auch etwas gespeichert wurde und das Speichermanagement für solch eine Liste ist auch besser, da die Daten nicht wie bei einem Array zusammenhängend gespeichert werden.

shmia 17. Aug 2005 18:30

Re: Probleme bei Leveleditor (Grid in Array speichern)
 
Zitat:

Zitat von Red six
Ich bin grade dabei einen Leveleditor für mein 2D Spiel zu bauen. Ich hab eine ScrollBoxEx (Die ich in diesem Forum gefunden habe, Danke an dieser Stelle) in der eine PaintBox ist auf welche ein Raster gezeichnet wird. Auf klick wird ermittelt in welchem Kästchen die Maus ist (hab ich villeicht etwas kompliziert gemacht aber es geht), dann soll auf Knopfdruck ein Bild in das entsprechende kästchen gezeichnet werden. Dieses wird auch in einem Array gespeichert damit es nicht verschwindet wenn das Raster neu gezeichnet wird. Nun hab ich aber das Problem dass wenn ich mehrere Bilder einfüge manche von ihnen wieder verschwinden...

Du machst einen grundsätzlichen Fehler mit der Paintbox.
Auf die Paintbox soll nur aus dem Event OnPaint gezeichnet werden; nicht von ausserhalb.
(die wenigen Ausnahmen lassen wir mal ausser acht)
Der Klick ändert also zuerst den Inhalt in deinem Array.
Danach rufst du. Paintbox.Paint auf.
Die VCL ruft dann das Event OnPaint auf und innerhalb dieses Events liest du das Array aus und zeichnest.

Wenn nun ein "böses" Fenster sich über deine Paintbox legt und es wieder aufdeckt, bleibt keine graue oder schwarze Fläche sichtbar, sondern es wird neu gezeichnet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:08 Uhr.

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