Benutzer-Werkzeuge

Webseiten-Werkzeuge


api:documentation:grafik:animation

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
api:documentation:grafik:animation [2021/01/06 17:57] – [Beispiel 3: Fliegende Bälle] Martin Pabstapi:documentation:grafik:animation [2021/12/29 11:29] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 14: Zeile 14:
   * Die Bewegung des Rechtecks ist sehr weich (ohne Ruckeln), da die ''act''-Methode im Gleichtakt mit der Render-Methode (s.o.) aufgerufen wird.   * Die Bewegung des Rechtecks ist sehr weich (ohne Ruckeln), da die ''act''-Methode im Gleichtakt mit der Render-Methode (s.o.) aufgerufen wird.
 <HTML> <HTML>
-<div class="java-online" style="height: 350px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'rotatingRectangle'}">+<div class="java-online" style="height: 350px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'rotatingRectangle', 'speed': 'max'}">
 <script type="text/plain" title="rotatingRectangle.java"> <script type="text/plain" title="rotatingRectangle.java">
 new World(1000, 1000); new World(1000, 1000);
Zeile 36: Zeile 36:
 ===== Beispiel 2: Hin- und herbewegende Rechtecke ===== ===== Beispiel 2: Hin- und herbewegende Rechtecke =====
   * Das ''MovingRectangle''-Objekt muss jederzeit "wissen", ob es sich gerade unterwegs zum rechten oder linken Rand befindet. Es benötigt daher ein Attribut, das diesen Zustand speichert. Wir verwenden das Attribut ''int dx'', in dem wir speichern, um wie viel sich das Rechteck im nächsten Schritt in x-Richtung bewegt. Ist ''dx == -8'', so bewegt sich das Rechteck nach links, ist ''dx == 8'', so bewegt sich das Rechteck nach rechts.   * Das ''MovingRectangle''-Objekt muss jederzeit "wissen", ob es sich gerade unterwegs zum rechten oder linken Rand befindet. Es benötigt daher ein Attribut, das diesen Zustand speichert. Wir verwenden das Attribut ''int dx'', in dem wir speichern, um wie viel sich das Rechteck im nächsten Schritt in x-Richtung bewegt. Ist ''dx == -8'', so bewegt sich das Rechteck nach links, ist ''dx == 8'', so bewegt sich das Rechteck nach rechts.
-  * Falls Du das Programm mit niedriger Geschwindigkeit startest, werden nur sehr wenige Quadrate gezeichnet, das Hauptprogramm läuft nicht mehr weiter. Die Ursache liegt darin, dass der Interpreter der Ausführung der ''act''-Methoden immer höhere Priorität einräumt als der Ausführung des Hauptprogramms. Da die ''act''-Methoden aber entsprechend der eingestellten Geschwindigkeit nur sehr langsam ablaufen, ist nach Ihrer Ausführung schon wieder 1/30 s vergangen, so dass die nächste ''act''-Methode ausgeführt wird und das Hauptprogramm nie zum Zug kommt. **Du musst also die Ausführungsgeschwindigkeit erhöhen, damit das Programm korrekt läuft.** 
 <HTML> <HTML>
-<div class="java-online" style="height: 350px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'movingRectangles'}">+<div class="java-online" style="height: 350px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'movingRectangles', 'speed': 'max'}">
 <script type="text/plain" title="movingRectangle.java"> <script type="text/plain" title="movingRectangle.java">
 new World(1000, 1000); new World(1000, 1000);
Zeile 74: Zeile 73:
 $$x_{neu} = x + v_{x, neu}\cdot\Delta t$$  $$x_{neu} = x + v_{x, neu}\cdot\Delta t$$ 
 $$y_{neu} = y + v_{y, neu}\cdot\Delta t$$  $$y_{neu} = y + v_{y, neu}\cdot\Delta t$$ 
-Das $g$ in der zweiten Gleichung ist die Erdbeschleunigung $g = 9,81\frac{m}{s^2}$. Aus dem "-" wird im Programm ein "+", da die Y-Achse nach unten zeigt. \\ \\ +Das $g$ in der zweiten Gleichung ist die Erdbeschleunigung $g = 9,81\frac{m}{s^2}$. Aus dem "-" wird im Programm ein "+", da die Y-Achse nach unten zeigt. $\Delta t$ ist in unserem Fall $\frac{1}{30} s$.\\ \\ 
-Als Spieleprogrammierer wollen wir natürlich, dass der Algorithmus möglichst schnell abläuft. Wir setzen daher $$\Delta t = 1$$ und passen dafür die Anfangsgeschwindigkeit und die Beschleunigung etwas an. Da sich $v_x$ nicht ändert, ist also nur noch folgendes zu tun:+Als Spieleprogrammierer wollen wir natürlich, dass der Algorithmus möglichst schnell abläuft. Wir setzen daher $$\Delta t = 1 s$$ und passen dafür die Anfangsgeschwindigkeit und die Beschleunigung etwas an. Da sich $v_x$ nicht ändert, ist bei jedem Zeitschritt also nur noch folgendes zu tun:
 $$v_{y, neu} = v_y + g$$ $$v_{y, neu} = v_y + g$$
 $$x_{neu} = x + v_x$$  $$x_{neu} = x + v_x$$ 
 $$y_{neu} = y + v_{y, neu}$$  $$y_{neu} = y + v_{y, neu}$$ 
