Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Spiel - Figur soll nicht über Hindernisse (Shapes) laufen (https://www.delphipraxis.net/195794-spiel-figur-soll-nicht-ueber-hindernisse-shapes-laufen.html)

Flickz 26. Mär 2018 19:12

Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Hallo, :)

ich wollte mich mal an ein kleines Spiel heranwagen, in dem sich eine Figur durch W, A, S und D bewegen kann.
Den Raum lade ich über ein Image. Die Figur lade ich über ein zweites Image. Die Figur soll immer zentral bleiben, sodass beim Bewegen der Figur sich das erste Image (der Raum) in die entsprechende Richtung verschiebt (so ähnlich wie bei den ersten Pokemon Generationen). Um die Gehbewegung darzustellen, lade ich mit jedem neuen Tastendruck in der gleichen Richtung ein anderes Bild in das zweite Image (Image der Figur). Im ersten Image (dem Raum) habe ich Shapes über die Wände, Möbel und Hindernisse gesetzt und wollte somit erreichen, dass die Figur nicht durch bzw über die Wände, Möbel und Hindernisse laufen kann. Dass die Figur nicht durch Wände läuft habe ich noch geschafft. Nu weiß ich jedoch nicht, wie man es so programmiert, dass die Figur sich nicht über Möbel und Hindernisse bewegt, sondern vor denen stehen bleibt. Hat jemand für mich einen Vorschlag?

[EDIT] Das ist nicht mein erstes Projekt, das ich schreibe. Habe mit meinem schulischen Wissen bisher sowas wie Mensch ärgere Dich nicht, Schach, Tetris, Snake usw programmiert. Wollte nu einfach mal die Bewegung von alten Adventure Spielen versuchen zu programmieren.

Hier ist der bisherige Quelltext:
Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
var moeg:boolean;
begin
  case Key of
    Ord('W'):
    begin
      moeg:= false;
      if (image2.top>obenShape.top+2*72) then moeg:= true; {obenShape= obere Grenze, sodass die Figur nicht
                                                                        durch die obere Wand läuft}
      if moeg then begin
      if bild = 'figur_hinten' then //Variable bild ist global deklariert
      begin
        bild:= 'figur_hinten_gehend';
        image1.top:= image1.top+72; //72, da die Schrittweite der Figur nach oben und unten 72 beträgt
        bettShape.top:= bettShape.top+72;
        pflanzeShape.top:= pflanzeShape.top+72;
        tischShape.top:= tischShape.top+72;
        tvShape.top:= tvShape.top+72;
        treppenShape.top:= treppenShape.top+72;
        linksShape.top:= linksShape.top+72;
        rechtsShape.top:= rechtsShape.top+72;
        untenShape.top:= untenShape.top+72;
        obenShape.top:= obenShape.top+72;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_hinten_linker_fuß.png');
      end
      else
      begin
        bild:= 'figur_hinten';
        image1.top:= image1.top+72;
        bettShape.top:= bettShape.top+72;
        pflanzeShape.top:= pflanzeShape.top+72;
        tischShape.top:= tischShape.top+72;
        tvShape.top:= tvShape.top+72;
        treppenShape.top:= treppenShape.top+72;
        linksShape.top:= linksShape.top+72;
        rechtsShape.top:= rechtsShape.top+72;
        untenShape.top:= untenShape.top+72;
        obenShape.top:= obenShape.top+72;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_hinten_rechter_fuß.png');
      end;
    end;
    end;
    Ord('S'):
    begin
      moeg:= false;
      if (image2.top<untenshape.top-2*72) then moeg:= true; {untenShape= unten Grenze, sodass die Figur nicht
                                                                          durch die untere Wand läuft}
      if moeg then begin
      if bild = 'figur_vorne' then
      begin
        bild:= 'figur_vorne_gehend';
        image1.top:= image1.top-72;
        bettShape.top:= bettShape.top-72;
        pflanzeShape.top:= pflanzeShape.top-72;
        tischShape.top:= tischShape.top-72;
        tvShape.top:= tvShape.top-72;
        treppenShape.top:= treppenShape.top-72;
        linksShape.top:= linksShape.top-72;
        rechtsShape.top:= rechtsShape.top-72;
        untenShape.top:= untenShape.top-72;
        obenShape.top:= obenShape.top-72;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_vorne_linker_fuß.png');
      end
      else
      begin
        bild:= 'figur_vorne';
        image1.top:= image1.top-72;
        bettShape.top:= bettShape.top-72;
        pflanzeShape.top:= pflanzeShape.top-72;
        tischShape.top:= tischShape.top-72;
        tvShape.top:= tvShape.top-72;
        treppenShape.top:= treppenShape.top-72;
        linksShape.top:= linksShape.top-72;
        rechtsShape.top:= rechtsShape.top-72;
        untenShape.top:= untenShape.top-72;
        obenShape.top:= obenShape.top-72;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_vorne_rechter_fuß.png');
      end;
    end;
    end;
    Ord('A'):
    begin
      moeg:=false;
      (image2.left>linksShape.left+96)) then moeg:= true; {linksShape= linke Grenze, sodass die Figur nicht
                                                                        durch die linke Wand läuft}
      if moeg then begin
      if bild = 'figur_links' then
      begin
        bild:= 'figur_links_gehend';
        image1.left:= image1.left+96; //96, da die Schrittweite der Figur nach links und rechts 96 beträgt
        bettShape.left:= bettShape.left+96;
        pflanzeShape.left:= pflanzeShape.left+96;
        tischShape.left:= tischShape.left+96;
        tvShape.left:= tvShape.left+96;
        treppenShape.left:= treppenShape.left+96;
        linksShape.left:= linksShape.left+96;
        rechtsShape.left:= rechtsShape.left+96;
        untenShape.left:= untenShape.left+96;
        obenShape.left:= obenShape.left+96;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_links.png');
      end
      else
      begin
        bild:= 'figur_links';
        image1.left:= image1.left+96;
        bettShape.left:= bettShape.left+96;
        pflanzeShape.left:= pflanzeShape.left+96;
        tischShape.left:= tischShape.left+96;
        tvShape.left:= tvShape.left+96;
        treppenShape.left:= treppenShape.left+96;
        linksShape.left:= linksShape.left+96;
        rechtsShape.left:= rechtsShape.left+96;
        untenShape.left:= untenShape.left+96;
        obenShape.left:= obenShape.left+96;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_links_gehend.png');
      end;
    end;
    end;
    Ord('D'):
    begin
      moeg:= false;
      if (image2.left<rechtsShape.left-96) then moeg:= true; {rechts Shape= rechte Grenze, sodass die Figur
                                                               nicht durch die rechte Wand läuft}
      if moeg then begin
      if bild = 'figur_rechts' then
      begin
        bild:= 'figur_rechts_gehend';
        image1.left:= image1.left-96;
        bettShape.left:= bettShape.left-96;
        pflanzeShape.left:= pflanzeShape.left-96;
        tischShape.left:= tischShape.left-96;
        tvShape.left:= tvShape.left-96;
        treppenShape.left:= treppenShape.left-96;
        linksShape.left:= linksShape.left-96;
        rechtsShape.left:= rechtsShape.left-96;
        untenShape.left:= untenShape.left-96;
        obenShape.left:= obenShape.left-96;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_rechts.png');
      end
      else
      begin
        bild:= 'figur_rechts';
        image1.left:= image1.left-96;
        bettShape.left:= bettShape.left-96;
        pflanzeShape.left:= pflanzeShape.left-96;
        tischShape.left:= tischShape.left-96;
        tvShape.left:= tvShape.left-96;
        treppenShape.left:= treppenShape.left-96;
        linksShape.left:= linksShape.left-96;
        rechtsShape.left:= rechtsShape.left-96;
        untenShape.left:= untenShape.left-96;
        obenShape.left:= obenShape.left-96;
        image2.picture.loadfromfile(GetcurrentDir+'\Bilder\figur\figur_rechts_gehend.png');
      end;
      end;
    end;

