AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Space Invaders in Delphi5
Thema durchsuchen
Ansicht
Themen-Optionen

Space Invaders in Delphi5

Ein Thema von N4r0 · begonnen am 7. Feb 2010 · letzter Beitrag vom 15. Feb 2010
Antwort Antwort
Seite 2 von 3     12 3      
N4r0

Registriert seit: 7. Feb 2010
14 Beiträge
 
#11

Re: Space Invaders in Delphi5

  Alt 12. Feb 2010, 15:28
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
Angehängte Dateien
Dateityp: rar info_projekt_space_invaders__121.rar (291,1 KB, 39x aufgerufen)
  Mit Zitat antworten Zitat
N4r0

Registriert seit: 7. Feb 2010
14 Beiträge
 
#12

Re: Space Invaders in Delphi5

  Alt 13. Feb 2010, 22:09
weiß keiner woran es liegt? ^^
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#13

Re: Space Invaders in Delphi5

  Alt 13. Feb 2010, 23:24
Du hast UKol nirgens initialisiert. Schriebe am Anfang der Funktion UKol := TKollision.Create; und am Ende UKol.Free 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.

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.
  Mit Zitat antworten Zitat
N4r0

Registriert seit: 7. Feb 2010
14 Beiträge
 
#14

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 01:33
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?
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#15

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 02:26
Zitat von N4r0:
Hast du vielleicht ne Idee, wie ich das mit dem Klassen besser umsetzen kann, bzw. was sinnvoll wär in Klassen zu packen?
Das naheliegenste wäre erstmal, alles in eine Klasse zu packen, was auch im spiel hinterher ein Objekt ist - Sprich: Invader = Klasse, Bullet = Klasse, Raumschiff = Klasse usw... diese Klassen leitet man im elegantesten Fall von einer Basisklasse ab, die die abstrakten Methoden Move() und Draw() zur Verfügung stellt. Diese werden von den abgeleiteten Klassen jeweils überschrieben. Die Objekte speichert man alle in einer Objektliste, die man dann zu jedem Frame in einer Schleife durchläuft und für jedes Element diese Methoden aufruft.

Und schon hat man eine eigene kleine Spriteengine. Die Kollisionsabfrage könnte man so ähnlich lösen.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#16

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 10:23
Zitat:
Die Kollisionsabfrage könnte man so ähnlich lösen.
Da ja jedes Objekt weiss, welche Ausmasse/Besonderheiten es hat.
Markus Kinzler
  Mit Zitat antworten Zitat
N4r0

Registriert seit: 7. Feb 2010
14 Beiträge
 
#17

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 12:56
Ok, ich glaub ich hab verstanden wie du das meinst, klingt logisch.
Ich werds nachher mal versuchen zu realisieren.
  Mit Zitat antworten Zitat
N4r0

Registriert seit: 7. Feb 2010
14 Beiträge
 
#18

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 16:53
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:
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.
Vor dieser Klasse habe ich nun drei weitere Klassen abgeleitet:


"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:
procedure TFormStarship.SchiffTimerTimer(Sender: TObject);

  var x : TSpaceShip;

begin
       
  x.MoveSpaceShip;

end;
Woran kann es liegen, dass ich trotzdem diese Fehlermeldung bekomme?


Danke schonmal, hier wird einem wenigstens verständlich geholfen
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#19

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 18:19
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;
  Mit Zitat antworten Zitat
N4r0

Registriert seit: 7. Feb 2010
14 Beiträge
 
#20

Re: Space Invaders in Delphi5

  Alt 14. Feb 2010, 21:34
Delphi-Quellcode:
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;
Das verstehe ich nicht ganz. Wo kommt das TBasis her? Die Klasse, welche du erstellt hast heißt doch TSprite, oder?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 23:32 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