Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Problem bei Pong Programmierung (https://www.delphipraxis.net/121897-problem-bei-pong-programmierung.html)

Andi28 6. Okt 2008 19:34


Problem bei Pong Programmierung
 
Guten Abend alle zusammen !

zunächst einmal hier mein Quelltext zu dem ich Fragen habe :

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var rq,aq,ax,ay : integer;
begin
 // zuerst den Kreis bewegen
 shape1.left :=shape1.Left+ dx;
 shape1.top :=shape1.top + dy;

 // testen, ob der Kreis in x-Richtung an den Rand des Formulars stößt
 if shape1.left <= 0                                then dx := +1;
 if (shape1.left >= form1.Width - shape1.width -8 ) then dx := -1;

 // testen, ob der Kreis in y-Richtung an den Rand des Formulars stößt
 if shape1.top <= 0                                 then dy:= +1;
 if (shape1.top >= form1.height - shape1.height-34 ) then dy:=-1;


 // testen, ob der Kreis mit dem untersten Punkt die Linie berührt
 if (shape1.Left+shape1.Width/2>shape2.Left)
 and (shape1.Left+shape1.Width/2<shape2.left+shape2.width)
 and (shape1.top+shape1.height=shape2.top)
 then dy:=-1;

 // testen, ob der Kreis mit dem obersten Punkt die Linie berührt
 if (shape1.Left+shape1.Width/2>shape2.Left)
 and (shape1.Left+shape1.Width/2<shape2.left+shape2.width)
 and (shape1.top=shape2.top+shape2.Height)
 then dy:=+1;

 // testen, ob der Kreis den linken Endpunkt der Linie berührt

 rq := (shape1.width div 2); rq := rq*rq; // rq = radius zum Quadrat
 ax := (shape1.Left + shape1.Width div 2) - shape2.left; // ax = abstand in x-richtung
 ay := (shape1.top + shape1.Height div 2) - shape2.top; // ay = abstand in y-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat

 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

 ay := (shape1.top + shape1.Height div 2) - shape2.top - shape2.Height; // ay = abstand in y-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat
 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

 // testen, ob der Kreis den rechten Endpunkt der Linie berührt


 ax := shape2.Left+shape2.width-shape1.left-shape1.width div 2; // ax = abstand in x-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat



 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

 ax := shape2.Left+shape2.width-shape1.left-shape1.width div 2; // ax = abstand in x-richtung
 ay := (shape1.top + shape1.Height div 2) - shape2.top; // ay = abstand in y-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat
 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

(**)(**)(**)(**)
(**)(**)(**)(**)
(**)(**)(**)(**)
(**)(**)(**)(**)
  // testen, ob der Kreis mit dem untersten Punkt die Linie2 berührt
 if (shape1.Left+shape1.Width/2>shape3.Left)
 and (shape1.Left+shape1.Width/2<shape3.left+shape3.width)
 and (shape1.top+shape1.height=shape3.top)
 then dy:=-1;

 // testen, ob der Kreis mit dem obersten Punkt die Linie2 berührt
 if (shape1.Left+shape1.Width/2>shape3.Left)
 and (shape1.Left+shape1.Width/2<shape3.left+shape3.width)
 and (shape1.top=shape3.top+shape3.Height)
 then dy:=+1;


 // testen, ob der Kreis den linken Endpunkt der Linie2 berührt

 rq := (shape1.width div 2); rq := rq*rq; // rq = radius zum Quadrat
 ax := (shape1.Left + shape1.Width div 2) - shape3.left; // ax = abstand in x-richtung
 ay := (shape1.top + shape1.Height div 2) - shape3.top; // ay = abstand in y-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat

 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

 ay := (shape1.top + shape1.Height div 2) - shape3.top - shape3.Height; // ay = abstand in y-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat
 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

 // testen, ob der Kreis den rechten Endpunkt der Linie berührt


 ax := shape3.Left+shape3.width-shape1.left-shape1.width div 2; // ax = abstand in x-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat



 if aq > rq then
  begin
   dx := -dx;
   dy := -dy;
  end;

 ax := shape3.Left+shape3.width-shape1.left-shape1.width div 2; // ax = abstand in x-richtung
 ay := (shape1.top + shape1.Height div 2) - shape3.top; // ay = abstand in y-richtung
 aq := ax*ax + ay*ay; // aq = Abstand zum Quadrat
 if aq > rq then
  begin
   dx :=-dx;
   dy := -dy;
  end;

// Punkteberechnung für Spieler Rot
if shape1.top<=0
   then
   begin
   inc(score)
   end  ;

label2.Caption:=FloatToStr(score);
// Punkteberechnung für Spieler Blau
if shape1.top+shape1.height>=form1.height-34
   then
   begin
   inc(score2)
   end  ;

label4.Caption:=FloatToStr(score2) ;



//if score=5
//then showmessage ('Spieler Rot hat gewonnen');

end; // timer1
http://img204.imageshack.us/my.php?i...benannttv2.jpg


und jetzt meine Fragen :


1. zunächst einmal hab ich ein Problem damit , das meine Kugel , also mein Shape1 zwar oben , unten und an den Ecken des Shape2 und Shape3 abprallt , jedoch durch die linke und die rechte Seite durchläuft , doch hab ich keine Ahnung warum das passiert ?!zu sehen in Bild A

2. hab ich ein Problem , wenn ich das Shape2 bzw 3 mit der maus in richtung Kugel schieben sollte das die Kugel ja abprallen , jedoch bleibt sie dann auf/in dem Shape 2 bzw 3 hängen und geht nur ein wenig hin und her und ohne meine Beihilfe garnicht mehr weg vom Shape 2.


nun meine Frage ist , ob mir wer helfen kann das Problem 1 zu lösen , denn ich glaube das sich damit auch das Problem 2 löst :)
Vielleicht zu sagen ist noch , dass ich (bisher) nicht viel Ahnung von Delphi habe , da ich es erst seit einer Woche durch ein Schulpraktikum lerne .



