Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   RandomRange() oder Random() beim Bewegen einer Komponente (https://www.delphipraxis.net/179269-randomrange-oder-random-beim-bewegen-einer-komponente.html)

faCee 24. Feb 2014 12:39

RandomRange() oder Random() beim Bewegen einer Komponente
 
Moin,

habe zur Zeit folgendes Problem:

Ich versuche den Klassiker Pong mit Pascal nachzuprogrammieren.
Das Spiel hat bei mir zwei Modi, "klassisch" und "auf Zeit".

Zum Verständnis:

Die beiden Balken und der Ball sind Shapes.

Der "auf Zeit"-Modus ist soweit implementiert. In jenem Modus spielt der Spieler auf Zeit gegen den Gegner-Balken, der immer den Ball abfängt.

Mein Problem liegt nun im "klassisch"-Modus. Da im "auf Zeit"-Modus der Ball immer im selben Winkel von den Wänden abprallt (und so auch praktisch immer das gleiche Bewegungsmuster hat), wollte ich ihm hier mit einem zufälligen Wert für die horizontale Geschwindigkeit an den Leib rücken.
Jedoch scheint dieser Wert immer gleich 0 zu sein, da der Ball sich nur hoch und runter bewegt.
Ich habe es mit Random() und RandomRange versucht.

Hier der Code der Timer-Prozedur, die die Steuerung des Balles übernimmt:
Delphi-Quellcode:
//Sorgt für die Bewegung des Balls und achtet auf die Spielregeln
procedure TForm1.tmrBewegerTimer(Sender: TObject);
begin

   //vZufallLinks := RandomRange(6, 24);
   //vZufallRechts := RandomRange(6, 24);

  //Falls der Ball steht
  if (vBallSteht = True) then
   begin
     //shpBall.Top := shpBall.Top + 1;    //Spielt dem Spieler bei Spielbeginn den Ball zu
     vBallAufschlag := True;
     vBallSteht := False;
   end;

  //Falls der Aufschlag kommt; zum Spieler!
  if (vBallAufschlag = True) then
   begin

     vAnfang := Now;
     tmrZaehler.Enabled := True;

     shpBall.Top := (shpBall.Top + 12);
     if (shpBall.Top = shpSP1.Top) then
      begin

         if (shpBall.Left >= shpSP1.Left) and (shpBall.Left <= (shpSP1.Left + 100)) then
           begin
             vBallNachOben := True;
             vBallAufschlag := False;

             vZufall := Random(2);
             if (vZufall = 1) then
              begin
               vBallNachRechts := True;
               vBallNachLinks := False;
              end
             else
              begin
               vBallNachRechts := False;
               vBallNachLinks := True;
              end;

           end;

      end;

   end;

  //Falls der Ball nach unten fliegen soll
  if (vBallNachUnten = True) then
   begin

     shpBall.Top := (shpBall.Top + 12);
     if (shpBall.Top = shpSP1.Top) then
      begin

         if (shpBall.Left >= shpSP1.Left) and (shpBall.Left <= (shpSP1.Left + 100)) then
           begin
             vBallNachOben := True;
             vBallNachUnten := False;

             if (vBallNachLinks = True) then
              begin
                 vBallNachRechts := False;
              end
             else
              begin
                 vBallNachLinks := False;
                 vBallNachRechts := True
              end;

           end;

      end;

   end;

  //Falls der Ball nach oben fliegen soll
  if (vBallNachOben = True) then
   begin

      shpBall.Top := (shpBall.Top - 12);
      if (shpBall.Top = shpCPU.Top + 10) then
       begin

          if (shpBall.Left >= shpCPU.Left) and (shpBall.Left <= (shpCPU.Left + 100)) then
           begin
             vBallNachOben := False;
             vBallNachUnten := True;

             if (vBallNachLinks = True) then
              begin
                 vBallNachRechts := False
              end
             else
              begin
                 vBallNachLinks := False;
                 vBallNachRechts := True;
              end;

           end;

       end;

   end;

   //Falls der Ball nach rechts fliegen soll
   if (vBallNachRechts = True) then
    begin

     if (rdbKlassik.Checked = True) then
      begin
        shpBall.Left := (shpBall.Left + vZufallRechts);
      end
     else
      begin
        shpBall.Left := (shpBall.Left + 12);
      end;

    end;

   //Falls der Ball nach links fliegen soll
   if (vBallNachLinks = True) then
    begin

      if (rdbKlassik.Checked = True) then
      begin
        shpBall.Left := (shpBall.Left - vZufallLinks);
      end
     else
      begin
        shpBall.Left := (shpBall.Left - 12);
      end;

    end;

   //Falls der Ball von unten an die rechte Wand stößt
   if (shpBall.Left >= 590) and (vBallNachOben = True) then
    begin

      vZufallLinks := RandomRange(6, 24);

      vBallNachRechts := False;
      vBallNachLinks := True;

    end;

   //Falls der Ball von unten an die linke Wand stößt
   if (shpBall.Left <= 10) and (vBallNachOben = True) then
    begin

      vZufallRechts := RandomRange(6, 24);

      vBallNachRechts := True;
      vBallNachLinks := False;

    end;

   //Falls der Ball von Oben an die rechte Wand stößt
   if (shpBall.Left >= 590) and (vBallNachUnten = True) then
    begin

      vZufallLinks := RandomRange(6, 24);

      vBallNachRechts := False;
      vBallNachLinks := True;

    end;

   //Falls der Ball von Oben an die linke Wand stößt
   if (shpBall.Left <= 10) and (vBallNachUnten = True) then
    begin

      vZufallRechts := RandomRange(6, 24);

      vBallNachRechts := True;
      vBallNachLinks := False;

    end;

   //Beendet die Runde, falls der Ball den unteren Rand übertritt!
   if (shpBall.Top >= 400) then
    begin

      vBeginne := False;
      vBallNachUnten := False;
      vBallNachOben := False;
      vBallNachLinks := False;
      vBallNachRechts := False;
      vBallSteht := False;
      vBallAufschlag := False;

      tmrBeweger.Enabled := False;
      tmrZaehler.Enabled := False;
      tmrCPU.Enabled := False;

      shpSP1.Left := 250;
      shpCPU.Left := 250;
      shpBall.Left := 296;
      shpBall.Top := 200;

      vZeit := lblZeit.Caption;

      ShowMessage('Spiel verloren! Deine erreichte Zeit: '+ vZeit +' Sekunden');

      beep;

      btnSpielen.Enabled := True;

    end;

end;
Ich hoffe, dass jemand da eine Idee hat. :)

