AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Andorra 2D - Tutorial 2 - Das erste Bild

Andorra 2D - Tutorial 2 - Das erste Bild

Ein Tutorial von igel457 · begonnen am 30. Jan 2007 · letzter Beitrag vom 7. Aug 2009
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von igel457
igel457
Registriert seit: 31. Aug 2005
Das Tutorial findet sich in der Originalversion hier

Andorra 2D Tutorials
Teil 2 - Die erste Grafik


Einleitung
Im letzten Tutorial haben Sie gelernt, wie Sie Andorra 2D initialisieren. Herausgekommen ist ein schwarzes Fenster. Doch dieses hätten wir auch viel einfacher haben können. Darum geht es jetzt mit unserem Beispielprogramm weiter - wir laden ein Bild und zeigen dieses an.

Die Liste der Images
Was wir als erstes benötigen, ist eine so genannte "ImageList". Diese verwaltet alle Bilder die wir in Sie herein geladen haben äußerst komfortabel.
Nun benötigen wir als erstes eine Variable des Typs "TAdImageList", die wir "AdImageList" nennen und in FormCreate erzeugen. Dabei ist darauf zu achten, dass die Liste erst nach dem Aufruf von AdDraw.Initialize erzeugt werden darf. Also schreiben wir unter der Zeile "Application.OnIdle := Idle" weiter:
AdImageList := TAdImageList.Create(AdDraw); Nun wollen wir ein Bild zu der Liste hinzufügen. Dies geschieht über folgenden Code:
Delphi-Quellcode:
with AdImageList.Add('bild') do //Zu der Liste wird ein Bild mit dem Namen "bild" hinzugefügt.
begin
  Texture.LoadGraphicFromFile('textur.bmp'); //In die Textur wird ein Bild hineingeladen.
end;
AdImageList.Restore; //Dazu kommen wir später
Die Funktion "Add" der Imagelist fügt ein Bild des Typs "TAdImage" mit entsprechendem Namen hinzu und gibt dieses als Rückgabewert zurück.

Warum hat dieses "TAdImage" jetzt nochmal ein Unterobjekt "Texture"? Sind ein Bild und eine Textur nicht das gleiche? Wie das nächste Bild verdeutlicht gilt dies in Andorra 2D nicht ganz...
http://andorra.sourceforge.net/tutots/image.png
Bei einem Image, also dem Objekt, dass wir gerade der Imagelist hinzugefügt haben, handelt es sich nur um eine Art Grundgerüst, auf das die Textur gezeichnet wird. Das "Image" oder "Bild" ist also nur eine Leinwand, die Textur dagegen ist das, was darauf gezeichnet wird.

Jetzt muss nur eine Unklarheit beseitigt werden: Die Aufgabe der Prozedur "Restore". Ruft man die "Restore" Funktion der Imagelist auf, so macht diese nichts anderes als die "Restore" Funktion der einzelnen Bilder aufzurufen. Folgender Code würde also das gleiche machen:
Delphi-Quellcode:
with AdImageList.Add('bild') do //Zu der Liste wird ein Bild mit dem Namen "bild" hinzugefügt.
begin
  Texture.LoadGraphicFromFile('textur.bmp',false,clNone); //In die Textur wird ein Bild ohne Transparenz hineingeladen.
  Restore;
end;
Allerdings ist diese Methode etwas umständlich, wenn man seiner Imagelist viele Einträge hinzufügt.
Nun muss nur noch geklärt werden, was dieses "Restore" macht. Erinnern wir uns an das Bild von oben: Das Image ist nur ein Gerüst, auf das die Textur gezeichnet wird. Nun kann das Gerüst nicht wissen wie groß die Textur, welche wir geladen haben, ist. Deshalb wird bei dem Aufruf der Funktion "Restore" das Gerüst mit entsprechender Größe neu gebildet und entsprechende Verknüpfungen gesetzt. Vergisst man den aufruf von Restore, so erhält man aller Wahrscheinlichkeit nach eine Fehlermeldung.


