Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Ping Pong Programm - Punktescore, Game Over und Start/Stopp (https://www.delphipraxis.net/180497-ping-pong-programm-punktescore-game-over-und-start-stopp.html)

KeksRebellion 23. Mai 2014 17:16

Ping Pong Programm - Punktescore, Game Over und Start/Stopp
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

Ich muss für meinen Info Lehrer ein ping Pong programm schreiben und bin relativ weit gekommen, hänge jetzt aber an 3 Punkten:
  • Punktescore Anzeige funktioniert nicht
  • Game Over Anzeige erscheint nicht wenn das Programm verloren hat
  • Das Gameplay läuft im Hintergrund ab ohne zu stoppen
Das hier ist mein Code von der Unit 1, also dem eigtl. Spiel.
Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Panel: TPanel;
    Background: TImage;
    SPlayer: TImage;
    Infopanel: TPanel;
    PMenu: TPanel;
    LScore: TLabel;
    SBall: TShape;
    PStartStop: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure PMenuClick(Sender: TObject);
    procedure PStartStopClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

  PosX, PosY, X, Y, Punktescore: Integer;

implementation

uses Unit2, Unit4;

{$R *.DFM}



procedure TForm1.FormCreate(Sender: TObject);
begin
Punktescore:=0;

randomize;
PosX:=200;
PosY:=208;
X:=2;
Y:=3;

end;

procedure TForm1.Timer1Timer(Sender: TObject);
Var
Overlay: Trect;
begin
//Bewegung
          PosX:=PosX+X;
          PosY:=PosY+Y;
   //Seitenwände
     If PosX>Panel.width - SBall.width then
        X:=-X;
     If PosX< 0 then
        X:=-X;
   //Obere und Untere Wand
     If PosY>Panel.height - SBall.height then
        Y:=-Y;
     If PosY< 0 then
        Y:=-Y;

   SBall.left:=round(PosX);
   SBall.Top:=round(posY);

//Ball trifft Schläger
       If intersectrect (Overlay, SPlayer.BoundsRect, SBall.BoundsRect) then
       begin
          X:=-X-random(2);
          Y:=-Y-random(2);
       end;

       If SBall.Top=SPlayer.Top-SBall.Top then
       begin
         LScore.caption:=IntToStr((Punktescore)+1);
       end;

end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
     if key = VK_ESCAPE then
         halt;

       if key = VK_Left then
         SPlayer.left:= SPlayer.Left-13;

       if key = VK_Right then
         SPlayer.left:= SPlayer.left+13;
 


end;


procedure TForm1.PMenuClick(Sender: TObject);
begin
form1.close; form2.show
end;



procedure TForm1.PStartStopClick(Sender: TObject);
begin
Timer1.Enabled := not Timer1.Enabled;
end;

end.
Anbei hänge ich noch n Bild von der Oberfläche an.
Anhang 41239

himitsu 23. Mai 2014 22:03

AW: Ping Pong Programm - Punktescore, Game Over und Start/Stopp
 
Wie soll da denn bitte etwas hochzähöen, wenn du den Wert von Punktescore nicht veränderst? :zwinker:
( immer wieder 0+1 ist und bleibt immer nur 1 )

Zitat:

Delphi-Quellcode:
If SBall.Top=SPlayer.Top-SBall.Top then

Außerdem zählt es nur, wenn dieser Vergleich ganz genau trifft
und jetzt beantworte dir die Frage, ob hier sich hier etwas nur in Einerschritten bewegt.



Und dann hab ich auch noch ein paar Fragen:

Zitat:

Delphi-Quellcode:
  PosX, PosY, X, Y, Punktescore: Integer;

Wieso sind diese Variablen global und liegen nicht in TForm1 (private) ?

Zitat:

Delphi-Quellcode:
     if key = VK_ESCAPE then
         halt;

So beendet man kein Programm :!:

Close der MainForm oder
Delphi-Quellcode:
Application.Terminate
.


Zitat:

Delphi-Quellcode:
procedure TForm1.PMenuClick(Sender: TObject);
begin
  form1.close; form2.show
end;

Wieso greifst du da auf Form1 zu, wo du doch schon im Code der TForm1 bist?

Self verwenden, oder nichts angeben. (nichts = ein implizites Self)

Zitat:

Delphi-Quellcode:
If SBall.Top=SPlayer.Top-SBall.Top then

Sicher, daß die Berechnung, bzw. der Vergleich so korrekt ist?
Es ist jetzt zwar bissl spät, aber ich versteh grade irgendwie nicht, was du da eigentlich prüfen willst.

Hmmm, bissl die Gleichung umstellen ...
Delphi-Quellcode:
If SBall.Top = -SBall.Top + SPlayer.Top then

Delphi-Quellcode:
If SBall.Top * 2 = SPlayer.Top then

SPlayer.Top soll doppelt so groß sein, wie SBall.Top ?
Und die Form1 ist doch die MainForm? (das die erste Form-Instanz, welche vom Delphi automatisch erstellt wird)
Wenn ja, dann wird das so nicht funktionieren, denn siehe dem Punkt, wo es um das Beenden eines Programms geht.



Was ein Debugger ist, das weißt du?


Zitat:

Das Gameplay läuft im Hintergrund ab ohne zu stoppen
Das hab ich jetzt nicht verstanden.


Zitat:

Game Over Anzeige erscheint nicht wenn das Programm verloren hat
Und das kann dir keiner beantworten, da man hierfür nichtmal etwas Code sieht/erkennt, welcher dafür verantwortlich sein könnte. :gruebel:




Ach ja, ich sehe da mindestens noch ein 4. Problem.
Tipp: Drücke mal ganz oft/lange auf die Pfeiltasten Links oder Rechts.

Sir Rufo 23. Mai 2014 22:27

AW: Ping Pong Programm - Punktescore, Game Over und Start/Stopp
 
Zum GameOver und Start/Stop:

Das ist doch Stati die das Programm einnehmen kann. Also erstelle dir eine Variable (bitte keine globale Variable, sondern erstelle die einfach im
Delphi-Quellcode:
private
Teil der Form-Klasse).

Möglichkeit 1:

Delphi-Quellcode:
const
  GAME_START = 0;
  GAME_RUN = 1;
  GAME_OVER = 2;

type
  TForm1 = class(TForm)
  ...
  private
    FGameState : integer;
  ...
  end;

case FGameState of
  GAME_START : ;
  GAME_RUN : ;
  GAME_OVER : ;
end;
Immer dann wenn du meinst du musst in einen anderen Status, dann trägst du das dort ein und dein Programm kann darauf reagieren.

Möglichkeit 2:

Delphi-Quellcode:
type
  TGameState = ( gsStart, gsRun, gsGameOver );

  TForm1 = class(TForm)
  ...
  private
    FGameState : TGameState;
  ...
  end;

case FGameState of
  gsStart : ;
  gsRun : ;
  gsGameOver : ;
end;
Eigentlich gleiche Vorgehensweise wie in 1

himitsu 23. Mai 2014 22:34

AW: Ping Pong Programm - Punktescore, Game Over und Start/Stopp
 
Was mir grade noch aufgefallen ist:

- Eigentlich heißt es hier "Eine Frage pro Thread".
- Und wieso fragst du hier schonwieder nach dem "Punktescore", wo es dafür bereits einen Thread von dir gibt?

Wenn es nicht funktioniert, dann hättest du dort nachfragen sollen, was du falsch machst. (vorallem da dort eigentlich schon eine Lösung steht)

Popov 23. Mai 2014 23:56

AW: Ping Pong Programm - Punktescore, Game Over und Start/Stopp
 
Paar Punkte die mir aufgefallen sind:

Du benutzt für Buttons TPanels. Ist nicht gut, aber ich glaube den Grund zu wissen - vermutlich geht es um den Fokus den TButton hält. Das Problem ist zwar lösbar, man kann aber auch TSpeedButtons nehmen (Register Zusätzlich). SpeedButtons haben kein Fokus, Problem gelöse, und es ist ein Button. Also ersetzten.

So wie ich das erkenne ist Panel (Name) unter dem Image. Warum? Zumindest scheint das so zu sein. Ist es so?
Delphi-Quellcode:
   //Seitenwände
     If PosX>Panel.width - SBall.width then
        X:=-X;
Wieso nimmst du nicht das Image Background dafür? Hier eine Möglichkeit:
Delphi-Quellcode:
   //Seitenwände
     //If PosX>Panel.width - SBall.width then
     if PosX>Background.Width - SBall.width then
        X:=-X;
     If PosX< 0 then
        X:=-X;
   //Obere und Untere Wand
     //If PosY>Panel.height - SBall.height then
     If PosY>Background.height - SBall.height then
        Y:=-Y;
Ist es sinnvoll keine Reaktion auf fehlgeschlagenen Ball zu zeigen und nur Punkte zählen? Das wäre eine Möglichkeit - Ball startet von der Startposition (kann man auch weiter oben starten lassen):
Delphi-Quellcode:
       //If SBall.Top=SPlayer.Top-SBall.Top then
       If SBall.Top>SPlayer.Top then
       begin
         LScore.caption:=IntToStr((Punktescore)+1);

         PosX:=200;  //Evtl. andere Werte
         PosY:=208;
         X:=2;
         Y:=3;
       end;
Auf die glob. Variablen gehe ich nicht ein, aber wann stoppt das Spiel? Eine Möglichkeit:
Delphi-Quellcode:
  PosX, PosY, X, Y, Punktescore: Integer;

const
  MaxPunktescore = 5;
Delphi-Quellcode:
       //If SBall.Top=SPlayer.Top-SBall.Top then
       If SBall.Top>SPlayer.Top then
       begin
         Inc(Punktescore);

         LScore.caption:=IntToStr((Punktescore)+1);
         if Punktescore >= MaxPunktescore then
         begin
           PStartStopClick(nil);
           ShowMessage('GameOver');
           Punktescore := 0; //oder Neustart
         end;


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