hoika 26. Mär 2018 19:25

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Hallo,
wo ist denn der Unterscheid einer Wand zu einem Tisch?

Zeig doch mal einen Screenshot.

Vielleicht sind ja Regions ein Ansatz,
wenn die Geometrie deines Shapes kompliziert ist.

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Flickz 26. Mär 2018 19:35

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Liste der Anhänge anzeigen (Anzahl: 3)
Ein Unterschied ist dabei nicht, nur ich weiß nicht, wie ich prüfen lassen kann, ob mehrere Shapes in der Richtung sind, in die die Figur bewegt werden soll.

Ich hatte bisher nur Delphi in der Schule und hab daher nur Grundwissen, womit ich vorerst versuchen will klarzukommen. Aber wenn es nicht anders geht, setze ich mich mit Region mal auseinander.

KodeZwerg 26. Mär 2018 19:49

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Als Einstiegs-Projekt schon eine Herausforderung, Kollisionsabfrage etc.
Einfacher als Einstieg in die Welt der Spiel wäre da eventuell so etwas:
ein Fenster zu Darstellung von Bildern und vier Bewegungs-Knöpfe für vier Richtungen wobei Knopf "Hoch" bzw "Runter" dafür verantwortlich ist welches Bild gerade in dem Fenster dargestellt wird, "Rechts" und "Links" optional je nach Bild zuschaltbar.
Klassische Adventure Steuerung der 80'er Jahre ;-)

Flickz 26. Mär 2018 19:55

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Zitat:

Zitat von KodeZwerg (Beitrag 1397298)
Als Einstiegs-Projekt schon eine Herausforderung, Kollisionsabfrage etc.
Einfacher als Einstieg in die Welt der Spiel wäre da eventuell so etwas:
ein Fenster zu Darstellung von Bildern und vier Bewegungs-Knöpfe für vier Richtungen wobei Knopf "Hoch" bzw "Runter" dafür verantwortlich ist welches Bild gerade in dem Fenster dargestellt wird, "Rechts" und "Links" optional je nach Bild zuschaltbar.
Klassische Adventure Steuerung der 80'er Jahre ;-)

