Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   pong-bug! suche hilfe (https://www.delphipraxis.net/136096-pong-bug-suche-hilfe.html)

maddom 23. Jun 2009 13:45


pong-bug! suche hilfe
 
Liste der Anhänge anzeigen (Anzahl: 1)
hallo leute,
habe mal ein pong spiel programmiert, doch wenn der ball an die schmale seite des paddels kommt, dopst der imm so komisch hin und her...
das spiel ist auch sonst noch nicht ganz fertig, zum beispiel bin ich mir noch nicht sicher, wie ich die KI machen soll(im moment noch unbesiegbar;) ).
habe mal das ganze ding gepackt und dazugeladen, wär nett, wenn sich das jemand mal anschauen würde(ziemlich übersichtlich, da viele kommentare).
danke schonmal im vorraus!

falls ihr es nicht runterladen woillt wegen virengefahr, hier auch noch der quellcode:

Delphi-Quellcode:
unit mPong;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Ball: TShape;
    PaddelL: TShape;
    PaddelR: TShape;
    labPunkteL: TLabel;
    labPunkteR: TLabel;
    butStart: TButton;
    labZeit: TLabel;
    labGewVer: TLabel;
    labBeruehrungL: TLabel;
    labBeruehrungR: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure butStartClick(Sender: TObject);
  private
    { Private declarations }
    StartZeit : TDateTime;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  PunkteL : integer;
  PunkteR : integer;
  beruehrung : integer;
  beruehrungL : integer;


