Inhaltsverzeichnis

Ein erstes Arcade Programm

Nachdem man die Arcade-Bibliothek eingebunden hat (mittels import Arcade) kann man die Objekte und Funktionen verwenden, die uns dadurch zur Verfügung gestellt werden. Zentral dabei sind vor allem die folgenden Funktionen:

import arcade

# Fenster erstellen (Breite, Höhe, Titel)
arcade.open_window(600, 600, "Basic Game")

# Hintergrundfarbe
arcade.set_background_color(arcade.color.WHITE)

# Damit das Fenster gerendert und gezeichnet wird, muss man start_render aufrufen
arcade.start_render()

# Ein Smiley zeichnen
arcade.draw_circle_filled(300, 300, 200, arcade.color.YELLOW)
arcade.draw_circle_filled(370, 350, 20, arcade.color.BLACK)
arcade.draw_circle_filled(230, 350, 20, arcade.color.BLACK)
arcade.draw_arc_outline(300, 280, 120, 100, arcade.color.BLACK, 190, 350, 10)

# rendern beenden und anzeigen
arcade.finish_render()

# Nun wird der Game-Loop gestartet, da sonst das Fenster nur ganz kurz sichtbar ist
arcade.run()

Der klassische Game-Loop

Mit dem oben verwendeten Prinzip könnte man Grafiken in einem Fenster erstellen - dafür gibt es in Arcade auch etliche Funktionen (siehe https://api.arcade.academy/en/latest/api/drawing_primitives.html für die Zusammenstellung aller Zeichenfunktionen. Doch für ein echtes Spiel benötigen wir weitere Dinge:

Um diese Funktionalitäten zu erreichen, erstellt man eine neue Klasse (z.B, myGame), die von der Klasse Arcade.Window abgeleitet wird und daher all ihre Methoden und Eigenschaften erbt. Im Konstruktor dieser Klasse (init) wird mit super der Konstruktor der Elternklasse Arcade.Window aufgerufen, welche das Fenster erstellt.

In der neuen Klasse MyGame werden einige Standard-Methoden definiert, die für das Funktionieren des Spiels zentral sind:

Befehl Beispielbefehl/Erklärung
init Der Konstruktor, er wird aufgerufen, wenn ein Objekt erstellt wird. Hier sollte der Konstruktor der Elternklasse aufgerufen werden mit super()
setup setup ist sehr ähnlich wie der Konstruktor - hier werden die grundlegenden Dinge erledigt, wenn ein Spiel beginnt. Der Grund, warum man zum Konstruktor noch eine setup-Methode hinzufügt, ist, dass man z.B. nach dem Ende eines Spiels ein neues Spiel mit setup starten kann.
on_update on_update wird x Mal pro Sekunde aufgerufen (Frage: wie gross ist x und wie kann man dies ändern?). Hier kann man die Veränderung der Spielewelt programmieren (Positionen der Objekte ändern etc)
on_draw Jedes Mal, wenn die Welt neu berechnet wurde (on_update) wird das Spielfenster neu gezeichnet.

import arcade
  
class MyGame(arcade.Window):
 
    def __init__(self, width, height, title):
        # Konstruktor der Elternklasse aufrufen
        super().__init__(width, height, title)
        # Hintergrundfarbe setzen
        arcade.set_background_color(arcade.color.AMAZON)
 
    def setup(self):
        # die x-Koordinate speichern als Objektvariable
        self.xValue = 0
       
    def on_draw(self):
        # Alles löschen
        self.clear()
        # Alles neu zeichnen.
        arcade.draw_circle_filled(self.xValue, 350, 20, arcade.color.BLACK)
 
    def on_update(self, delta_time):
          # x-Wert vergrössern
        self.xValue = self.xValue + 5 
 
def main():
    # Das Objekt der Klasse MyGame erstellen
    window = MyGame(800, 600, "Simple Example")
    window.setup() # setup aufrufen
    arcade.run()  # Game-Loop starten

# Nur falls diese Datei direkt über Python aufgerufen wird, main() starten 
if __name__ == "__main__":
    main()

Events (Keyboard, Mouse) verarbeiten

Wenn der Spieler eine Aktion tätigt (z.B. W,A,S,D auf der Tastatur drückt), soll dies im Spiel einen Einfluss haben. Diese Events (z.B. Tastaturbefehle) kann man auch in der Klasse arcade.Window abfragen. Tipp: man kann innerhalb von on_key_press einfach print(key) schreiben, dann wird der Code der aktuell gedrückten Taste ausgegeben.

import arcade
  
class MyGame(arcade.Window):
 
    def __init__(self, width, height, title):
        # Konstruktor der Elternklasse aufrufen
        super().__init__(width, height, title)
        # Hintergrundfarbe setzen
        arcade.set_background_color(arcade.color.AMAZON)
 
    def setup(self):
        # die x-Koordinate speichern als Objektvariable
        self.xValue = 0
        self.xVel = 0
       
    def on_draw(self):
        # Alles löschen
        self.clear()
        # Alles neu zeichnen.
        arcade.draw_circle_filled(self.xValue, 350, 20, arcade.color.BLACK)
 
    def on_update(self, delta_time):
          # x-Wert vergrössern
        self.xValue = self.xValue + self.xVel
    
    def on_key_press(self, key, modifiers):
        # Wenn eine Taste gedrückt wird
        if key == arcade.key.RIGHT:
            self.xVel = 5
        elif key == arcade.key.LEFT:
            self.xVel = -5
            
    def on_key_release(self, key, modifiers):
        self.xVel = 0
 
def main():
    # Das Objekt der Klasse MyGame erstellen
    window = MyGame(800, 600, "Simple Example")
    window.setup() # setup aufrufen
    arcade.run()  # Game-Loop starten

# Nur falls diese Datei direkt über Python aufgerufen wird, main() starten 
if __name__ == "__main__":
    main()

Aufgabe

  • Verändere das Programm von oben, sodass man mit den Pfeiltasten den Kreis nach rechts, links, oben, unten bewegen kann.
  • Verändere das Programm von oben, sodass der Kreis an den Rändern des Fensters stehen bleibt.
  • Verändere das Programm von oben, sodass man die Bewegung des Kreises nicht abrupt ändern kann. Der Kreis soll quasi die Beschleunigung verändern, so dass man ihn schneller und langsamer machen kann.

Akteure (Spieler, Gegner etc. hinzufügen (Sprites und Spritelists)

Mit den Konzepten von oben könnte man ein ganzes Spiel programmieren. Doch Arcade stellt uns weitere Hilfsobjekte und Methoden zur Verfügung, die das Programmieren eines Spiels erleichtern sollen. Die Klasse arcade.Sprite ist dazu da, Akteure wie den Spieler oder Gegner, oder sonstige Objekte hinzuzufügen. Hat man viele solcher Sprites, kann man diese in eine arcade.Spritelist fügen. Haben die Sprites eine eigene update-Methode, so wird diese automatisch aufgerufen, wenn das Spiel „geupdated“ wird. Dies erleichtert die Programmierung extrem. Hat man viele Sprites in einer Spritelist, so werden diese automatisch alle „geupdated“, wenn die Spritelist „geupdated“ wird.

Sprites erstellt man, indem man eine Klasse von der Klasse arcade.Sprite ableitet.

Studiere dieses Programm, um zu sehen, wie Sprites und Spritelists funktionieren