Das Laden der Bilder
Die Textur bietet die nachfolgenden Prozeduren, die sich irgendwie nach Laden und Speichern von Bildern anhören:
Delphi-Quellcode:
procedure LoadFromStream(AStream:TStream);
procedure SaveToStream(AStream:TStream);
procedure SaveToFile(AFile:string);
procedure LoadFromFile(AFile:string);

procedure LoadGraphicFromFile(AFile:string;Transparent:boolean;TransparentColor:TColor);
procedure LoadFromGraphic(AGraphic:TGraphic);
Um Grafiken direkt zu laden sind nur die letzten beiden Methoden relevant. Die ersten vier schreiben die Textur in ein Andorra 2D eigenes Dateiformat und eigenen sich nicht um "normale" Grafikdateien zu laden.
LoadFromGraphic besorgt sich Transparenzparameter direkt aus der zu ladenden Grafik. Standardmäßig kann Andorra 2D alle Standardgrafikformate der VCL Laden - also *.bmp (Bitmap), *.dib (Device Interpendent Bitmap) und *.wmf (Windows Meta File). Um andere Formate laden zu können müssen entsprechende Loader-Bibliotheken zur uses-Liste hinzugefügt werden. Diese Bibliotheken fügen sich beim Programmstart zu einer Liste in der Unit AdDraws hinzu. Absofort kann Andorra 2D dann diese Formate laden und (wenn entsprechend implementiert) auch speichern. Um PNG-Bilder zu laden muss die Unit "AdPNG" zur Uses-Liste hinzugefügt werden. Für JPEG-Bilder die Unit "AdJPEG". Meist sind zum laden der Bilder weitere Bibliotheken nötig. Diese müssen unabhängig von Andorra 2D installiert werden. Für das PNG-Format ist die Bibliothek "PNGDelphi" (http://pngdelphi.sourceforge.net/) von nöten.

Vorhang auf
Nun sind wir nur noch einen kleinen Schritt davon entfernt unser erstes Bild auf den Bildschirm zu zaubern. Folgende Zeile, die wir in der Prozedur "Idle" zwischen "BeginScene" und "EndScene" einfügen, erledigt dies:

AdImageList.Find('bild').Draw(AdDraw1,0,0,0); Was bedeuten nun diese vier Parameter der Prozedure "Draw"? AdDraw1 ist hierbei das so genannte "Surface", d.h. die "Oberfläche" auf die gezeichnet wird. Geben Sie hier vorerst immer das Objekt welches der ImageList als Parameter bei "Create" übergeben wurde (in unserem Fall also AdDraw1) an. Die beiden nächsten Parameter spezifizieren die Position auf dem Bildschirm, an denen das Image gezeichnet werden soll. Der dritte Parameter gibt den so gennannten "PatternIndex" an, der für Animationen zuständig ist, aber dazu kommen wir später.

Nun gibt es nicht nur die Funktion "Draw" alleine um Bilder zu zeichnen, das wäre auch etwas wenig. Das TPictureCollectionItem Objekt stellt noch die folgenden Prozeduren zur Verfügung:
Delphi-Quellcode:
//Einfachste Zeichenmethode
procedure Draw(Dest:TAdDraw;X,Y,PatternIndex:integer);

//Zeichnet ein Bild gestreckt
procedure StretchDraw(Dest:TAdDraw;const DestRect:TAdRect;PatternIndex:integer);
//Zeichnet ein Bild gestreckt und um einen bestimmten Alphawert (von 0 wie durchsichtig bis 255 wie komplett Opac) transparent.
procedure DrawAlpha(Dest: TAdDraw; const DestRect: TAdRect; PatternIndex: Integer; Alpha: Integer);
//Zeichnet ein Bild gestreckt mit additiver Farbmischung und um einen bestimmten Alphawert(von 0 wie durchsichtig bis 255 wie komplett Opac) transparent.
procedure DrawAdd(Dest: TAdDraw; const DestRect: TAdRect; PatternIndex: Integer; Alpha: Integer);
//Zeichnet ein gestrecktes Bild komplett Schwarz und um einen bestimmten Alphawert(von 0 wie durchsichtig bis 255 wie komplett Opac) transparent.
procedure DrawMask(Dest: TAdDraw; const DestRect: TAdRect; PatternIndex: Integer; Alpha: Integer);

//Zeichnet ein Bild rotiert. Angle ist ein Wert von 0 Grad bis 360 Grad. CenterX und CenterY bezeichnen hier Mittelpunkt der Rotation. Die beiden Werte gehen von 0 bis 1. Somit gibt 0.5 und 0.5 genau die Mitte eines Bildes an.
procedure DrawRotate(Dest: TAdDraw; X, Y, Width, Height: Integer; PatternIndex: Integer; CenterX, CenterY: Double; Angle: Integer);
procedure DrawRotateAdd(Dest: TAdDraw; X, Y, Width, Height: Integer; PatternIndex: Integer; CenterX, CenterY: Double; Angle: Integer; Alpha: Integer);
procedure DrawRotateAlpha(Dest: TAdDraw; X, Y, Width, Height: Integer; PatternIndex: Integer; CenterX, CenterY: Double; Angle: Integer; Alpha: Integer);
procedure DrawRotateMask(Dest: TAdDraw; X, Y, Width, Height: Integer; PatternIndex: Integer; CenterX, CenterY: Double; Angle: Integer; Alpha: Integer);

//Ähnlich wie StretchBlt aus der Windows GDI. Zeichnet einen bestimmten ausschnitt aus einem Bild vergrößert oder verkleinert.
procedure StretchBltAlpha(Dest:TAdDraw; SourceRect,DestRect:TAdRect;CenterX,CenterY:integer;Angle:Integer;Alpha:Integer);
procedure StretchBltAdd(Dest:TAdDraw; SourceRect,DestRect:TAdRect;CenterX,CenterY:integer;Angle:Integer;Alpha:Integer);
Am besten probieren Sie diese Methoden mal an unserem Beispielbild aus. Auf einige werde ich aber auch nochmal im Verlauf der Tutoriale eingehen. Wie Sie vielleicht bemerkt haben verwendet Andorra 2D eigene Typen wie zum Beispiel "TAdRect", welche sich in der Unit "AdTypes" befinden. Somit muss die VCL-Unit "Types" bzw. "Windows" nicht verwendet werden.


Vollbild
Viele Spiele laufen ja im Vollbildmodus ab. Auch diesen können Sie in Andorra 2D einfach Einstellen. Dazu müssen Sie sich in die "OnCreate" Funktion von Form1 begeben. Fügen Sie vor AdDraw1.Initialize folgende Zeilen ein:
Delphi-Quellcode:
AdDraw.Options := AdDraw.Options+[doFullscreen];
AdDraw.Display.Width := 800;
AdDraw.Display.Height := 600;
AdDraw.Display.BitCount := 32; //Die Farbtiefe. Hierbei sind 16 und 32 Bit erlaubt.
Wichtig zu beachten ist, dass die Grafikausgabe des AdDraws auf einem TForm stattfinden muss, sonst funktioniert die Vollbilddarstellung nicht.

Schon läuft Ihre Andorra 2D Anwendung im Vollbildmodus ab. Sie müssen allerdings beachten, dass ihr Monitor und ihre Grafikkarte die entsprechenden Auflösungen unterstützen. Es gibt auch einen kleinen Trick, mit dem Sie Vollbild erreichen, ohne die Auflösung umändern zu mussen. Scheiben Sie anstatt den Zeilen oben einfach:
Delphi-Quellcode:
BorderStyle := bsNone;
Top := 0;
Left := 0;
Width := Screen.Width;
Height := Screen.Height;
Damit wird nur die Größe ihres Formulars verändert.


Bewegungen und Animationen
Am besten löschen Sie alle Änderungen, die Sie in diesem Tutorial bis jetzt gemacht haben, wieder aus dem Programm heraus.

Nun möchten wir mal eine animierte Figur über den Bildschirm wandern lassen. Diese soll sobald sie über den einen Bildschirmrand herausgelaufen ist wieder auf einer beliebigen Y Position zurücklaufen.
Dazu benötigen wir erst einmal das Bild der animierten Figur - und so sieht es aus:
http://andorra.sourceforge.net/tutots/pattern.png
Wie wir sehen ist dieses Bild praktisch wie eine Art Filmstreifen aufgebaut. Um ein einzelnes Bild aus der Animation anzuzeigen, wird einfach nur ein Ausschnitt aus der Textur gezeichnet.
Sie werden jetzt vielleicht denken, warum wir nicht für jeden Schritt der Animation (auch Frame oder Pattern genannt) eine eigene Bilddatei haben. Dies wäre aber schlichtweg inneffektiv, da es für die Grafikkarte besser ist eine Textur der Größe 512x512 zu verwalten, anstatt viele kleine, der Größe 128x128.

Das Bild der Figur gibt es hier zum herunterladen. Es stammt übrigens von Rainer's Tilesets. Dort gibt es jede menge Figuren, Objekte und noch vieles mehr für den Einstatz in 2D Spielen.

Als erstes müssen wir das Bild mit den Animationen in die Engine laden. Dies machen wir fast so wie vorher:
Delphi-Quellcode:
AdImageList := TAdImageList.Create(AdDraw);
with AdImageList.Add('figur') do
begin
  Texture.LoadGraphicFromFile('boy.bmp',true,clFuchsia); // Dieses mal laden wir das Bild transparent herein
  PatternWidth := 96;
  PatternHeight := 96;
end;
AdImageList.Restore;
Mit PatternWidth und PatternHeight werden die Höhe und Breite eines Frames gesetzt, in unserem Fall also auf 96. Mit dem Aufruf der Restore Anweisung erstellt Andorra 2D eine Art Karte, auf der Sie Nummer und Position jedes einzelnen Frames speichert. Und zwar nummeriert Andorra von links nach rechts und dann von oben nach unten. Außerdem beginnt die Nummerierung bei Null, wie auf dem Bild oben dargestellt.

Wenn Sie nun ein einzelnes Frame aus der Animation zeichnen möchten, dann kommt das "PatternIndex" der Zeichenfunktion ins Spiel. Hier kann man einfach die Nummer des Frames angeben und schon wird dieses gezeichnet.

Wir wollten die Figur ja aber über den Bildschirm laufen lassen. Also kümmern wir uns als erstes mal um die Animation. Dazu benötigen wir eine Variable des Typs "Single" oder "Double". Warum es kein einfacher Integer sein kann, sehen Sie später. Also fügen wir im Interface Teil des Programms unter den Variablendeklarationen eine Variable "Pattern" hinzu, sodass diese Zeile dann ungefähr so aussieht:
Delphi-Quellcode:
var
  Form1: TForm1;
  Pattern:single;
In "Idle" zählen wir Pattern nun jeden Schritt um eins hoch, und zeichnen die Figur dann anschließend. Außerdem müssen wir überprüfen, ob Pattern ggf. die Patternanzahl übersteigt und wenn ja, Pattern wieder auf Null setzen:
Delphi-Quellcode:
Pattern := Pattern + 1;
if Pattern >= AdImageList.Items[0].PatternCount-1 then Pattern := 0;
AdImageList1.Items[0].Draw(AdDraw1,0,0,round(Pattern));
Beim Ausführen sieht man jedoch, dass die Animation viel zu schnell von statten geht. Schließlich wird die Renderschleife bis zu 5000 mal in der Sekunde ausgeführt und Pattern damit um 5000 erhöht. Natürlich könnten wir nun anstatt +1 z.B. +0.001 schreiben, dann würde die Animation langsamer ablaufen. Jedoch haben wir dann das, im ersten Tutorial angesprochene Problem, dass die Animation nicht auf allen PCs gleich schnell abläuft. Um dieses Problem zu umfahren, gibt es in Andorra 2D ein weiteres Objekt: Den so genannten "TAdPerformanceCounter", den wir in der Unit "AdPerformanceCounter" finden. Also deklarieren wir eine neue Variable des Typs TAdPerformanceCounter mit dem Namen "AdPerCounter", erzeugen eine instanz der Klasse in FormCreate und geben diese in FormDestroy wieder hübsch frei, so wie wir dies auch mit allen anderen Objekten gemacht haben.
In der "Idle" Prozedur schreiben wir nun ziemlich am Anfang "AdPerCounter.Calculate".
Damit berrechnet das Objekt den Zeitabstand zwischen den Prozedurdurchläufen außerdem werden auch die bekannten FPS (Frames per second), die Sie vielleicht aus einigen Spielen kennen und die ein wichtiger Indikator für die Leistung sind, berrechnet. Mit dem Zeitabstand in Millisekunden, der in der Variable "AdPerCounter.TimeGap" vorliegt, können wir nun eine Animation erreichen, die auf fast PCs dieser Welt gleich schnell abläuft. Und zwar so:
Delphi-Quellcode:
AdPerCounter.Calculate;
Pattern := Pattern + 15 * (AdPerCounter.TimeGap / 1000);
Fünfzehn spezifiziert hier die Anzahl der Frames pro Sekunde mit der die Animation abläuft. Beim ausführen sollte die Animation nun schön langsam ablaufen und auch noch auf jedem Rechner gleich.

Unser Ziel war es ja, die Figur über den Bildschirm zu bewegen. Doch abgesehen davon, dass sie jetzt schön Animiert ist, fehlt es noch an Bewegung. Nun benötigen wir erst einmal eine Handvoll neuer Variablen, die wir bei den anderen Deklarieren:
Delphi-Quellcode:
StartPt,EndPt:integer; //Das Start- und das Endpattern der Animation
Y,X:single; //Die X und die Y Position der Figur
XSpeed:single; //Die Geschwindigkeit in X-Richtung
Um die Figur zu bewegen müssen wir die "Draw"-Routine etwas erweitern:
AdImageList1.Find('figur').Draw(AdDraw1,round(X),round(Y),round(Pattern)); Nun wird die Figur an der Position X und Y gezeichnet.
Um Sie zu bewegen schreiben wir über die Zeichenfunktion folgendes:
X := X + XSpeed * (AdPerCounter.TimeGap / 1000); Außerdem soll sich die Animation nur im Rahmen von "StartPt" zu "EndPt" bewegen. Also passen wir die eine "if" Abfrage ein wenig an:
if Pattern >= EndPt then Pattern := StartPt; Nun brauchen wir nur noch eine Prozedur, die den Richtungswechsel der Figur verwaltet. Wir nennen Sie "SetLine", da auch die Y-Position der Figur verändert wird. "SetLine" sollte innerhalb von TForm1 Deklariert sein.
Delphi-Quellcode:
procedure TForm1.SetLine;
begin
  //Die Richtung umkehren
  XSpeed := -XSpeed;
  
  if XSpeed > 0 then
  begin
    StartPt := 0;
    EndPt := 7;
    X := -96;
  end
  else
  begin
    StartPt := 8;
    EndPt := 15;
    X := ClientWidth+96;
  end;
  
  //Die Y-Position setzen
  Y := Random(ClientHeight-96);
end;
Außerdem brauchen wir folgende Zeile in der "Idle"-Prozedur, die sich darum kümmert die Prozedur aufzurufen, wenn die Figur den Bildschirmrand verlässt:
Delphi-Quellcode:
if ((X > ClientWidth) and (XSpeed > 0)) or
   ((X < -96) and (XSpeed < 0)) then SetLine;
Nun müssen wir nur noch in FormCreate XSpeed setzen und die Prozedur "SetLine" ein erstes mal aufrufen:
Delphi-Quellcode:
XSpeed := -150;
SetLine;
Und schon rennt unsere Figur beim Ausführen über den Bildschirm.

Der Sourcecode
Wie immer, als Referenz noch mal der Sourcecode:

Delphi-Quellcode:
unit Main;

interface

uses
  Windows, Dialogs, SysUtils, Graphics, Classes, Forms, AdDraws, AdClasses, AdTypes,
  AdPerformanceCounter;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    AdDraw:TAdDraw;
    AdPerCounter:TAdPerformanceCounter;
    AdImageList:TAdImageList;
    procedure Idle(Sender:TObject;var Done:boolean);
    procedure SetLine;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Pattern:single;
  StartPt,EndPt:integer;
  Y,X:single;
  XSpeed:single;

implementation

{$R *.dfm}

procedure TForm1.SetLine;
begin
  XSpeed := -XSpeed;
  if XSpeed > 0 then
  begin
    StartPt := 0;
    EndPt := 7;
    X := -96;
  end
  else
  begin
    StartPt := 8;
    EndPt := 15;
    X := ClientWidth+96;
  end;
  Y := Random(ClientHeight-96);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := true;
  AdPerCounter := TPerformanceCounter.Create;

  AdDraw := TAdDraw.Create(self);
  AdDraw.DllName := 'AndorraDX93D.dll';

  if AdDraw.Initialize then
  begin
    Application.OnIdle := Idle;
    AdImageList := TAdImageList.Create(AdDraw);
    with AdImageList.Add('figur') do
    begin
      Texture.LoadGraphicFromFile('boy.bmp',true,clFuchsia);
      PatternWidth := 96;
      PatternHeight := 96;
    end;
    AdImageList.Restore;

    XSpeed := -150;

    Randomize;
    SetLine;
  end
  else
  begin
    ShowMessage('Error while initializing Andorra 2D. Try to use another display '+
                'mode or another video adapter.');
    Close;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  AdImageList.Free;
  AdPerCounter.Free;
  AdDraw.Free;
end;

procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
  if AdDraw.CanDraw then
  begin
    AdPerCounter.Calculate;
    Caption := 'FPS:'+inttostr(AdPerCounter.FPS);

    Pattern := Pattern + 15*AdPerCounter.TimeGap/1000;
    if Pattern >= EndPt then Pattern := StartPt;

    X := X + XSpeed*AdPerCounter.TimeGap/1000;
    if ((X > ClientWidth) and (XSpeed > 0)) or
       ((X < -96) and (XSpeed < 0)) then SetLine;


    AdDraw.ClearSurface(clBlack);
    AdDraw.BeginScene;

    AdImageList.Find('figur').Draw(AdDraw1,round(X),round(Y),round(Pattern));
    AdDraw.EndScene;
    AdDraw.Flip;

    Done := false;
  end;
end;

end.
Fazit
Nun haben wir schon eine Animierte Figur erzeugt, jedoch war das ganze immer noch ein wenig umständlich. In den nächsten Tutorials werden wir uns desahlb einen in Andorra 2D integrierten Lösungsansatz anschauen: Die so genannte SpriteEngine. Mit ihrer Hilfe kann man jede Art von Spielen programmieren - ohne großen Aufwand.


Copyright und Lizenz
(c) by Andreas Stöckel Januar 2007

Revision 2: Oktober 2007
Revision 3: Dezember 2007

Der Inhalt dieses Tutorials steht unter der GNU Lizenz für freie Dokumentation.

[edit=Matze]Tutorial aktualisiert (27.12.07). MfG, Matze[/edit]
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
 
smgdennis
 
#2
  Alt 17. Apr 2008, 21:41
Unter Vista brauch man Admin Rechte um all das auzuführen. Nur als kleiner Tipp
  Mit Zitat antworten Zitat
oneP

 
Turbo Delphi für Win32
 
#3
  Alt 6. Jun 2009, 14:18
Hallo,

und woher krieg ich eine AdImageList? Ist das einfach eine Imagelist die man umbennenen muss (was ich eher nicht glaub) ? Weil bei mir wird AdImageList rot unterstrichen.

Sorry das ist mein erster Tag mit Andorra 2D...
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

 
FreePascal / Lazarus
 
#4
  Alt 6. Jun 2009, 15:30
Du musst die Unit AdDraws einbinden und eine Objektvariable des Typs "TAdImageList" deklarieren - so wie es im Beispiel unten getan ist.

Andorra 2D verwendet keine Komponenten, die du zur Designzeit auf dein Formular ziehen kannst!
Andreas
  Mit Zitat antworten Zitat
Haxler
 
#5
  Alt 7. Aug 2009, 10:23
Hi, immer wenn ich das Programm starte, kommt eine Fehlermeldung:

[delphi]
Access violation at address 00450256 in module 'Project1.exe'. Read of address 00000018.

Was mach ich falsch? Bitte helft mir.

mfg
  Mit Zitat antworten Zitat
Vasco da Gama

 
Delphi 2009 Professional
 
#6
  Alt 7. Aug 2009, 10:31
Hallo, dafür musst du uns etwas Code zeigen. Es könnte zum beispiel sein, dass du z.B. auf AdDraw zugreifst bevor es Created wird.

mfG
Flo
  Mit Zitat antworten Zitat
Haxler
 
#7
  Alt 7. Aug 2009, 10:46
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,AdDraws, AdClasses, AdTypes, ImgList, AdPerformanceCounter;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
   AdDraw:TAdDraw;
   AdPerCounter:TAdPerformanceCounter;
   AdImageList:TAdImageList;
   procedure Idle(Sender:TObject; var Done:boolean);


  end;

var
  Form1: TForm1;
  Pattern:single;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin

AdDraw := TAdDraw.Create(self);
AdDraw.DllName := 'AndorraDX93D.dll';

if AdDraw.Initialize then
begin
  Application.OnIdle := Idle;
  AdImageList := TAdImageList.Create(AdDraw);
with AdImageList.Add('figur') do
begin
  Texture.LoadGraphicFromFile('boy.bmp',true,clFuchsia); // Dieses mal laden wir das Bild transparent herein
  PatternWidth := 96;
  PatternHeight := 96;
end;
AdImageList.Restore;


end
else
begin
  ShowMessage('Andorra 2D konnte nicht richtig initialisiert werden!');
  halt;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
AdDraw.Free;
AdPerCounter.free;
end;

procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
  if AdDraw.CanDraw then //Wenn überhaupt auf das AdDraw gezeichnet werden kann dann...
  begin
AdPerCounter.Calculate;
Pattern := Pattern + 15 * (AdPerCounter.TimeGap / 1000);
AdDraw.ClearSurface(clBlack); //Füllt die Oberfläche mit schwarzer Farbe

AdDraw.BeginScene;
Pattern := Pattern + 1;
if Pattern >= AdImageList.Items[0].PatternCount-1 then Pattern := 0;
AdImageList.Items[0].Draw(AdDraw,0,0,round(Pattern));
AdDraw.EndScene;

AdDraw.Flip; //Präsentiert die gezeichneten Dinge auf dem Bildschirm.
  end;

  Done := false; // Diese Zeile nicht vergessen, sonst wird der Code nur sporadisch ausgeführt.
end;

end.
Hoffe du kannst mir helfen
  Mit Zitat antworten Zitat
Vasco da Gama

 
Delphi 2009 Professional
 
#8
  Alt 7. Aug 2009, 11:12
Im FormCreate Teil fehlt:
  AdPerCounter := TPerformanceCounter.Create(AdDraw); dann sollte es gehen, vor imagelistcreate am besten

mfG
Flo
  Mit Zitat antworten Zitat
Haxler
 
#9
  Alt 7. Aug 2009, 12:21
Hmm Delphi kennt den Begriff irgendwie nicht

[Error] Unit1.pas(34): Undeclared identifier: 'TPerformanceCounter'
  Mit Zitat antworten Zitat
Namenloser

 
FreePascal / Lazarus
 
#10
  Alt 7. Aug 2009, 12:44
Zitat von Haxler:
Hmm Delphi kennt den Begriff irgendwie nicht

[Error] Unit1.pas(34): Undeclared identifier: 'TPerformanceCounter'
In neueren Versionen von Andorra wurden die Namen vereinheitlicht: TPerformanceCounter heißt jetzt TAdPerformanceCounter.
  Mit Zitat antworten Zitat
Themen-Optionen Tutorial durchsuchen
Tutorial durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:08 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