Benutzer-Werkzeuge

Webseiten-Werkzeuge


api:projects:pong:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
Nächste ÜberarbeitungBeide Seiten der Revision
api:projects:pong:start [2020/12/29 12:59] Martin Pabstapi:projects:pong:start [2021/01/20 22:49] – [Jetzt bist Du dran!] Martin Pabst
Zeile 1: Zeile 1:
 ====== Beispielprojekt: Pong ====== ====== Beispielprojekt: Pong ======
-Pong ist eines der ersten Computerspiele. Es wurde 1972 von Atari entwickelt, [[https://de.wikipedia.org/wiki/Pong|mehr dazu hier im Wikipedia-Artikel]]. Ziel des Spiel ist es - ähnlich wie beim Tennis, den Ball mit dem eigenen Schläger in die Hälfte des Gegners zu schlagen. Verfehlt man den Ball, so erhält der Gegner einen Punkt. Der linke Schläger wird mit den Tasten a und q gesteuert, der rechte mit den Tasten ö und p.+Pong ist eines der ersten Computerspiele. Es wurde 1972 von Atari entwickelt, [[https://de.wikipedia.org/wiki/Pong|mehr dazu hier im Wikipedia-Artikel]]. Ziel des Spiel ist es - ähnlich wie beim Tennis, den Ball mit dem eigenen Schläger in die Hälfte des Gegners zu schlagen. Verfehlt man den Ball, so erhält der Gegner einen Punkt. Der linke Schläger wird mit den Tasten a und q gesteuert, der rechte mit den Tasten ö und p. \\  
 +==== Jetzt bist Du dran! ==== 
 +Erweitere das Programm. Hier ein paar Ideen: 
 +  * Der Ball soll als Kreis dargestellt werden. 
 +  * Mit zunehmender Spieldauer soll der Betrag der Geschwindigkeit des Balls zunehmen, damit ein Tor herbeigeführt wird. Beim Anstoß soll der Ball wieder seine anfängliche Zufallsgeschwindigkeit haben. 
 +  * Herausforderung: Programmiere einen Single-Player-Mode, bei dem der rechte Schläger vom Computer gespielt wird. 
 +  * Der Ball soll eine kurze Spur hinter sich herziehen. 
 +  * Je schneller der Ball ist, desto roter wird er.
  
 <HTML> <HTML>
-<div class="java-online" style="height: 620px; width: 100%" data-java-online="{'withBottomPanel': true, 'id': 'Minesweeper'}">+<div class="java-online" style="height: 620px; width: 100%" data-java-online="{'withBottomPanel': true, 'id': 'Pong'}">
  
 <script type="text/plain" title="Pong.java"> <script type="text/plain" title="Pong.java">
 +// Im Hauptprogramm wird nur ein Pong-Objekt instanziert. Dadurch
 +// wird der Konstruktor der Klasse Pong aufgerufen, in dem 
 +// die weiteren Objekte (Schläger, Ball, ...) instanziert werden.
 +new Pong();
  
 +class Pong {
 +   
 +   private Schläger schlägerLinks;
 +   private Schläger schlägerRechts;
 +   private Ball ball;
 +
 +   private Text punkteAnzeige;
 +
 +   // In diesen Attributen wird der Spielstand gespeichert:
 +   private int punkteLinks = 0;
 +   private int punkteRechts = 0;
 +
 +   /*
 +    * Im Konstruktor werden die Schläger, der Ball und die Punkteanzeige 
 +    * instanziert. Danach ist das Hauptprogramm beendet. Weiter gehts in 
 +    * den act-Methoden der Schläger und des Balls, die 30-mal pro Sekunde
 +    * vom Browser aufgerufen werden.
 +    */
 +   public Pong() {
 +      schlägerLinks = new Schläger(0, 100, "q", "a");
 +      schlägerRechts = new Schläger(800 - 30, 100, "p", "ö");
 +      ball = new Ball(schlägerLinks, schlägerRechts, this);
 +      punkteAnzeige = new Text(400, 10, 48, "0 : 0");
 +      punkteAnzeige.setAlignment(Alignment.center);
 +      punkteAnzeige.setFillColor(Color.white);
 +   }
 +
 +   /*
 +    * Zeigt den aktuellen Punktestand an
 +    */
 +   private void zeigePunkte() {
 +      punkteAnzeige.setText(punkteLinks + " : " + punkteRechts);
 +   }
 +
 +   /*
 +    * Wird von der act-Methode des Balls aufgerufen, wenn der Ball den rechten
 +    * Bildschirmrand überschreitet.
 +    */
 +   public void punktFürLinkenSpieler() {
 +      punkteLinks++;
 +      zeigePunkte();
 +   }
 +
 +   /*
 +    * Wird von der act-Methode des Balls aufgerufen, wenn der Ball den linken
 +    * Bildschirmrand überschreitet.
 +    */
 +   public void punktFürRechtenSpieler() {
 +      punkteRechts++;
 +      zeigePunkte();
 +   }
 +
 +}
 +</script>
 +
 +<script type="text/plain" title="Schläger.java">
 +/**
 + * Ein Objekt der Klasse Schläger stellt den Schläger als Rechteck dar und bewegt ihn nach
 + * oben/unten wenn die Taste tasteHoch/tasteRunter gedrückt wird.
 + */
 +class Schläger extends Rectangle {
 +   
 +   private String tasteHoch;        // Taste, mit der der Schläger hochbewegt wird
 +   private String tasteRunter;      // Taste, mit der der Schläger runterbewegt wird
 +   
 +   private int geschwindigkeit = 8; // Geschwindigkeit des Schlägers in Pixel pro 1/30 s
 +   
 +   /**
 +    * Im Konstruktor wird das Schläger-Rechteck initialisiert. Damit die Schläger-Klasse sowohl zum 
 +    * Erzeugen des linken als auch des rechten Schläger-Objekts verwendet werden kann, werden dem Konstruktor
 +    * die x-Koordinate des linken Randes sowie die zwei Tasten zur Steuerung des Schlägers als Parameter übergeben.
 +    */
 +   public Schläger(double links, double höhe, String tasteHoch, String tasteRunter) {
 +      super(links, 0, 20, höhe);
 +      this.tasteHoch = tasteHoch;
 +      this.tasteRunter = tasteRunter;
 +      move(0,(getWorld().getHeight() - höhe) / 2);
 +      setFillColor(Color.white);
 +   }
 +
 +   /**
 +    * Die Methode act wird 30-mal pro Sekunde vom Browser aufgerufen.
 +    */
 +   public void act() {
 +      /*
 +       * Die Klasse Rectangle besitzt eine Methode isKeyDown, die genau dann true zurückgibt, wenn
 +       * eine bestimmte Taste gerade gedrückt ist. 
 +       */
 +      if(isKeyDown(tasteHoch)) {
 +         // Falls der Schläger noch nicht am oberen Rand anschlägt, bewege ihn hoch:
 +         if(getCenterY() > getHeight() / 2) {
 +            move(0, -geschwindigkeit);
 +         }
 +      }
 +      
 +      if(isKeyDown(tasteRunter)) {
 +         // Falls der Schläger noch nicht am unteren Rand anschlägt, bewege ihn runter:
 +         if(getCenterY() < getWorld().getHeight() - getHeight() / 2) {
 +            move(0, geschwindigkeit);
 +         }
 +      }
 +   }
 +   
 +
 +</script>
 +
 +<script type="text/plain" title="Ball.java">
 +/**
 + * Die Klasse Ball stellt den Ball am Bildschirm dar, bewegt ihn, reagiert auf Kollision
 + * mit den Schlägern und dem oberen/unteren Bildschirmrand. Sie registriert auch, ob der Ball
 + * den sichtbaren Bereich rechts oder links verlässt und veranlasst dann die Änderung des Spielstands 
 + * sowie einen Abstoß in der Mitte des Bildschirms.
 + */
 +class Ball extends Rectangle {
 +   
 +   private double vx;   // x-Komponente der Ballgeschwindigkeit (in Pixel je 1/30 s)
 +   private double vy;   // y-Komponente der Ballgeschwindigkeit
 +
 +   private double breite = 20;   // Breite und zugleich Höhe des Ball-Rechtecks
 +
 +   private Schläger schlägerLinks;  // Referenz auf das linke Schläger-Objekt
 +   private Schläger schlägerRechts; // Referenz auf das rechte Schläger-Objekt
 +
 +   private Pong pong;               // Referenz auf das Pong-Objekt
 +
 +   /**
 +    * Der Konstruktor der Klasse Ball initialisiert das Ball-Rechteck.
 +    */
 +   public Ball(Schläger schlägerLinks, Schläger schlägerRechts, Pong pong) {
 +      super(400 - breite / 2, 300 - breite / 2, breite, breite);  // Aufruf des Konstruktors der Oberklasse Rectangle
 +      setzeZufallsGeschwindigkeit();
 +      setFillColor(Color.white);
 +
 +      this.schlägerRechts = schlägerRechts;
 +      this.schlägerLinks = schlägerLinks;
 +      this.pong = pong;
 +   }
 +
 +   /**
 +    * Die Methode act wird vom Browser 30-mal pro Sekunde aufgerufen. Sie bewegt den Ball und
 +    * reagiert auf Kollisionen mit den Schlägern, dem oberen/unteren Rand sowie auf das Verlassen
 +    * des Grafikbereichs rechts/links.
 +    */
 +   public void act() {
 +      move(vx, vy);  // bewegt den Ball
 +      
 +      // stößt der Ball am oberen/unteren Rand an? => vy umkehren
 +      if(getCenterY() < breite / 2 || getCenterY() > getWorld().getHeight() - breite / 2) {
 +         vy *= -1;
 +      } 
 +
 +      testKollisionMitSchläger(schlägerLinks);
 +      testKollisionMitSchläger(schlägerRechts);
 +
 +      // Wenn sich der Ball schon um vx weiter links befindet als bei Berührung mit dem linken Schläger,
 +      // dann lassen wir kein Abprallen mit dem Schläger mehr zu, sondern werten es als Punkt für den 
 +      // rechten Spieler:
 +      if(getCenterX() < schlägerLinks.getWidth() + breite / 2 - Math.abs(vx)) {
 +         setCenter(400, 300);             // Abstoß in der Mitte des Grafikbereichs
 +         setzeZufallsGeschwindigkeit();
 +         pong.punktFürRechtenSpieler();
 +      }
 +      
 +      // ... entsprechend für den rechten Bildschirmrand:
 +      if(getCenterX() > getWorld().getWidth() - schlägerRechts.getWidth() - breite / 2 + Math.abs(vx)) {
 +         setCenter(400, 300);
 +         setzeZufallsGeschwindigkeit();
 +         pong.punktFürLinkenSpieler();
 +      }
 +
 +   }
 +
 +   private void testKollisionMitSchläger(Schläger schläger) {
 +      if(this.collidesWith(schläger)) {
 +         vx *= -1;
 +         double dy = schläger.getCenterY() - getCenterY();
 +         if(Math.abs(vy) < 10) {
 +            vy -= dy / schläger.getHeight() * 6; 
 +         }
 +         if(schläger == schlägerLinks) {
 +            Sound.playSound(Sound.pong_f);
 +         } else {
 +            Sound.playSound(Sound.pong_d);
 +         }
 +      }
 +   }
 +
 +   /**
 +    * Diese Methode gibt dem Ball eine zufällige Geschwindigkeit. Dabei dürfen aber keine Geschwindigkeitsvektoren
 +    * entstehen, die zu "flach" oder "steil" sind, da das Spiel sonst langweilig wird.
 +    */
 +   public void setzeZufallsGeschwindigkeit() {
 +      double v = Math.random() * 4 + 8;      // Betrag der Geschwindigkeit zwischen 8 und 12 (Pixel je 1/30 s)
 +      double winkel = Math.random() * Math.PI / 4 + Math.PI / 8;  // Winkel zwischen 22,5 und 67,5 Grad
 +      vx = Math.cos(winkel) * v;
 +      vy = Math.sin(winkel) * v;
 +      if(Math.random() < 0.5) vx *= -1;   // mit 50% Wahrscheinlichkeit: Spiegeln an der y-Achse
 +      if(Math.random() < 0.5) vy *= -1;   // mit 50% Wahrscheinlichkeit: Spiegeln an der x-Achse
 +   }
 +
 +}
 </script> </script>
 </div> </div>
 </HTML> </HTML>
api/projects/pong/start.txt · Zuletzt geändert: 2021/12/29 11:29 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki