![]() |
Re: Space Invaders in Delphi5
Liste der Anhänge anzeigen (Anzahl: 1)
Tut mir leid, aber ich verstehe grad nicht worauf du hinaus willst, bzw. was das bringen soll ^^
hier nochmal mein komplettes Projekt, vielleicht erkennt man ja da genaueres |
Re: Space Invaders in Delphi5
weiß keiner woran es liegt? ^^
|
Re: Space Invaders in Delphi5
Du hast UKol nirgens initialisiert. Schriebe am Anfang der Funktion
Delphi-Quellcode:
und am Ende
UKol := TKollision.Create;
Delphi-Quellcode:
Allerdings ist es nicht sonderlich sinnvoll, Code so in Klassen auszulagern wie du es hier getan hast. Eine Klasse soll dazu dienen, einen Programmteil so abzukapseln, dass er flexibel und leicht wiederverwendbar ist. Dazu ist es nötig, dass möglichst wenig Abhängigkeiten zu Elementen außerhalb der Klasse bestehen.
UKol.Free
Deine Klasse ist aber immer noch fest mit den Elementen von Form1 verdrahtet, sodass der Wartungsaufwand eher steigt, als dass er abnimmt, denn bei jeder Änderung musst du jetzt gleich an zwei Stellen Anpassungen vornehmen. OOP bedeutet nicht, dass man einfach nur seinen Code in mehrere Klassen packt, sondern dass man sein Programm in voneinander unabhängige Bausteine zerlegt. Wenn nämlich hinterher sich alle Klassen gegenseitig kennen, ist nichts gewonnen. Die Kunst besteht darin, zu erkennen, wo und wie man Bestandteile sinnvoll extrahieren könnte, und sein Programm entsprechend zu strukturieren. |
Re: Space Invaders in Delphi5
hm ja, ich versteh worauf zu hinaus willst. An sich wollte ich das ganze jetzt nur in Klassen packen, weil es auch in der Aufgabenstellung erwähnt ist, dass wir Klassen benutzen sollen.
Aber du hast schon recht, einen wirklkichen sinnvollen Zweck hat das ganze auch nicht, wenn man alles nur "zerreißt". Hast du vielleicht ne Idee, wie ich das mit dem Klassen besser umsetzen kann, bzw. was sinnvoll wär in Klassen zu packen? |
Re: Space Invaders in Delphi5
Zitat:
Und schon hat man eine eigene kleine Spriteengine. Die Kollisionsabfrage könnte man so ähnlich lösen. |
Re: Space Invaders in Delphi5
Zitat:
|
Re: Space Invaders in Delphi5
Ok, ich glaub ich hab verstanden wie du das meinst, klingt logisch.
Ich werds nachher mal versuchen zu realisieren. |
Re: Space Invaders in Delphi5
Gut, ich habe jetzt mal was zusammengebastelt und mich würde interessieren, ob ich das soweit richtig verstanden habe:
Ich habe eine Basisklasse "TBasis" erstellt:
Delphi-Quellcode:
Vor dieser Klasse habe ich nun drei weitere Klassen abgeleitet:
unit UnitBasis;
interface uses extctrls; type TBasis = class protected Invader : array[1..21] of TImage; Spielfeld, Raumschiff, Schuss, Invader1, Invader2, Invader3, Invader4, Invader6, Invader7, Invader5, Invader8, Invader9, Invader10, Invader11, Invader12, Invader13, Invader14, Invader15, Invader16, Invader17, Invader18, Invader19, Invader20, Invader21 : TImage; procedure MoveSpaceShip ; virtual; abstract; function MoveInvader(level: integer): boolean; virtual; abstract; procedure ShotCreate ; virtual; abstract; procedure MoveShot ; virtual; abstract; function Collision(Schuss : TImage ; i : integer) : boolean; virtual; abstract; end; implementation end. "TSpaceShip":
Delphi-Quellcode:
unit UnitSpaceShip;
interface uses UnitBasis, Dialogs, Windows; type TSpaceShip = class (TBasis) protected procedure MoveSpaceShip ; end; implementation procedure TSpaceShip.MoveSpaceShip ; begin if getasynckeystate(VK_RIGHT)<>0 then Raumschiff.left := Raumschiff.left + 8 else if getasynckeystate(VK_LEFT) <> 0 then Raumschiff.left := Raumschiff.left - 8; if Raumschiff.left < Spielfeld.left then Raumschiff.left := Spielfeld.left + 2 else if Raumschiff.left + Raumschiff.width > Spielfeld.left + Spielfeld.width then Raumschiff.left := Spielfeld.left + Spielfeld.width - Raumschiff.width - 2; end; end. "TInvader":
Delphi-Quellcode:
unit UnitInvader;
interface uses UnitBasis, Dialogs; type TInvader = class (TBasis) protected Bewegungsrichtung : integer; function MoveInvader( level: integer): boolean; end; implementation function TInvader.MoveInvader(level: integer): boolean; var i,x,y : integer; begin for i := 1 to 21 do begin Invader[i].left := Invader[i].left + (Bewegungsrichtung * 10); end; if Invader7.left + Invader7.width > Spielfeld.left + Spielfeld.width then begin i := 1; for x := 1 to 3 do for y := 1 to 7 do begin Invader[i].top := Invader[i].top + 25; Invader[i].left := Spielfeld.left + Spielfeld.width - ((Invader[i].width + 7) * (8 - y)) - 2; i := i + 1; end; Bewegungsrichtung := -1 end else if Invader1.left < Spielfeld.left then begin i := 1; for x := 1 to 3 do for y := 1 to 7 do begin Invader[i].top := Invader[i].top + 25; Invader[i].left := Spielfeld.left + ((Invader[i].width + 7) * (y - 1)) + 9; i := i + 1; end; Bewegungsrichtung := 1 end; for i := 21 downto 1 do if (Invader[i].visible = true) and (Invader[i].top + Invader[i].height >= Raumschiff.top - 10) then begin showmessage('Game Over'); break; end; end; end. und "TBullet":
Delphi-Quellcode:
unit UnitBullet;
interface uses UnitBasis, extctrls, MMSystem, Unit1; type TBullet = class (TBasis) protected Schuss1 : array of TImage; procedure ShotCreate; procedure MoveShot; function Collision(Schuss : TImage ; i : integer) : boolean; end; implementation procedure TBullet.ShotCreate ; var Schusstemp : TImage; begin SndPlaySound( '.\pew.wav', SND_ASYNC ); Schusstemp := TImage.Create(FormStarship); Schusstemp.Parent := FormStarship; // this is important Schusstemp.Left := Raumschiff.left + (RaumSchiff.width div 2); // X coordinate Schusstemp.Top := RaumSchiff.top - 20; // Y coordinate Schusstemp.Picture := Schuss.Picture; SetLength(Schuss1, High(Schuss1) + 2); Schuss1[High(Schuss1)] := Schusstemp; end; function TBullet.Collision(Schuss : TImage ; i : integer) : boolean; var xposition, yposition: integer; begin Collision := false; xposition := Schuss.left; yposition := Schuss.top; if (xposition >= Invader[i].left) and (xposition <= (Invader[i].left + Invader[i].width)) then begin if (yposition <= (Invader[i].top + Invader[i].height)) and (yposition >= Invader[i].Top) then Collision := true else Collision := false end else Collision := false; end; procedure TBullet.MoveShot; var j,i,x : integer; collide : boolean; begin for j := High(Schuss1) downto 0 do begin collide := false; for i := 1 to 21 do begin if (Collision(Schuss1[j],i) = true) and (Invader[i].Visible = true) then begin collide := true; Invader[i].visible := false; SndPlaySound( '.\boom1.wav', SND_ASYNC ); Schuss1[j].Free; for x:=j to high(Schuss1)-1 do Schuss1[x] := Schuss1[x+1]; SetLength(Schuss1,length(Schuss1)-1); break; end end; if collide = false then if Schuss1[j].top > Spielfeld.top + 5 then Schuss1[j].top := Schuss1[j].top - 10 else begin Schuss1[j].Free; for x:=j to high(Schuss1)-1 do Schuss1[x] := Schuss1[x+1]; SetLength(Schuss1,length(Schuss1)-1); end; end; end; end. Sieht das soweit verständlich und logisch aus oder was sollte ich ändern? Wenn ich jetzt die Procedure "TSpaceShip.MoveSpaceShip" in meiner Hauptprogramm aufrufen möchte sagt mir Delphi: "[Fehler] Unit1.pas(247): Undefinierter Bezeichner: 'MoveSpaceShip'". Ich habe aber im Hauptprogramm die "UnitSpaceShip" unter "uses" bei "implemantation" bekannt gemacht und die Procedure wiefolgt aufgerufen:
Delphi-Quellcode:
Woran kann es liegen, dass ich trotzdem diese Fehlermeldung bekomme?
procedure TFormStarship.SchiffTimerTimer(Sender: TObject);
var x : TSpaceShip; begin x.MoveSpaceShip; end; Danke schonmal, hier wird einem wenigstens verständlich geholfen :P |
Re: Space Invaders in Delphi5
Ich meinte eher sowas:
Delphi-Quellcode:
type
TSprite = class protected FImage: TImage; FParent: TForm; procedure InitImage; virtual; abstract; public constructor Create(Parent: TForm; Position: TPoint); destructor Destroy; override; procedure Move; virtual; abstract; function CollidesWith(AObject: TSprite): boolean; end; TInvader = class(TSprite) protected procedure InitImage; override; public procedure Move; override; end; TBullet = class(TSprite) protected procedure InitImage; override; public procedure Move; override; end; implementation constructor TSprite.Create(Parent: TForm; Position: TPoint); begin inherited Create; FParent := Parent; FImage := TImage.Create(nil); FImage.Parent := Parent; InitImage; FImage.Left := Position.X; FImage.Top := Position.Y; end; destructor TSprite.Destroy; begin FImage.Free; inherited; end; function TSprite.CollidesWith(AObject: TSprite): boolean; begin Result := (FImage.Left+FImage.Width > AObject.Left) and (FImage.Top +FImage.Height > AObject.Top ) and ...; end; procedure TInvader.InitImage; begin FImage.LoadFromFile('invader.bmp'); // z.B... end; procedure TInvader.Move; begin FImage.Left := FImage.Left+1; // z.B... end; procedure TBullet.InitImage; begin FImage.LoadFromFile('bullet.bmp'); // z.B... end; procedure TInvader.Move; begin FImage.Top := FImage.Top-10; // z.B... end;
Delphi-Quellcode:
TForm1 = class(TForm)
... private FSprites: TObjectList; ... end; implementation procedure TForm1.FormCreate(Sender: TObject); var i,j: integer; begin FSprites := TObjectList.Create(True); for i := 0 to 8-1 do for j:= 0 to 3-1 do FSprites.Add(TInvader.Create(self, Point(i*30, j*20))); end; procedure TForm1.Timer1Timer(Sender: TObject); var i,j: integer; begin for i := 0 to FSprites.Count-1 do TSprite(FSprites[i]).Move; ... end; |
Re: Space Invaders in Delphi5
Delphi-Quellcode:
Das verstehe ich nicht ganz. Wo kommt das TBasis her? Die Klasse, welche du erstellt hast heißt doch TSprite, oder?
function CollidesWith(AObject: TBasis): boolean;
[...] function TSprite.CollidesWith(AObject: TBasis): boolean; begin Result := (FImage.Left+FImage.Width > AObject.Left) and (FImage.Top +FImage.Height > AObject.Top ) and ...; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:19 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 by Thomas Breitkreuz