Entwickler-Ecke
Multimedia / Grafik - Probleme beim Sprites zeichnen...
Mike_C - Mi 07.05.03 13:26
Titel: Probleme beim Sprites zeichnen...
Hi
ich versuche gerade mit DelphiX sprites zu zeichnen.
Wenn ich's richtig verstanden habe, sollte es eigentlich so funktionieren:
ich leite eine klasse fü mein sprite von
TImageSprite ab.
beim Constructor suche ich ein bestimmtes bild aus der ImageList (mit Items.find(name) ) und weise es der Image-Property von meinem Sprite zu.
erstellen tue ich es im moment so:
Quelltext
1: 2: 3: 4:
| with TSprite.Create(DXSpriteEngine1.Engine) do begin x := 0; y := 10; end; |
warum bekomme ich dabei AccessViolations und andere Felher?
edit:
hab noch was wichtiges vergessen:
ich habe das in eine klasse implementiert und über einen zweiten constructor aufgerufen:
und zwar so
Quelltext
1: 2: 3: 4: 5: 6: 7:
| Create(AParent); Image:=DXImageList.Items.Find('Player'+Color); Width :=Image.Width; Height :=Image. Height; Visible:=True;
fColor := Color; |
dabei gibts dauernd AccessViolations
maximus - Mi 07.05.03 16:27
Hi mike...
Die zusammenhänge sind mir noch nicht ganz klar. Aber 'TSprite' is doch deine klasse oder...so heist aber auch die basis-klasse von TImageSprite. Das solltest du nicht gleich bennen. Oder du wollstest tatsächlich ein TSprite erzeugen...da seh ich dann alerdings keinen sinn drinn.
Der untere code-schnipsel von dir, wo steht der genau drinn. Viellcht könntest du mal den constructor(wozu du einen zweiten brauchst weiss ich nicht) posten.
Mike_C - Mi 07.05.03 16:43
Hi!
Folgendes Problem: ich will ein Spiel ähnlich Monopoly schreiben. um schön objekt-orietiert zu bleiben hab ich mir ein paar klassen angelegt, darunter eine für das spielfeld und eine für die spielfiguren. die spielfeldklasse soll später dafür verantwortlich sein, die spielfiguren und andere grafiken zu laden, zu zeichnen, zu bewegen.
Meine spielfeldklasse sieht etwa so aus:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| TSpielfeld = class (TObject) protected fDXDraw: TDXDraw; fDXImageList: TDXImageList;
fPlayerRed, fPlayerGreen, fPlayerBlue, fPlayerYellow, fActPlayer: TSpieler; public constructor Create; virtual; destructor Destroy; override;
procedure Initialize; procedure Draw; procedure ConnectToDelphiX (DXImageList: TDXImageList; DXDraw: TDXDraw); procedure AddPlayer(Sprite: TSprite; color: string); published
end; |
die Prozedur ConnectTODelphiX setzt Referenzen zu den Komponenten TDXIMAGELIST und TDXDRAW, damit sie in der Klasse verwendet werden können und nicht immer auf die Application.MainForm zugegriffen werden muss.
Die Klasse für die Spielfiguren sieht so aus:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| TSpieler = class (TImageSprite) protected fColor: string; public procedure DoMove(MoveCount: Integer); override; constructor Create(AParent: TSprite ); override; constructor CreateColored(Aparent: TSprite; DXImageList: TDXImageList; color:string='red'); published property Color: string read fColor; end; |
Sie hat 2 KOnstruktoren, damit man die Spielfigur abhängig von der Farbe erstellen kann. Dazu die Konstruktoren:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| constructor TSpieler.Create(AParent: TSprite ); begin inherited Create(AParent); end;
constructor TSpieler.CreateColored(Aparent: TSprite; DXImageList: TDXImageList; color:string='red'); begin Create(AParent); Image:=DXImageList.Items.Find('Player'+Color); Width :=Image.Width; Height :=Image. Height; Visible:=True;
fColor := Color; end; |
Auf meiner Maiform habe ich /zu Testzwecken) einen Button, der eine rote Spielfigur erstellen soll und zwar über die prozedur TSpielfeld.AddPlayer(Sprite: TSprite; color: string);
die mach nichts anderes als das:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TSpielfeld.AddPlayer(Sprite: TSprite; color: string); begin if uppercase(color) = uppercase('red') then with fPlayerRed.CreateColored(Sprite, fDXImageList, 'red') do begin x := 100; y := 100; end; end; |
der Aufruf über den Button sieht dann so aus:
Quelltext
1:
| Spielfeld.AddPlayer(DXSpriteEngine1.Engine, 'red'); |
im konstruktor von meiner mainform, hab ich die bilder, die ich brauche alle geladen und benannt - die existieren also.. sieht so aus:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| DXImageList1.Items.Add; DXImageList1.Items[0].Picture.LoadFromFile('Graphic\Spielfeld.bmp'); DXImageList1.Items[0].Name := 'Spielfeld'; DXImageList1.Items.Add; DXImageList1.Items[1].Picture.LoadFromFile('Graphic\manred.bmp'); DXImageList1.Items[1].Name := 'PlayerRed'; DXImageList1.Items.Add; DXImageList1.Items[2].Picture.LoadFromFile('Graphic\mangreen.bmp'); DXImageList1.Items[2].Name := 'PlayerGreen'; DXImageList1.Items.Add; DXImageList1.Items[3].Picture.LoadFromFile('Graphic\manblue.bmp'); DXImageList1.Items[3].Name := 'PlayerBlue'; DXImageList1.Items.Add; DXImageList1.Items[4].Picture.LoadFromFile('Graphic\manyellow.bmp'); DXImageList1.Items[4].Name := 'PlayerYellow'; |
Nun mein eigentliches Problem....
bei diesen Konstrukten, bekomme ich eine AccessViolation, wenn ich auf den button klicke. Mit dem Debugger komme ich nicht weiter, weil er ständig an WinProcs und ähnlichem hängen bleibt (wegen den DelphiX-Units und allen möglichen Fenster-Events...)
Kann mir da jemand behilflich sein?
Gruß,
Mike_C
maximus - Do 08.05.03 15:04
Ok. Ich hab schon vermutet woran es liegen mag, aber wollte dich nicht fälschlicherweise zublahen :wink:
Im zweiten konstruktor ruft du den anderen konstruktor auf...was in deinem fall mit AccessViolations bestraft wird. Theoretisch sollten diese verschwinden, wenn du 'inherited' benutzt:
Quelltext
1: 2: 3: 4: 5: 6:
| constructor TSpieler.CreateColored(Aparent: TSprite; DXImageList: TDXImageList; color:string='red'); begin inherited Create(AParent); // <- dein anderer constructor macht auch nix anderes Image:=DXImageList.Items.Find('Player'+Color); Width :=Image.Width; ... |
...und den ersten konstruktor brauchst du eigentlich nicht..da er ja direkt weitergegeben wird.
Können natürlich noch andere fehler drinn sein...sieht aber sonst ganz gut aus.
bis denn und viel spass
PS: vielleicht macht es sinn wenn du das SpielFeld auch von TImageSprite oder TSprite ableitest, dann kannst du es glaich für die darstellung benutzen und die Player hängst du dann dort ein.
Mike_C - Do 08.05.03 16:12
@maximus
was du meintest, mit den zwei konstruktoren geht nicht anders.
ich kann in einem konstruktor nur dann inherited Create ausrufen, wenn es den kunstruktor ansich in der gleichen definition schonmal in der klasse gibt, von der ich ableite. mein konstruktor ist aber völlig frei definiert, deshalb brauche ich zwei und muss den ersten aufrufen. verstehst du, was ich meine?
nebenbei: am inherited lasg nicht ;-)
naja werd noch ein bisschen rumprobieren... wenn noch jemand eine idee hat, ich bin immer dafür dankbar...
maximus - Do 08.05.03 16:38
Na Klar kannst du ihn frei definieren...um ihn zu vererben musst du aber inherited verwenden und darfst nicht einfach den anderen aufrufen. Und du musst beim inheriten nur die parameter der vorgänger klasse aufrufen.
der konstruktor:constructor Create(AParent: TSprite ); override;Ist doch in der vorgänger klasse schon drinn, wozu brauchst du den, wenn du dort eh nix tust?
Setz doch mal n paar breakpoints!
Mike_C - Fr 09.05.03 12:18
du meinst ich soll nur einen konstruktor verwenden und den in der klasse so definieren
Quelltext
1:
| constructor CreateColored(AParent: TSprite; DXImageList: TDXImageList; color: string='red'); |
Ein
override geht dann ja nicht mehr, weil die Definition von der in der Basisklasse abweicht. Brauche ich das override am Ende garnicht?
Mike_C - Fr 09.05.03 13:34
ich hab's geschafft, meine spielfigur ohne accessviolation zu zeichenen, in dem ich die klassen alle von TImageSprite abgeleitet habe. kann ich jetzt noch irgendwie die Reihenfolge beeinflussen, in der die grafiken gezeichnet werden sollen?
bisher zeichne ich so
Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer); begin DXInput1.Update; DXDraw1.Surface.Fill(0); DXSpriteEngine1.Draw; DXDraw1.Flip; end; |
wäre eine zweite SpriteEngine die Lösung oder geht das auch anders?
maximus - Fr 09.05.03 14:24
Sehr schön! Jedes sprite hat eine Z-property, mit der du die zeichnen-reihenfolge angeben kannst.
Mike_C - Fr 09.05.03 15:07
thx, ich probier's...
mit ner zweiten SpriteEngine geht's auch...
maximus - Fr 09.05.03 17:44
Du kannst ja nicht für jedes sprite 'ne eigene engin machen :wink:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!