Ein Einstieg ist das nicht direkt. Habe neben der Schule bereits Mensch ärgere Dich nicht bspweise programmiert und als Belegarbeit nu am Ende der 12ten Schach. Ich wollte mich einfach mal an was anderes wagen und gucken, was ich evtl mit meinem schulischen Grundwissen erreichen könnte.

KodeZwerg 26. Mär 2018 23:45

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Hier im Forum hat jemand ein Pacman Spiel vorgestellt, das könntest Du lesen und lernen wie eine Kollisionsabfrage funktioniert.
Einfacher dafür wäre Pong, ich finde nur gerade keine Quelle dafür.

matashen 27. Mär 2018 07:32

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Guten Morgen,

das einfachste ist einfach die Koordinatengrenzen abzufragen, dann hast du aber nur die Prüfung auf die "harte Kante" deines Rechtecks das du prüfst, wenn dus genauer willst dann musst du das "Zielrechteck" auf der Spielfläche mittels XOR prüfen inwieweit sich Pixel überschnneiden

DeddyH 27. Mär 2018 08:05

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Ich werfe da einfach mal MSDN-Library durchsuchenIntersectRect in den Raum.

Mavarik 28. Mär 2018 10:27

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Aber bitte keine Kollisionsabfrage über Pixel auf dem Bildschirm...

Stell Dir vor Dein Spiel müsste komplett ohne Tastatureingaben und ohne Bildschirm laufen.
Am besten, wenn Deine Spiellogik komplett ohne Form funktioniert.

Also hast Du eine Routine der Du die Bewegungsrichtung übergibst. Und die Daten, wie Deine Räume aussehen. Bitte nicht FIX in den Code hacken...

Vielleicht ein 2 DIM-Array für X und Y
Darin stehen bytes oder was auch immer... Vielleicht ein Aufzählungstyp...

Delphi-Quellcode:
TFeldType = (ftFrei,ftWand,ftBlume);
Oder ein Byte mit der Image Nummer...

wenn Du nun den Raum aufbraust, stellst Du einfach nur die Daten aus dem Array dar...

Wenn Dein Spieler also bei Position X=10,Y=10 ist, kannst Du einfach Abfragen:

Delphi-Quellcode:
Case Bewegungsrichtung of
  Hoch : if Feld[Player.X,Player.Y-1] = ftFrei
           then KannHoch := true
           else KannHoch := false;
 Links : if Feld[Player.X-1,Player.Y] = ftFrei
           then KannLinks := true
           else KannLinks := false;
// usw.
end; // of case
Dann kannst Du auch einfach Deine Game-Logik testen... (z.B. mit Unittests)


Delphi-Quellcode:
Procedure TesteLogik;
begin
  GameEngine.Player := TPlayer.Create(10,10);
  GameEngine.Bewege(Hoch);
  GameEngine.Bewege(Hoch);
  Check(GameEngine.KannHoch,'Fehler in der Logik'); // Da steh eine Wand - kann nicht sein!
end;
Mavarik :coder:

Flickz 28. Mär 2018 21:36

AW: Spiel - Figur soll nicht über Hindernisse (Shapes) laufen
 
Zitat:

Zitat von Mavarik (Beitrag 1397398)
Aber bitte keine Kollisionsabfrage über Pixel auf dem Bildschirm...

Stell Dir vor Dein Spiel müsste komplett ohne Tastatureingaben und ohne Bildschirm laufen.
Am besten, wenn Deine Spiellogik komplett ohne Form funktioniert.

Also hast Du eine Routine der Du die Bewegungsrichtung übergibst. Und die Daten, wie Deine Räume aussehen. Bitte nicht FIX in den Code hacken...

Vielleicht ein 2 DIM-Array für X und Y
Darin stehen bytes oder was auch immer... Vielleicht ein Aufzählungstyp...

Delphi-Quellcode:
TFeldType = (ftFrei,ftWand,ftBlume);
Oder ein Byte mit der Image Nummer...

wenn Du nun den Raum aufbraust, stellst Du einfach nur die Daten aus dem Array dar...

Wenn Dein Spieler also bei Position X=10,Y=10 ist, kannst Du einfach Abfragen:

Delphi-Quellcode:
Case Bewegungsrichtung of
  Hoch : if Feld[Player.X,Player.Y-1] = ftFrei
           then KannHoch := true
           else KannHoch := false;
 Links : if Feld[Player.X-1,Player.Y] = ftFrei
           then KannLinks := true
           else KannLinks := false;
// usw.
end; // of case
Dann kannst Du auch einfach Deine Game-Logik testen... (z.B. mit Unittests)


Delphi-Quellcode:
Procedure TesteLogik;
begin
  GameEngine.Player := TPlayer.Create(10,10);
  GameEngine.Bewege(Hoch);
  GameEngine.Bewege(Hoch);
  Check(GameEngine.KannHoch,'Fehler in der Logik'); // Da steh eine Wand - kann nicht sein!
end;
Mavarik :coder:

Danke Dir! Das ist die beste Lösung gewesen ^^


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:59 Uhr.

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