api:projects:pong:start
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende ÜberarbeitungNächste ÜberarbeitungBeide Seiten der Revision | ||
api:projects:pong:start [2020/12/29 12:59] – Martin Pabst | api:projects:pong:start [2021/01/20 22:49] – [Jetzt bist Du dran!] Martin Pabst | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== Beispielprojekt: | ====== Beispielprojekt: | ||
- | Pong ist eines der ersten Computerspiele. Es wurde 1972 von Atari entwickelt, [[https:// | + | Pong ist eines der ersten Computerspiele. Es wurde 1972 von Atari entwickelt, [[https:// |
+ | ==== 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: | ||
+ | * Der Ball soll eine kurze Spur hinter sich herziehen. | ||
+ | * Je schneller der Ball ist, desto roter wird er. | ||
< | < | ||
- | <div class=" | + | <div class=" |
<script type=" | <script type=" | ||
+ | // 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 { | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | // In diesen Attributen wird der Spielstand gespeichert: | ||
+ | | ||
+ | | ||
+ | |||
+ | /* | ||
+ | * 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. | ||
+ | */ | ||
+ | | ||
+ | schlägerLinks = new Schläger(0, | ||
+ | schlägerRechts = new Schläger(800 - 30, 100, " | ||
+ | ball = new Ball(schlägerLinks, | ||
+ | punkteAnzeige = new Text(400, 10, 48, "0 : 0"); | ||
+ | punkteAnzeige.setAlignment(Alignment.center); | ||
+ | punkteAnzeige.setFillColor(Color.white); | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | * Zeigt den aktuellen Punktestand an | ||
+ | */ | ||
+ | | ||
+ | punkteAnzeige.setText(punkteLinks + " : " + punkteRechts); | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | * Wird von der act-Methode des Balls aufgerufen, wenn der Ball den rechten | ||
+ | * Bildschirmrand überschreitet. | ||
+ | */ | ||
+ | | ||
+ | punkteLinks++; | ||
+ | zeigePunkte(); | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | * Wird von der act-Methode des Balls aufgerufen, wenn der Ball den linken | ||
+ | * Bildschirmrand überschreitet. | ||
+ | */ | ||
+ | | ||
+ | punkteRechts++; | ||
+ | zeigePunkte(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <script type=" | ||
+ | /** | ||
+ | * Ein Objekt der Klasse Schläger stellt den Schläger als Rechteck dar und bewegt ihn nach | ||
+ | * oben/unten wenn die Taste tasteHoch/ | ||
+ | */ | ||
+ | class Schläger extends Rectangle { | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | /** | ||
+ | * 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. | ||
+ | */ | ||
+ | | ||
+ | super(links, | ||
+ | this.tasteHoch = tasteHoch; | ||
+ | this.tasteRunter = tasteRunter; | ||
+ | move(0, | ||
+ | setFillColor(Color.white); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Die Methode act wird 30-mal pro Sekunde vom Browser aufgerufen. | ||
+ | */ | ||
+ | | ||
+ | /* | ||
+ | * Die Klasse Rectangle besitzt eine Methode isKeyDown, die genau dann true zurückgibt, | ||
+ | * eine bestimmte Taste gerade gedrückt ist. | ||
+ | */ | ||
+ | if(isKeyDown(tasteHoch)) { | ||
+ | // Falls der Schläger noch nicht am oberen Rand anschlägt, bewege ihn hoch: | ||
+ | | ||
+ | move(0, -geschwindigkeit); | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | if(isKeyDown(tasteRunter)) { | ||
+ | // Falls der Schläger noch nicht am unteren Rand anschlägt, bewege ihn runter: | ||
+ | | ||
+ | move(0, geschwindigkeit); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <script type=" | ||
+ | /** | ||
+ | * Die Klasse Ball stellt den Ball am Bildschirm dar, bewegt ihn, reagiert auf Kollision | ||
+ | * mit den Schlägern und dem oberen/ | ||
+ | * 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 { | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | /** | ||
+ | * Der Konstruktor der Klasse Ball initialisiert das Ball-Rechteck. | ||
+ | */ | ||
+ | | ||
+ | super(400 - breite / 2, 300 - breite / 2, breite, breite); | ||
+ | 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/ | ||
+ | * des Grafikbereichs rechts/ | ||
+ | */ | ||
+ | | ||
+ | move(vx, vy); // bewegt den Ball | ||
+ | | ||
+ | // stößt der Ball am oberen/ | ||
+ | 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)) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | | ||
+ | // ... entsprechend für den rechten Bildschirmrand: | ||
+ | if(getCenterX() > getWorld().getWidth() - schlägerRechts.getWidth() - breite / 2 + Math.abs(vx)) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | | ||
+ | if(this.collidesWith(schläger)) { | ||
+ | vx *= -1; | ||
+ | | ||
+ | | ||
+ | vy -= dy / schläger.getHeight() * 6; | ||
+ | } | ||
+ | | ||
+ | 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 " | ||
+ | */ | ||
+ | | ||
+ | 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: | ||
+ | if(Math.random() < 0.5) vy *= -1; // mit 50% Wahrscheinlichkeit: | ||
+ | } | ||
+ | |||
+ | } | ||
</ | </ | ||
</ | </ | ||
</ | </ |
api/projects/pong/start.txt · Zuletzt geändert: 2021/12/29 11:29 von 127.0.0.1