unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  LCLTranslator, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls, Types;

type

  { TForm1 }

  TForm1 = class(TForm)
    Ball: TShape;
    LabelAnzeigeGeschwindigkeit: TLabel;
    TextfeldBreitePaddle: TEdit;
    BildEinstellungen: TImage;
    LabelBreitePaddel: TLabel;
    RadioGroupForm: TRadioGroup;
    ButtonStoppSpiel: TButton;
    TextfeldGeschwindigkeit: TEdit;
    LabelEinstellungen: TLabel;
    LabelGeschwindigkeit: TLabel;
    ButtonStart: TButton;
    Rahmen: TShape;
    LabelSpielEnde: TLabel;
    LabelSpielstand: TLabel;
    Paddle: TShape;
    Timer1: TTimer;
    UpDownGeschwindigkeit: TUpDown;
    UpDownBreitePaddle: TUpDown;

    procedure FormClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure PaddleBewegen(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure BildEinstellungenClick(Sender: TObject);
    procedure PaddleMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure RadioGroupFormClick(Sender: TObject);
    procedure SpielStart;
    procedure SpielstandZeigen;
    procedure ButtonStartClick(Sender: TObject);
    procedure ButtonStoppSpielClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure EndeSpiel;
    procedure UpDownGeschwindigkeitClick(Sender: TObject; Button: TUDBtnType);
    procedure UpDownBreitePaddleClick(Sender: TObject; Button: TUDBtnType);
    procedure GeschwindigkeitAnzeigen;
  private

  public

  end;

var
  Form1: TForm1;
  Treffer: Integer;
  GeschwindigkeitX, GeschwindigkeitY: Integer;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
   SetDefaultLang('de');
   TextfeldGeschwindigkeit.Text:= IntToStr(UpDownGeschwindigkeit.Position);
   TextfeldBreitePaddle.Text:= IntToStr(UpDownBreitePaddle.Position);
   LabelSpielEnde.Visible:= false;
   LabelAnzeigeGeschwindigkeit.Caption:= 'Geschwindigkeit: ' + IntToStr(UpDownGeschwindigkeit.Position);
end;

procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
var
  WertX: Integer;
begin
   // Testen ob GeschwindigkeitX negativ ist
  if GeschwindigkeitX > 0 then WertX:= GeschwindigkeitX
  else WertX:= -GeschwindigkeitX;

  if WertX > 1 then
  begin
     if (GeschwindigkeitX > 0) and (GeschwindigkeitY > 0) then
     begin
       dec(GeschwindigkeitX);
       dec(GeschwindigkeitY);
       GeschwindigkeitAnzeigen;
     end;

     if (GeschwindigkeitX > 0) and (GeschwindigkeitY < 0) then
     begin
       GeschwindigkeitY:= -GeschwindigkeitY;
       dec(GeschwindigkeitX);
       dec(GeschwindigkeitY);
       GeschwindigkeitAnzeigen;
       GeschwindigkeitY:= -GeschwindigkeitY;
     end;

     if (GeschwindigkeitX < 0) and (GeschwindigkeitY > 0) then
     begin
       GeschwindigkeitX:= -GeschwindigkeitX;
       dec(GeschwindigkeitX);
       dec(GeschwindigkeitY);
       GeschwindigkeitAnzeigen;
       GeschwindigkeitX:= -GeschwindigkeitX;
    end;

    if (GeschwindigkeitX < 0) and (GeschwindigkeitY < 0) then
    begin
       GeschwindigkeitX:= -GeschwindigkeitX;
       GeschwindigkeitY:= -GeschwindigkeitY;
       dec(GeschwindigkeitX);
       dec(GeschwindigkeitY);
       GeschwindigkeitAnzeigen;
       GeschwindigkeitX:= -GeschwindigkeitX;
       GeschwindigkeitY:=-GeschwindigkeitY;
     end;
  end;
end;

procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
   // von links nach unten
   if (GeschwindigkeitX > 0) and (GeschwindigkeitY > 0) then
   begin
     inc(GeschwindigkeitX);
     inc(GeschwindigkeitY);
     GeschwindigkeitAnzeigen;
   end;

   // von links nach oben
   if (GeschwindigkeitX > 0) and (GeschwindigkeitY < 0) then
   begin
     GeschwindigkeitY:= -GeschwindigkeitY;
     inc(GeschwindigkeitX);
     inc(GeschwindigkeitY);
     GeschwindigkeitAnzeigen;
     GeschwindigkeitY:= -GeschwindigkeitY;
   end;

   // von rechts nach unten
   if (GeschwindigkeitX < 0) and (GeschwindigkeitY > 0) then
   begin
     GeschwindigkeitX:= -GeschwindigkeitX;
     inc(GeschwindigkeitX);
     inc(GeschwindigkeitY);
     GeschwindigkeitAnzeigen;
     GeschwindigkeitX:= -GeschwindigkeitX;
   end;

   // von rechts nach oben
   if (GeschwindigkeitX < 0) and (GeschwindigkeitY < 0) then
   begin
     GeschwindigkeitX:= -GeschwindigkeitX;
     GeschwindigkeitY:= -GeschwindigkeitY;
     inc(GeschwindigkeitX);
     inc(GeschwindigkeitY);
     GeschwindigkeitAnzeigen;
     GeschwindigkeitX:= -GeschwindigkeitX;
     GeschwindigkeitY:=-GeschwindigkeitY;
   end;
end;

procedure TForm1.FormClick(Sender: TObject);
begin
   // Spiel pausieren
   if Timer1.Enabled= true then Timer1.Enabled:= false
   else Timer1.Enabled:= true;
   // Einstellungsfenster angezeigt -> ausblenden
   if Rahmen.Visible= true then
   begin
      LabelSpielEnde.Visible:= false;
      ButtonStart.Visible:= false;
      LabelEinstellungen.Visible:= false;
      UpDownGeschwindigkeit.Visible:= false;
      UpDownBreitePaddle.Visible:= false;
      Rahmen.Visible:= false;
      LabelGeschwindigkeit.Visible:= false;
      LabelBreitePaddel.Visible:= false;
      TextfeldGeschwindigkeit.Visible:= false;
      TextfeldBreitePaddle.Visible:= false;
      ButtonStoppSpiel.Visible:= false;
      RadioGroupForm.Visible:= false;
      LabelBreitePaddel.Visible:= false;
   end;
end;

procedure TForm1.PaddleBewegen(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   // X-> Mausposition X-Achse
   // davon wird die Hälfte der Breite des Paddles abgezogen
   Paddle.Left:= X - Paddle.Width div 2;
   // das Paddle wird immer am unteren Ende platziert
   // auch wenn die Form in der Größe verändert wird
   Paddle.Top:= Form1.Height - Paddle.Height;
end;

procedure TForm1.BildEinstellungenClick(Sender: TObject);
begin
   // LabelEinstellungen anzeigen
   ButtonStart.Visible:= true;
   LabelEinstellungen.Visible:= true;
   UpDownGeschwindigkeit.Visible:= true;
   UpDownBreitePaddle.Visible:= true;
   Rahmen.Visible:= true;
   LabelGeschwindigkeit.Visible:= true;
   LabelBreitePaddel.Visible:= true;
   TextfeldGeschwindigkeit.Visible:= true;
   TextfeldBreitePaddle.Visible:= true;
   ButtonStoppSpiel.Visible:= true;
   RadioGroupForm.Visible:= true;
   // Ball sichtbar platzieren
   Ball.Top:= ClientWidth div 2;
   Ball.Left:= ClientHeight div 2;
   // aktuelle Geschwindigkeit anzeigen
   if GeschwindigkeitX < 0 then GeschwindigkeitX:= GeschwindigkeitX * -1;
   TextfeldGeschwindigkeit.Text:= IntToStr(GeschwindigkeitX);
   UpDownGeschwindigkeit.Position:= GeschwindigkeitX;
   // Timer stoppen
   Timer1.Enabled:= false;
end;

procedure TForm1.PaddleMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   // Aufruf
   PaddleBewegen(Sender, Shift, X + Paddle.Left, Y + Paddle.Top)
end;

procedure TForm1.RadioGroupFormClick(Sender: TObject);
begin
  case RadioGroupForm.ItemIndex of
     0: Ball.Shape:= stCircle;
     1: Ball.Shape:= stSquare;
     2: Ball.Shape:= stRoundSquare;
     3: Ball.Shape:= stDiamond;
     4: Ball.Shape:= stStar;
  end;

end;

procedure TForm1.SpielstandZeigen;
begin
   LabelSpielstand.Caption:= 'Treffer: ' + IntToStr(Treffer);
   if Treffer > 0 then
   begin
      if Treffer mod 10 = 0 then
      begin
         // negative GeschwindigkeitX
        if GeschwindigkeitX < 0 then dec(GeschwindigkeitX)
        else inc(GeschwindigkeitX);
        inc(GeschwindigkeitY);
        if  GeschwindigkeitX < 0 then LabelAnzeigeGeschwindigkeit.Caption:= 'Geschwindigkeit: ' + IntToStr(-GeschwindigkeitX)
        else LabelAnzeigeGeschwindigkeit.Caption:= 'Geschwindigkeit: ' + IntToStr(GeschwindigkeitX);
      end;
   end;
end;

procedure TForm1.ButtonStartClick(Sender: TObject);
begin
  SpielStart;
end;

procedure TForm1.ButtonStoppSpielClick(Sender: TObject);
begin
   Application.Terminate;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Ball.Left:= Ball.Left + GeschwindigkeitX;
  Ball.Top:= Ball.Top + GeschwindigkeitY;
  // Game Over -> Ball am unteren Ende
  if Ball.Top + Ball.Height >= ClientHeight then
  begin
     EndeSpiel;
  end;

  // rechts und links
  if (Ball.Left<= 0) or (Ball.Left + Ball.Width>= ClientWidth) then GeschwindigkeitX:=- GeschwindigkeitX;
  // oben -> Geschwindigkeit rückwärts
  if (Ball.Top<= 0) then
  begin
    GeschwindigkeitY:=- GeschwindigkeitY;
    inc(Treffer);
    SpielstandZeigen;
  end;
  // Ball berührt Paddle
  // linker Rand -> Ball.Left + Ball.Width>= Paddle.Left
  // rechter Rand -> Ball.Left<= Paddle.Left + Paddle.Width
  // oberer Rand -> Ball.Top + Ball.Height>= Paddle.Top
  if (Ball.Left + Ball.Width>= Paddle.Left) and (Ball.Left<= Paddle.Left + Paddle.Width)
  and (Ball.Top + Ball.Height>= Paddle.Top) then
  begin
    // Paddle getroffen -> Geschwindigkeit rückwärts
    GeschwindigkeitY:= -GeschwindigkeitY;
  end;
end;

procedure TForm1.EndeSpiel;
begin
   LabelSpielEnde.Visible:= true;
   Timer1.Enabled:= false;
end;

procedure TForm1.UpDownGeschwindigkeitClick(Sender: TObject; Button: TUDBtnType);
begin
  inc(GeschwindigkeitX);
  inc(GeschwindigkeitY);
  TextfeldGeschwindigkeit.Text:= IntToStr(UpDownGeschwindigkeit.Position);
  LabelAnzeigeGeschwindigkeit.Caption:= 'Geschwindigkeit: ' + IntToStr(UpDownGeschwindigkeit.Position);
end;

procedure TForm1.UpDownBreitePaddleClick(Sender: TObject; Button: TUDBtnType);
begin
  TextfeldBreitePaddle.Text:= IntToStr(UpDownBreitePaddle.Position);
  Paddle.Width:= UpDownBreitePaddle.Position;
end;

procedure TForm1.GeschwindigkeitAnzeigen;
begin
   LabelAnzeigeGeschwindigkeit.Caption:= 'Geschwindigkeit: ' + IntToStr(GeschwindigkeitX);
end;

procedure TForm1.SpielStart;
begin
  // zufällige Startposition > Hälfte der Höhe
   Randomize;
   Ball.Left:= Random(ClientWidth - Ball.Height);
   Ball.Top:= Random((ClientHeight - Ball.Width) div 2);
   Treffer:= 0;
   // Elemente Fenster Einstellungen ausblenden
   // Labels
   LabelSpielEnde.Visible:= false;
   LabelEinstellungen.Visible:= false;
   LabelGeschwindigkeit.Visible:= false;
   LabelBreitePaddel.Visible:= false;
   LabelBreitePaddel.Visible:= false;
   // Buttons
   ButtonStart.Visible:= false;
   ButtonStoppSpiel.Visible:= false;
   // UpDown-Elemente
   UpDownGeschwindigkeit.Visible:= false;
   UpDownBreitePaddle.Visible:= false;
   // Textfelder
   TextfeldGeschwindigkeit.Visible:= false;
   TextfeldBreitePaddle.Visible:= false;
   // Rahmen Einstellungen
   Rahmen.Visible:= false;
   // RadioGroup Form Ball
   RadioGroupForm.Visible:= false;
   DoubleBuffered:= true;
   // Timer starten
   Timer1.Enabled:= true;
   // Geschwindigkeit lesen und festlegen
   GeschwindigkeitX:= UpDownGeschwindigkeit.Position;
   GeschwindigkeitY:= UpDownGeschwindigkeit.Position;
   // Breite des Paddles
   Paddle.Width:= UpDownBreitePaddle.Position;
   SpielstandZeigen;
   GeschwindigkeitAnzeigen;
end;

end.