-Als Physiklehrer graut es mir, wenn ich an die Einheiten der drei obigen Gleichungen denke (stellt Euch rechts jeweils "$\cdot 1 s$ vor, damit Ihr wieder ruhig schlafen könnt...), als Programmierer freue ich mich aber über die einfache und performante Umsetzung. Die zweite und dritte Gleichung zusammengenommen lassen sich jetzt nämlich mit einer einzigen Java-Anweisung erledigen: ''move(vx, vy)''.+Als Physiklehrer überfällt mich ein großes Unbehagen, wenn ich an die Einheiten der drei obigen Gleichungen denke. Stellt Euch daher rechts jeweils "$\cdot 1 s$ vor, damit Ihr wieder ruhig schlafen könnt ;-Als Programmierer freue ich mich aber über die einfache und performante Umsetzung. Die zweite und dritte Gleichung zusammengenommen lassen sich jetzt nämlich mit einer einzigen Java-Anweisung erledigen: ''move(vx, vy)''. \\ \\  
 +=== Erzeuger-Objekt === 
 +Im [[#beispiel_2hin-_und_herbewegende_rechtecke|Beispiel mit den hin- und herbewegenden Rechtecken]] haben wir die neuen Rechtecke im Hauptprogramm erzeugt. Das ist problematisch, da bei vielen Laufenden actor-Methoden nicht sichergestellt ist, mit welcher Geschwindigkeit das Hauptprogramm durchlaufen wird. Stell Dir vor, in einem Spiel würde die Rate, mit der vom Rechner Gegner erzeugt werden, von der Geschwindigkeit Deines Rechners abhängen! \\ Wir wollen es diesmal besser machen und erledigen die Erzeugung der Bälle ebenfalls in einem Ereignis-Handler. Dazu erstellen wir die Klasse ''Erzeuger'' als Unterklasse von ''Actor''. Letztere besitzt eine ''act''-Methode, die 30-mal pro Sekunde aufgerufen wird. Wir überschreiben sie mit einer eigenen Methode, die bei jedem fünften Aufruf einen neuen Ball erzeugt.
  
 <HTML> <HTML>
-<div class="java-online" style="height: 600px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'flyingCircles'}">+<div class="java-online" style="height: 600px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'flyingCircles', 'speed': 'max'}">
 <script type="text/plain" title="flyingCircles.java"> <script type="text/plain" title="flyingCircles.java">
 new World(800, 1000); new World(800, 1000);
Zeile 121: Zeile 122:
 </HTML> </HTML>
  
 +===== Beispiel 4: Feuerwerk =====
 +Dieses Beispiel habe ich als Wiederholungsübung für meine zehnten Klassen im Schuljahr 2020/21 geschrieben. Damals war wegen er Corona-Epidemie das Sylvesterfeuerwerk ausgefallen.
 +{{ youtube>4OY-p4M4hpY?large }}
 +<HTML>
 +<div class="java-online" style="height: 600px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Feuerwerk', 'speed': 'max'}">
 +<script type="text/plain" title="Feuerwerk.java">
 +new Feuerwerk();
 +
 +class Feuerwerk extends Actor {
 +   
 +   public void act() {
 +      if(Math.random() < 0.03) {
 +         
 +         int funkenzahl = Math.floor(Math.random() * 50 + 30);
 +         int farbe = Color.randomColor(128);
 +
 +         double x = Math.random() * 400 + 200;
 +         double y = Math.random() * 600;
 +         double lebensdauer = 60 + Math.random() * 60;
 +         for(int i = 0; i < funkenzahl; i++) {
 +            new Funke(x, y, farbe, lebensdauer);
 +         }
 +         Sound.playSound(Sound.cannon_boom);
 +
 +      }
 +   }
 +
 +}
 +
 +class Funke extends Circle {
 +   double vx;
 +   double vy;
 +   double lebensdauer;           // lebensdauer in 1/30 s
 +
 +   Funke(double x, double y, int farbe, double lebensdauer) {
 +      super(x, y, 4);
 +      double winkel = Math.random() * 2 * Math.PI;
 +      double v = Math.random() * 15 + 5;
 +      vx = v * Math.cos(winkel);
 +      vy = v * Math.sin(winkel);
 +      setFillColor(farbe);
 +      this.lebensdauer = lebensdauer;
 +   }
 +
 +   public void act() {
 +      lebensdauer--;
 +      move(vx, vy);
 +      vy = vy + 0.2;
 +      if(lebensdauer < 30) {
 +         setAlpha(lebensdauer / 30);
 +      }
 +      if(isOutsideView() || lebensdauer < 0) {
 +         destroy();
 +      }
 +   }
 +
 +}
 +</script>
 +</div>
 +</HTML>
  
api/documentation/grafik/animation.1609952278.txt.gz · Zuletzt geändert: 2021/12/29 11:29 (Externe Bearbeitung)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki