{
  "name": "Spielwerkstatt: nach Kontrollstrukturen",
  "settings": {
    "language": "Java",
    "libraries": [
      "scratch",
      "nrw"
    ]
  },
  "modules": [
    {
      "name": "Welt.java",
      "text": "/// Deine Spielwelt. Hier stellst du alles auf, was im Spiel vorkommt.\npublic class Welt extends Spielwelt {\n\n   /// So viele Münzen hat der Spieler schon eingesammelt.\n   private int punkte = 0;\n   /// So viele Münzen liegen insgesamt in der Welt.\n   private int anzahlMuenzen = 0;\n   /// So viele Sekunden bleiben noch.\n   private double zeit = 30;\n   /// Solange das true ist, läuft das Spiel noch.\n   private boolean laeuft = true;\n   /// Die Anzeige oben links.\n   private Text anzeige;\n   /// Die Spielfigur. Sie ist eine Variable der Welt, damit run() sie anhalten kann.\n   private Spieler held;\n\n   public Welt() {\n      // Ein Rahmen aus Steinen, damit niemand aus dem Bild läuft:\n      // oben und unten je eine Reihe ...\n      for (int x = -360; x <= 360; x = x + 48) {\n         Hindernis oben = new Hindernis();\n         oben.addCostume(\"stein\", \"assets/backgrounds/tilesets/tileset-dungeon.png\", 128, 48, 16, 16);\n         oben.setPosition(x, 192);\n         this.add(oben);\n\n         Hindernis unten = new Hindernis();\n         unten.addCostume(\"stein\", \"assets/backgrounds/tilesets/tileset-dungeon.png\", 128, 48, 16, 16);\n         unten.setPosition(x, -192);\n         this.add(unten);\n      }\n      // ... und links und rechts je eine Spalte.\n      for (int y = -144; y <= 144; y = y + 48) {\n         Hindernis links = new Hindernis();\n         links.addCostume(\"stein\", \"assets/backgrounds/tilesets/tileset-dungeon.png\", 128, 48, 16, 16);\n         links.setPosition(-360, y);\n         this.add(links);\n\n         Hindernis rechts = new Hindernis();\n         rechts.addCostume(\"stein\", \"assets/backgrounds/tilesets/tileset-dungeon.png\", 128, 48, 16, 16);\n         rechts.setPosition(360, y);\n         this.add(rechts);\n      }\n\n      Hindernis baum = new Hindernis();\n      baum.addCostume(\"baum\", \"assets/backgrounds/tilesets/tileset-nature.png\", 0, 0, 32, 32);\n      baum.setPosition(-120, 90);\n      this.add(baum);\n\n      Hindernis tanne = new Hindernis();\n      tanne.addCostume(\"tanne\", \"assets/backgrounds/tilesets/tileset-nature.png\", 32, 0, 32, 32);\n      tanne.setPosition(140, -40);\n      this.add(tanne);\n\n      Hindernis fels = new Hindernis();\n      fels.addCostume(\"fels\", \"assets/backgrounds/tilesets/tileset-nature.png\", 256, 128, 32, 32);\n      fels.setPosition(220, 110);\n      this.add(fels);\n\n      // Eine Reihe aus fünf Münzen am unteren Rand.\n      for (int x = -160; x <= 160; x = x + 80) {\n         Muenze m = new Muenze();\n         m.setPosition(x, -130);\n         this.add(m);\n         anzahlMuenzen = anzahlMuenzen + 1;\n      }\n\n      Muenze versteck = new Muenze();\n      versteck.setPosition(300, 140);\n      this.add(versteck);\n      anzahlMuenzen = anzahlMuenzen + 1;\n\n      anzeige = new Text(\"\", 0, 200, 700);\n      anzeige.setTextSize(20);\n      anzeige.setTextColor(255, 255, 255);\n      this.add(anzeige);\n\n      held = new Spieler(\"boy\");\n      held.setPosition(-280, 0);\n      this.add(held);\n   }\n\n   /// Wird jedes Mal ausgeführt, wenn der Spieler eine Münze einsammelt.\n   public void wennMuenzeEingesammelt() {\n      punkte = punkte + 1;\n   }\n\n   /// Wird immer wieder ausgeführt, etwa 60-mal in der Sekunde.\n   public void run() {\n      if (laeuft) {\n         zeit = zeit - 1.0 / 60;\n\n         if (punkte == anzahlMuenzen) {\n            laeuft = false;\n            held.setTempo(0);\n            anzeige.showText(\"Gewonnen! Noch \" + (int) zeit + \" Sekunden übrig.\");\n         } else if (zeit <= 0) {\n            laeuft = false;\n            held.setTempo(0);\n            anzeige.showText(\"Die Zeit ist um! \" + punkte + \" von \" + anzahlMuenzen + \" Münzen.\");\n         } else {\n            anzeige.showText(\"Münzen: \" + punkte + \" von \" + anzahlMuenzen + \"   Zeit: \" + (int) zeit);\n         }\n      }\n   }\n}\n"
    },
    {
      "name": "Main.java",
      "text": "/// Startet das Spiel.\nvoid main() {\n   // Pixelgrafik bleibt beim Vergrößern scharf.\n   Window.useTextureSampling(TextureSampling.POINT);\n   Window fenster = new Window(768, 432);\n   fenster.setStage(new Welt());\n}\n"
    },
    {
      "name": "Hindernis.java",
      "text": "/// Fertig für dich: eine Figur, durch die der Spieler nicht hindurchlaufen kann.\n/// Ein Hindernis ist ein Sprite wie jedes andere. Sein Kostüm gibst du ihm selbst.\npublic class Hindernis extends Sprite {\n\n   public Hindernis() {\n      // Die Bilder sind winzig. Dreifach vergrößert passen sie zum Spieler.\n      this.setSize(300);\n   }\n\n   /// Wie addCostume von Sprite. Zusätzlich hält nur die untere Hälfte des Bildes auf,\n   /// also der Stamm eines Baums oder der Fuß eines Felsens. Hinter dem Rest kann man vorbeigehen.\n   public void addCostume(String pName, String pBild, int pX, int pY, int pBreite, int pHoehe) {\n      super.addCostume(pName, pBild, pX, pY, pBreite, pHoehe);\n      this.setHitbox(0, pHoehe / 2.0, pBreite, pHoehe / 2.0, pBreite, pHoehe, 0, pHoehe);\n   }\n}\n"
    },
    {
      "name": "Muenze.java",
      "text": "/// Fertig für dich: eine Münze, die sich dreht, bis der Spieler sie einsammelt.\npublic class Muenze extends AnimatedSprite {\n\n   public Muenze() {\n      // Vier Bilder zu je 10 × 10 Pixeln nebeneinander.\n      this.addAnimation(\"drehen\", \"assets/items/treasure/coin2.png\", 4, 10, 10);\n      this.setAnimationInterval(150);\n      this.setSize(300);\n   }\n\n   public void run() {\n      this.playAnimation(\"drehen\");\n   }\n}\n"
    },
    {
      "name": "Spieler.java",
      "text": "/// Fertig für dich: die Figur, die du mit den Pfeiltasten steuerst.\n/// Sie bleibt an Hindernissen hängen und sammelt Münzen ein.\n/// Im Kapitel über Objektorientierung schaust du dir an, wie sie gebaut ist.\npublic class Spieler extends AnimatedSprite {\n\n   /// So viele Pixel geht der Spieler in jedem Bild.\n   private int tempo = 3;\n\n   /// Erzeugt einen Spieler. pFigur ist ein Ordner in assets/actor/character/, zum Beispiel \"boy\".\n   public Spieler(String pFigur) {\n      String bild = \"assets/actor/character/\" + pFigur + \"/sprite-sheet.png\";\n      // Im Bild steht jede Blickrichtung in einer eigenen Spalte,\n      // die vier Schritte untereinander.\n      this.addAnimation(\"unten\", bild, 4, 16, 16, 0, true);\n      this.addAnimation(\"oben\", bild, 4, 16, 16, 1, true);\n      this.addAnimation(\"links\", bild, 4, 16, 16, 2, true);\n      this.addAnimation(\"rechts\", bild, 4, 16, 16, 3, true);\n      this.setAnimationInterval(150);\n      this.setSize(250);\n      // Nur die Füße zählen: So kann die Figur vor einem Baum stehen, ohne an ihm hängen zu bleiben.\n      this.setHitbox(4, 10, 12, 10, 12, 16, 4, 16);\n      this.addSound(\"muenze\", \"assets/audio/sounds/bonus/coin.ogg\");\n   }\n\n   public void run() {\n      double altX = this.getX();\n      double altY = this.getY();\n\n      if (this.isKeyPressed(KeyCode.RIGHT)) {\n         this.changeX(tempo);\n         this.playAnimation(\"rechts\");\n      } else if (this.isKeyPressed(KeyCode.LEFT)) {\n         this.changeX(-tempo);\n         this.playAnimation(\"links\");\n      } else if (this.isKeyPressed(KeyCode.UP)) {\n         this.changeY(tempo);\n         this.playAnimation(\"oben\");\n      } else if (this.isKeyPressed(KeyCode.DOWN)) {\n         this.changeY(-tempo);\n         this.playAnimation(\"unten\");\n      }\n\n      // In ein Hindernis hineingelaufen? Dann zurück auf den alten Platz.\n      if (this.getTouchingSprite(Hindernis.class) != null) {\n         this.setPosition(altX, altY);\n      }\n\n      Muenze m = this.getTouchingSprite(Muenze.class);\n      if (m != null) {\n         m.remove();\n         this.playSound(\"muenze\");\n         Welt welt = (Welt) this.getStage();\n         welt.wennMuenzeEingesammelt();\n      }\n   }\n\n   /// Legt fest, wie viele Pixel der Spieler in jedem Bild geht. Mit 0 bleibt er stehen.\n   public void setTempo(int pTempo) {\n      tempo = pTempo;\n   }\n}\n"
    },
    {
      "name": "Spielwelt.java",
      "text": "/// Fertig für dich: die Wiese als Hintergrund und die Reihenfolge, in der gezeichnet wird.\npublic class Spielwelt extends Stage {\n\n   /// So viele Pixel ist eine Kachel auf der Bühne breit und hoch.\n   public static final int KACHEL = 48;\n\n   public Spielwelt() {\n      // Die Wiese ist ein einziges Bild, so groß wie die Bühne.\n      this.addBackdrop(\"wiese\", \"assets/backgrounds/wiese.png\");\n\n      // Wer weiter unten steht, ist näher am Betrachter: Er wird später gezeichnet\n      // und verdeckt, was hinter ihm steht. So läuft man hinter Bäumen vorbei.\n      this.getSorting().byY();\n   }\n}\n"
    }
  ]
}