Danke schonmal im voraus !:D

Mfg Andi

sx2008 7. Okt 2008 03:08

Re: Problem bei Pong Programmierung
 
Das Problem mit deinem Sourcecode ist, dass du versucht alles in einer Procedure zu erledigen.
Du bekommst dann jede Menge Code, der zwar von dir noch einigermassen gut kommentiert ist, aber trotzdem recht schwer zu lesen ist.
Ein zentrales Problem scheint ja zu sein, festzustellen, ob ein Punkt innerhalb eines Kreises liegt oder nicht.
Dazu eine kleine Hilfsfunktion:
Delphi-Quellcode:
function PointInCircle(p, center:TPoint; radius:integer):Boolean;
begin
  // SQR() = Square-Funktion = quadrieren
  // Hier wird die Formel a^2 + b^2 = c^2 von Pythagoras ausgenützt
  Result := SQR(p.x-center.x) + SQR(p.y-center.y) <= SQR(radius);
end;
Mit dieser Funktion kannst du an einigen Stellen eine Vereinfachung vornehmen.
Die Funktion nimmt zwei Punkte mit dem Datentyp TPoint entgegen.
Um x/y-Werte in einen TPoint umzuwandelt, gibt es die Point()-Funktion:
Delphi-Quellcode:
if PointInCircle(Point(0,0), Point(Shape1.left, Shape1.Top), 50) then ...
Wenn du herausfinden möchtest, ob ein Kreis innerhalb eines Rechtecks liegt, gibt es einen einfachen Trick:
Man prüft nicht, ob der Kreis im Rechteck liegt, sondern ob der Mittelpunkt in einem verkleinertem Rechteck liegt.
Also:
1.) Rechteck an allen 4 Seiten um den Radius verkleinern
2.) prüfen, ob Mittelpunkt innerhalb des Rechteck liegt
Dazu gibt es schon Hilfsfunktionen aus der Windows-API.
InflateRect() vergrössert oder verkleinert ein Rechteck.
PointInRect() prüft, ob ein Punkt innerhalb eines Rechtecks liegt.

Andi28 7. Okt 2008 05:47

Re: Problem bei Pong Programmierung
 
Danke erstmal für die Antwort !:)
Die Funktion an sich versteh ich wohl aber was ich fragen wollte ist , die Funktion soll ich doch bei meinem Teil mit ax und ay und so einsetzen bzw ersetzen , oder? und dann zur eigentlichen Frage dazu : is center schon in meinem Fall als shape1.left+shape1.width div 2 definiert oder muss ich da für center und p noch was eintragen ?und p soll dann wohl der Punkt am shape2 sein der den Kreis berührt , oder ?


dann noch eine Frage zu:
InflateRect , wie benutz ich den den Befehl denn genau im Quelltext das mein shape2 verkleinert wird ?!


und noch eine letze frage zu