baumina 24. Feb 2014 12:53

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Vielleicht Randomize vergessen.

DeddyH 24. Feb 2014 12:58

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Das ist eine Menge Code für ein wenig Bewegung. Zullererst solltest Du auf jeden Fall die ganzen Vergleiche mit true entfernen (siehe z.B. hier). Und eigentlich braucht man die ganzen Boolean-Variablen gar nicht, es genügt doch je ein Integerwert für die X- und die Y-Achse, das Vorzeichen bestimmt dann die Richtung.

P.S.: Gruß ins Sauerland, da bin ich geboren und aufgewachsen :)

[edit]P.P.S: Sry, Willkommen in der DP :dp: [/edit]

faCee 24. Feb 2014 13:00

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Zitat:

Zitat von baumina (Beitrag 1249285)
Vielleicht Randomize vergessen.

Nein,

Randomize()

ist in Form1.Create drinne...

faCee 24. Feb 2014 13:07

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Zitat:

Zitat von DeddyH (Beitrag 1249287)
Das ist eine Menge Code für ein wenig Bewegung. Zullererst solltest Du auf jeden Fall die ganzen Vergleiche mit true entfernen (siehe z.B. hier). Und eigentlich braucht man die ganzen Boolean-Variablen gar nicht, es genügt doch je ein Integerwert für die X- und die Y-Achse, das Vorzeichen bestimmt dann die Richtung.

P.S.: Gruß ins Sauerland, da bin ich geboren und aufgewachsen :)

[edit]P.P.S: Sry, Willkommen in der DP :dp: [/edit]

Ich hatte erst gar nicht gedacht, dass für Pong soviel anfällt. :D
Habe den Eintrag auf delphi-treff gelesen und das Spiel noch mal umprogrammieren.

Apropos, wenn ich auf Zufallszahlen verzichten wollte, wie würde ich am besten die Winkel berechnen?
Habe im Netz Beiträge dazu gelesen, aber bin nicht ganz schlau draus geworden.

Gruß zurück, wunderschöne Region. :)

DeddyH 24. Feb 2014 13:16

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Wenn ich an das originale Pong zurückdenke (ich bin so alt, dass ich das noch kenne), dann war der Winkel von der Aufprallposition auf dem Schläger abhängig: je weiter außen, desto steiler.

faCee 24. Feb 2014 13:21

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Zitat:

Zitat von DeddyH (Beitrag 1249292)
Wenn ich an das originale Pong zurückdenke (ich bin so alt, dass ich das noch kenne), dann war der Winkel von der Aufprallposition auf dem Schläger abhängig: je weiter außen, desto steiler.

Alles klar, vielen Dank! :D Klemme mich gleich dahinter und erstatte Bericht, wenn's fertig ist.

DeddyH 24. Feb 2014 13:24

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Gern geschehen. Anregungen sollten sich übrigens auch hier im Forum finden lassen: Hier im Forum suchenKollisionskontrolle Hier im Forum suchenBallbewegung Hier im Forum suchenPong

faCee 24. Feb 2014 17:06

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
So,

habe mich grad an das Neuprogrammieren der Prozedur gewagt und habe leider mein erstes Problem.
Zuerst will, dass der Ball sich nach unten bewegt und vom Spieler-Balken (der später mal in 3 Sektoren unterteilt sein wird, was aber erst noch kommt) abprallt.

Allerdings fliegt der Ball einfach durch den Schläger.

Hier der Quelltext:
Delphi-Quellcode:
//Falls der Ball auf den unteren Balken trifft

   if (shpBall.Top = (shpSP1.Top - 10)) then
    begin
      vY := (vY * (-1));
    end;

//Bewegung des Balles
   shpBall.Top := (shpBall.Top + vY);    //Steuert vertikal!
   shpBall.Left := (shpBall.Left + vX);  //Steuert horizontal!
Erläuterung: shpSP1 ist die Shape-Komponente die den Balken des Spielers darstellt. shpBall ist der Ball.

Gruß :)

DeddyH 24. Feb 2014 17:17

AW: RandomRange() oder Random() beim Bewegen einer Komponente
 
Zitat:

Delphi-Quellcode:
if (shpBall.Top = (shpSP1.Top - 10)) then

Bist Du sicher, dass der Abstand exakt 10 Pixel betragen muss? Was ist denn, wenn er kleiner wird (durch ungünstige Schrittweite z.B.)?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:58 Uhr.
Seite 1 von 2  1 2      

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