Benutzer-Werkzeuge

Webseiten-Werkzeuge


api:documentation:spiele:sprites

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


Vorhergehende Überarbeitung
api:documentation:spiele:sprites [2025/04/06 08:11] (aktuell) martin
Zeile 1: Zeile 1:
 +====== Sprites ======
 +<WRAP center round info 80%>
 +Sprites ([[https://dict.leo.org/englisch-deutsch/sprite|aus dem Englischen: Elfe, Kobold, Wicht]]) sind Bitmap-Grafiken, die direkt von der Grafikkarte auf den Bildschirm gezeichnet werden und daher den Hauptprozessor des Rechners kaum beanspruchen. Von vielen Betriebssystemen wird beispielsweise der Mauszeiger oder der Textcursor durch ein Sprite dargestellt, auch in vielen (v.a. zweidimensionalen) Computerspielen finden sie Verwendung.
 +  * [[https://www.online-ide.de/spriteLibrary.html|Übersicht über alle in der Online-IDE eingebauten Sprites]]
 +</WRAP>
 +
 +===== Beispiel 1: Raumschiff und Smilies =====
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Sprite_1'}">
 +
 +<script type="text/plain" title="Sprite_1.java">
 +Sprite raumschiff = new Sprite(400, 300, SpriteLibrary.Ship_1, 0);
 +
 +raumschiff.scale(0.5);
 +raumschiff.rotate(30);
 +
 +for(int i = 0; i < 100; i++) {
 +   Sprite smiley = new Sprite(Math.random() * 800, Math.random() * 600, SpriteLibrary.Minesweeper, 18);
 +   smiley.rotate(Math.random()*180);
 +   smiley.scale(2);
 +}
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
 +<WRAP left round info 80%>
 +Ein Sprite wird durch die Angabe der x- und y-Koordinate seines "Mittelpunktes", des Namens der Bilderfolge und des Index innerhalb dieser Folge instanziert.
 +<code myJava>
 +new Sprite(400, 300, SpriteLibrary.Ship_1, 0);
 +</code>
 +etwa instanziert ein Sprite, das das erste (index == 0) Bild der Bilderfolge "Ship_1" darstellt.
 +</WRAP>
 +
 +
 +===== Übersicht über die Bilderfolgen =====
 +[[https://www.online-ide.de/spriteLibrary.html|Einen Überblick über alle Bilderfolgen erhaltet Ihr hier.]]
 +
 +===== Animation von Sprites =====
 +<WRAP left round info 80%>
 +Es gibt Bilderfolgen, die - schnell hintereinander abgespielt - einen kleinen "Film" (Animation) ergeben. Diese Animationen kann man mit der Methode ''playAnimation'' abgespielt werden.
 +<code myJava>
 +Sprite explosion = new Sprite(400, 300, SpriteLibrary.Explosion_1, 0);
 +explosion.playAnimation(0, 63, RepeatType.loop, 15);
 +</code>
 +Spielt die Bilder mit den Indizes 0 bis 63 (jeweils einschließlich) mit der Geschwindigkeit 15 Bilder pro Sekunde ab, wobei nach dem 63. Bild die Animation wieder von vorne begonnen wird (RepeatType.loop).
 +</WRAP>
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 200px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Sprite_2'}">
 +
 +<script type="text/plain" title="Sprite_2.java">
 +Sprite explosion = new Sprite(400, 300, SpriteLibrary.Explosion_1, 0);
 +explosion.scale(6);
 +explosion.playAnimation(0, 63, RepeatType.loop, 15);
 +
 +while(true);
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
 +===== Kollision =====
 +Wie bei allen anderen Grafikobjekten kann auch bei Sprites mit er Methode ''collidesWith'' ausgewertet werden, ob ein Sprite mit einem anderen Objekt überlappt. Soll die Kollision mit vielen gleichartigen Objekten ausgewertet werden, so empfiehlt es sich aus Performancegründen, diese Objekte in einer Gruppe zusammenzufassen und die Kollision mithilfe der Methode ''getCollidingShapes'' der Gruppe zu suchen.
 +<HTML>
 +
 +<div class="java-online" style="height: 600px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Sprite_3'}">
 +
 +<script type="text/plain" title="Sprite_3.java">
 +new RechteckAngriff();
 +
 +class RechteckAngriff extends Actor {
 +   
 +   Group rechtecke = new Group();
 +   Sprite ship = new Sprite(200, 300, SpriteLibrary.Ship_1, 0);
 +
 +   public RechteckAngriff() {
 +      super();
 +      ship.scale(0.5);
 +   }
 +
 +   public void act() {
 +      if(Math.random() < 0.3) {
 +         rechtecke.add(new FliegendesRechteck());
 +      } 
 +
 +      Shape[] kollidierendeRechtecke = rechtecke.getCollidingShapes(ship);
 +
 +      for(Shape shape : kollidierendeRechtecke) {
 +         Sprite explosion = new Sprite(shape.getCenterX(), shape.getCenterY(), SpriteLibrary.Explosion_1, 0);
 +         explosion.scale(3);
 +         explosion.rotate(Math.random() * 360);
 +         explosion.playAnimation(0, 55, RepeatType.once, 30);
 +         shape.destroy();         
 +      }
 +
 +   }
 +
 +}
 +
 +class FliegendesRechteck extends Rectangle {
 +   
 +   double vy = Math.random() * 10 - 5;
 +   double vAngle = Math.random() * 4;
 +
 +   public FliegendesRechteck() {
 +      super(800, Math.random() * 600, Math.random() * 50 + 20, Math.random() * 100 + 20);
 +      this.setBorderColor(null);
 +      this.setFillColor((int)(Math.random() * 0xffffff), 0.5);
 +   }
 +
 +   public void act() {
 +      move(-15, vy);
 +      rotate(vAngle);
 +      if(getCenterX() < 0) {
 +         destroy();
 +      } 
 +
 +   }
 +
 +}
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
 +
 +===== Tiled Sprites =====
 +{{ :api:documentation:spiele:pasted:20210621-180539.png?350}}
 +<WRAP left round info 50%>
 +  * Die Methode ''makeTiling(double width, double height)'' macht aus einem Sprite eine "Kachelfläche" der Breite ''width'' und der Höhe ''height'', indem das Sprite-Bild geeignet oft neben- und untereinander gezeichnet wird. 
 +  * Alle Methodenaufrufe des Sprites (z.B. ''move'', ''scale'', ...) beziehen sich auf die Kachelfläche als Ganzes. 
 +  * Möchte man die einzelnen Kachelbilder verändern, so erhält man mit der Methode ''getTileImage()'' ein Objekt, das einem geeignete Methoden ''move'' und ''scale'' hierzu bietet. 
 +  * Die Methode ''getTileImage().move(double dx, double dy)'' verschiebt die Bilddaten um die angegebene Verschiebung und fügt sie zyklisch in der gegenüberliegenden Richtung wieder an. Dadurch entsteht ein Scroll-Effekt. Starte am besten das nachfolgende Beispielprogramm, dann siehst Du sofort, was gemeint ist!
 +</WRAP>
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Sprite_4'}">
 +
 +<script type="text/plain" title="Sprite_4.java">
 +new Beweger();
 +
 +class Beweger extends Actor {
 +
 +   Sprite s;
 +   
 +   Beweger() {
 +      s = new Sprite(200, 200, SpriteLibrary.Boulders, 0);
 +      s.makeTiling(160, 96);
 +      s.scale(3); 
 +   }
 +
 +   void act() {
 +      s.getTileImage().move(2, 1); 
 +   }
 +}
 +</script>
 +
 +</HTML>
 +
 +
 +===== Sprite als Hintergrundbild setzen =====
 +
 +<WRAP left round info 50%>
 +Die Methode ''setAsBackgroundImage()'' skaliert und verschiebt das Sprite so, dass es den gesamten Hintergrund gerade überdeckt. Zudem setzt sie das Bild in der Zeichenreihenfolge nach hinten, so dass es von allen anderen graphischen Objekten überdeckt wird. Die Skalierung erfolgt in x- und y-Richtung gleichartig, damit das Bild nicht verzerrt erscheint. Falls das Bild also ein anderes Seitenverhältnis hat als die Zeichenfläche, lässt die Methode rechts oder unten ein Stück des Bildes überstehen.
 +</WRAP>
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Sprite_setAsBackgroundImage'}">
 +
 +<script type="text/plain" title="Sprite_5.java">
 +new Circle(300, 200, 100).setFillColor(0xff2020);     // obwohl der Kreis vorher instanziert wird...
 +
 +Sprite s = new Sprite(200, 200, SpriteLibrary.Background, 2);
 +
 +s.setAsBackgroundImage();        // ... erscheint er jetzt HINTER dem Wolkenbild
 +
 +// Zur Info: Die Methode setAsBackground macht dasselbe wie:
 +// s.moveTo(World.getWorld().getLeft() +  World.getWorld().getWidth() / 2, World.getWorld().getTop() + World.getWorld().getHeight() / 2);
 +// s.scale(World.getWorld().getHeight() / s.getHeight());
 +// s.sendToBack();
 +</script>
 +</div>
 +</HTML>