Delphi-Quellcode:
if PointInCircle(Point(0,0), Point(Shape1.left, Shape1.Top), 50) then ...
point(0,0) wird ja wohl der Mittelpunkt des Kreises sein , aber warum wird danach nochmal der point beschrieben und dann ,50 ?

sorry wenn ich das noch nicht so schnell verstehe , bin ja erst seid einer woche bei Delphi dabei

Mfg Andi :)

Corpsman 7. Okt 2008 06:06

Re: Problem bei Pong Programmierung
 
Ho das

Delphi-Quellcode:
if PointInCircle(Point(0,0), Point(Shape1.left, Shape1.Top), 50) then
ist sowieso falsch

richtig wäre

Delphi-Quellcode:
if PointInCircle(Point(0,0), Point(Shape1.left + shape1.width div 2, Shape1.Top+ shape1.height div 2), 50) then
Du brauchst 2 Punkt als übergabe

1. Kollisionspunkt
2. Mittelpunkt des Kreises
die 50 ist der Radius also auch wieder shape1.width div 2 weil dein shape hoffentlich qaudratisch ist.

Andi28 7. Okt 2008 10:03

Re: Problem bei Pong Programmierung
 
ok das hab ich dann schonmal verstanden ! :-D

Dann bleibt nurnoch meine erste Frage ... vll hab ich es auch unverständlich gesagt was mein Ziel ist.
Also meine Schläger shape2 und 3 sollen den ball verschlagen können. Vielleicht ist es jetzt besser zu versetehn .

und dann hab ich noch eine Frage auf die ich gerade gestoßen bin.Da mein Spiel schon Punkte zählen kann soll es den Ball auch nach jedem Punkt in die Mitte zurücksetzen. Wie mach ich das? :?


mein Ansatz sieht so aus :
Delphi-Quellcode:
// verschieben des Balles nach einem TReffer zum Ausgangspunkt

if shape1.top<=0
then begin
shape1.left:=243
and shape1.Top:=284
doch das klingt für mich auch nicht logisch!


Mfg

Corpsman 7. Okt 2008 11:26

Re: Problem bei Pong Programmierung
 
also deine 1. Frage versteh ich nicht,

das Centrieren ist einfacher.

Delphi-Quellcode:

if shape1.top<=0
then begin
// und die Zahlenwerte berechnest du hoffentlich mittels
shape1.left:=243; // (form1.clientwidth - shape1.width ) div 2 // evtl mus das - auch ein + sein, das verwechsle ich immer
shape1.Top:=284;// (form1.clientheight - shape1.height ) div 2 // evtl mus das - auch ein + sein, das verwechsle ich immer
end;

Andi28 7. Okt 2008 11:33

Re: Problem bei Pong Programmierung
 
Erstmal Danke and Dich Corpsman !

die erste Frage ist im Moment nicht mehr so wichtig für mich (evtl-. später wieder). Durch dein Lösungvorschlag hab ich mein Problem zwar gelöst .. aber da hab ich auch schon wieder das nächste gefunden :-D und zwar has ich jetzt soweit alles das wenn der Ball ins aus geschossen wird der vor dem Schläger startet .
Jetzt zum Problem : Ich bekomme es nur so hin das er immer in die selbe richtung fliegt , da ic nich weiß wie ich ein Zufall zwische dx:=1 und dx:=-1 bekomme ,damit er zufällg in eine richtung fliegt.

Mfg Andi

Corpsman 7. Okt 2008 16:12

Re: Problem bei Pong Programmierung
 
Also normalerweise darfst / solltest du glaubig nur eine Frage Pro Thread machen.

Aber deine Fragen hier sind ja alle so Trivial das wir das mal nicht so eng sehen wollen.

Zufall heist auf Englisch Random, das in die Delphi Hilfe eingegeben und du würdest Erfahren das du bei


Delphi-Quellcode:
Procedure Tform1.create( .. ) ;
begin
  ..
  Randomize; // Initialisieren des Zufallgenerators
  ..
End;
eintragen must und im Game dann an der Stelle die du haben willst etwas in der Art

Delphi-Quellcode:

case Random(4) of
  0: begin
    dx := 1;
    dy := 1;
  end;
  1: begin
    dx := -1;
    dy := 1;
  end;
  2: begin
    dx := -1;
    dy := -1;
  end;
  3: begin
    dx := 1;
    dy := -1;
  end;
end;
machen kannst ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:06 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-2025 by Thomas Breitkreuz