implementation
  var x,y : Integer;
{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 //punktelabeleinstellungen
 labPunkteL.Caption := inttostr(PunkteL);
 labPunkteR.Caption := inttostr(PunkteR);
 //Bewegung
 ball.Left := ball.Left + x ;
 ball.Top := ball.Top + y ;

 //abdopsen vom Rand
 if Ball.Top >= 440
  then y := -Y ;
 if Ball.Top <= 0
  then y := -Y ;

 //abdopsen von paddel links
 if (Ball.Left <= 49) and (ball.Top +9 > paddelL.Top) and (ball.Top +9 < paddelL.Height + paddelL.top)
  Then begin
  x := -X ;
  beruehrungl := beruehrungL+1;
  end   ;
              //abdopsen an den schmalen rändern L
 if ((ball.left +9)<(paddell.Left +25)) and ((ball.Left+9)>paddell.Left) and ((ball.Top+17)>=paddell.Top)
  then y := -y ;
 if ((ball.left +9)<(paddell.Left +25)) and ((ball.Left+9)>paddell.Left) and ((ball.Top)<=(paddell.Top+113))
  then y := -y ;

 //abdopsen von paddel rechts
 if (ball.Left >= 599) and (Ball.Top > paddelR.Top) and (ball.Top < (paddelR.Height +paddelR.top))
  then begin
  x:= -x;
  Beruehrung := Beruehrung +1;
  end
               //abdopsen an den schmalen rändern R
 if ((ball.left+9)>paddelr.Left) and ((ball.left +9)<(paddelr.Left +25)) and ((ball.Top +17)>=paddelr.Top)
 then y := -y;
 if ((ball.left+9)>paddelr.Left) and ((ball.left +9)<(paddelr.Left +25)) and (ball.Top<=paddelr.Top+113)
 then y := -y;
 



 //ball ins aus rechts
 if ball.Left >= form1.Width
  then begin
  ball.Left :=form1.Width div 2 ;
  ball.Top := form1.Height div 2 ;
  x := -x;
  PunkteL := punktel+1;
  beruehrung := 0;
  end ;

 //ball ins aus links
 if ball.left <= 0
  then begin
  ball.Left :=form1.Width div 2 ;
  ball.Top := form1.Height div 2 ;
  x := -x;
  PunkteR:= PunkteR +1 ;
  beruehrung := 0;
  end   ;

 //Zeitanzeige
 labZeit.Caption := TimeToStr (now-StartZeit);
 //gewonnen!
 if PunkteL = 2
  then begin
  labgewver.Caption := 'GEWONNEN!';
     {labgewver.Caption := 'SPIELER 1 GEWONNEN!'; FÜR 2 SPIELER}
  labgewver.Visible :=true;
  timer1.Enabled := false;
  butStart.Visible := true;
  end;

 //Verloren...
 if PunkteR = 2
  then begin
  labgewver.Caption := 'VERLOREN!';
     {labgewver.Caption := 'SPIELER 2 GEWONNEN!'; FÜR 2 SPIELER }
  labgewver.Visible := true;
  timer1.Enabled := false;
  butStart.Visible := true;
  end   ;

 //ballgeschwindigkiet
 if beruehrung = 0
  then timer1.Interval := 60;
 if beruehrung = 1
  then timer1.Interval := 55;
 if beruehrung = 2
  then timer1.Interval := 50;
 if beruehrung = 3
  then timer1.Interval := 45;
 if beruehrung = 4
  then timer1.Interval := 40;
 if beruehrung = 5
  then timer1.Interval := 35;
 if beruehrung = 6
  then timer1.Interval := 30;
 if beruehrung = 7
  then timer1.Interval := 25;
 if beruehrung = 8
  then timer1.Interval := 20;
 if beruehrung = 9
  then timer1.Interval := 17;

 //berührungszähler
 labBeruehrungL.caption := inttostr(beruehrungl);
 labberuehrungR.Caption := inttostr(beruehrung);

 //K I
 if x>=0 then paddelR.Top := Ball.Top -50;








end;

procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;
x:= random(5) + 5;
y:= round(sqrt(10*10-x*x)) ;
PunkteL:= 0;
PunkteR:= 0;
end;


//paddel bewegen
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
If key=vk_Down
 then paddelL.Top := paddelL.Top + 20;
if key=vk_up
 then paddelL.Top := paddelL.Top - 20;
   {if key= VkKeyScan('-')
     then paddelr.Top := paddelr.Top + 20;    FÜR 2 SPIELER
    if key=VkKeyScan('+')
     then paddelr.Top := paddelr.Top - 20;}
end ;


procedure TForm1.butStartClick(Sender: TObject);
begin
  butstart.Visible := false;
  ball.Visible := true;
  labPunkteL.Visible := true;
  labpunkter.visible := true;
  paddell.Visible := true;
  paddelr.Visible := true;
  Timer1.Enabled := true;
  startzeit := now;
  PunkteL := 0;
  punkter := 0;
  labgewver.visible := false;
  labZeit.Visible := true;
  timer1.interval := 60;
  beruehrungl := 0;
  beruehrung := 0;
  labberuehrungL.Visible := True;
  labberuehrungR.Visible := True;

 
end;

end.

mleyen 23. Jun 2009 14:28

Re: pong-bug! suche hilfe
 
Willkommen in der DP, :dp:

mein erstes Spiel sah auch so ähnlich aus wie deines momentan. :lol:

Ich hab hier vorerst mal ein paar Tipps:
  • Nicht das ganze Spiel in einer Prozedur programmieren, sondern bestimmte Teile 'auslagern'. (Beispiel: procedure OnBallMovedRightOut)
  • Eine einheitliche Code-Formatierung hilft ungemein
  • (Für spätere/größere Projekte Objektorientierung anschauen)
Zum eigentlichem Fehler:
Den wirst du sicherlich schnell finden, wenn du den Code in Prozeduren aufgesplittet hast.
Setz dazu mal ein paar Breakpoints und du wirst sehen, der Ball verändert zu häufig seine Richtung. :wink:

btw: Die Ballgeschwindigkeit verändert sich proportional mit allen anderen Zeitwerten

Edit:
Da das hhargenau mein aller erstes Problem in Delphi war, hier nochmal ein kleiner Hinweis:
Überleg mal was passiert, wenn der Schläger des Spielers seitwärts in den Ball reinfährt.
Der Ball ändert die Richtung und fliegt ein paar Pixel weit zurück.
Da der Schläger aber ziemlich breit ist, trifft der Ball den Schläger erneut und ändert wieder die Richtung.
So geht das dann die ganze zeit weiter... :lol:
(zugegeben: ich hab das Problem damals nie gelöst :oops: )

maddom 23. Jun 2009 15:42

Re: pong-bug! suche hilfe
 
so danke erstmal für die schnelle antwort!
aufgrund deiner tips habe ich mir überlegt noch einzufügen, dass der ball entweder eine positive oder eine negative y-koordinate haben muss.
Delphi-Quellcode:
             //abdopsen an den schmalen rändern
 if ((ball.left +9)<(paddell.Left +25)) and ((ball.Left+9)>paddell.Left) and ((ball.Top+17)>=paddell.Top) and (y <0)
  then y := -y ;
 if ((ball.left +9)<(paddell.Left +25)) and ((ball.Left+9)>paddell.Left) and ((ball.Top)<=(paddell.Top+113)) and (y>0)
  then y := -y ;
funktioniert leider immer noch nicht, dochj meiner meinung nach klingt das ziemlich logisch, oder etwa nicht? :gruebel:

naja wäre sehr dankbar für noch nen tip/ ne idee.

Blup 24. Jun 2009 08:36

Re: pong-bug! suche hilfe
 
Auch bei Änderung des x-Vektors muss das bisherige Vorzeichen berücksichtigt werden.

maddom 24. Jun 2009 12:58

Re: pong-bug! suche hilfe
 
die x-richtung wird ja nicht geändert, wenn er auf die schmale seite des paddels kommt...

ich habs jedenfalls jetzt mal öfter gespielt und manchmal funktioniert es ja, so wie es soll, aber oft eben nicht.
naja falls jemand noch eine idee hätte, wäre ich dankbar, wenn er sie hier posten würde.

Blup 24. Jun 2009 16:17

Re: pong-bug! suche hilfe
 
Hast du denn versucht das Problem so zu lösen?

Ein Ball hat im allgemeinen einen gewissen Durchmesser, da sich sowohl Ball als auch Schläger bewegen, kann der Ball durchaus so tief im Schläger stecken, daß er nicht durch einen Bewegungsschritt den Schläger verlässt.
In diesem Fall wird der x-Vektor negiert und der Ball geht noch tiefer in den Schläger hinein und das kann sich mehrmals wiederholen. Der Ball scheint am Schläger zu kleben und bewegt sich nur vertikal.

RedShakal 24. Jun 2009 19:18

Re: pong-bug! suche hilfe
 
ich habs damals so gemacht das ich den ball nachdem eine kollision festgestellt wurde einfach um 10 pixel nach links oder rechts verschoben hab und ihn erst dann die richtung ändern lassen


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:40 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