Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
| Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
| talit:microbit_asteroids_game_2023 [2023-05-23 22:14] – [Teil II: Mirco-Bit] sca | talit:microbit_asteroids_game_2023 [2024-05-06 09:07] (aktuell) – [Version 3] sca | ||
|---|---|---|---|
| Zeile 3: | Zeile 3: | ||
| ===== Programm 1M FS2023 Q2 ===== | ===== Programm 1M FS2023 Q2 ===== | ||
| - | ++++Programm| | ||
| - | === Lektion 4: 10.05.2023 === | ||
| - | |||
| - | * Rückmeldung HA: | ||
| - | * Erreichbarkeit: | ||
| - | * wird besser | ||
| - | * bitte mit aussagekräftiger Rückmeldung. Probleme oder Fehler? Beschreibe diese und nicht einfach "... dann wird mir eine Fehlermeldung bei Linie 30 angegeben." | ||
| - | * GitHub: NIE Files per Upload hochladen sondern über Git-Bash. Finde heraus wie das geht, frage TALIT-Go(e)tti! | ||
| - | |||
| - | * OOP: | ||
| - | * Grundidee | ||
| - | * Beispiele von SuS | ||
| - | * Live-Demo: Asteroiden-Regen | ||
| - | |||
| - | * HA: | ||
| - | * v05 korrigieren & erweitern | ||
| - | * beachte: Aufgabe wurde ergänzt: | ||
| - | * z.B. Klasse für Player | ||
| - | * **Abgabe 1:** bis kommenden Sonntag 14.5. (besser früher) | ||
| - | * dann warten auf Rückmeldung von LP | ||
| - | * **Abgabe 2:** Verbesserung (falls nötig bis So. 21.5. | ||
| - | * **Ziel: perfekte OOP Version bis zur nächsten Lektion** | ||
| - | |||
| - | **Code-Beispiele SuS:** | ||
| - | |||
| - | Wo ist das Problem? | ||
| - | <code python> | ||
| - | class Asteroid: | ||
| - | def __init__(self, | ||
| - | self.pos_x = pos_x | ||
| - | self.pos_y = pos_y | ||
| - | self.brightness = brightness | ||
| - | self.speed = speed | ||
| - | self.last_update = last_update | ||
| - | |||
| - | def spawn(self): | ||
| - | if len(Asteroids) < MAX_ASTEROIDS: | ||
| - | pos_x = random.randint(0, | ||
| - | pos_y = 0 | ||
| - | brightness = ASTEROID_BRIGHTNESS | ||
| - | speed = random.randint(50, | ||
| - | last_update = time.ticks_ms() | ||
| - | asteroid = Asteroid(pos_x, | ||
| - | Asteroids.append(asteroid) | ||
| - | return asteroid | ||
| - | return None | ||
| - | </ | ||
| - | |||
| - | === Lektion 3: 03.05.2023 === | ||
| - | |||
| - | * Rückmeldung HA: | ||
| - | * In Code unten keine Werte (ausser z.B. 0), sondern KONSTANTEN | ||
| - | * Keep it short & simple: | ||
| - | * anstelle `if < | ||
| - | * vermeide zu viele Einrückungen -> schwierig zu lesen | ||
| - | * Logische Abfolge in Game-Loop: Halte dich an Vorgaben in Template: | ||
| - | * Template: Update Asteroid & Player / Collision / Display / Short Sleep | ||
| - | * Bsp. nicht optimal: Display / Update Asteroid & Player / Collision / Short sleep | ||
| - | * Neustart bei Game Over: Mehrere Möglichkeiten: | ||
| - | * Nach Game Over in neues `while True`, mit break ausbrechen (Lösung v04a). Problem: Wie auf Starteinstellungen zurücksetzen, | ||
| - | * Alternative: | ||
| - | * Besprechung: | ||
| - | * Theorie Input und Aufgaben (keine Zeit mehr für Aufgaben) zu [[talit: | ||
| - | * Version 5 programmieren | ||
| - | * **HA:** | ||
| - | * v05 fertig und abgeben bis So. | ||
| - | * optional aber sehr empfohlen: [[talit: | ||
| - | |||
| - | |||
| - | === Lektion 2: 26.04.2023 === | ||
| - | |||
| - | * **Rückmeldung Abgaben** von HA: | ||
| - | * waren nicht gut im Allgemeinen, | ||
| - | * Lektion verpasst? SELBSTÄNDIG nacharbeiten, | ||
| - | * z.T. HEX-File oder File ohne Endung anstelle PY-File hochgeladen. Python-Files immer von Form `my_file.py` | ||
| - | * vor Abgabe **überprüfen**, | ||
| - | * z.T. (fast) identische Abgaben. Warum??? | ||
| - | * **Nachricht** an LP per Teams mit folgender Info: | ||
| - | * **Link** zum File (jedes Mal aufs Neue, damit LP nicht lange suchen muss) | ||
| - | * **Rückmeldung: | ||
| - | * **Rückmeldungen Code:** | ||
| - | * [[talit: | ||
| - | * falls `game_over` bool (True oder False), schreibe `if game_over` anstelle `if game_over == True` | ||
| - | * Kommentare: Überschriften, | ||
| - | * Strukturierung Code (siehe Template zu nächster Code-Version) | ||
| - | * Trenne Logik von Anzeige (mehr dazu im Auftrag zu v03) | ||
| - | * Verwende **kein sleep()** für Bewegung der Asteroiden (beeinflusst auch Player) sondern `time.ticks_ms()`\\ \\ | ||
| - | * **Auftrag Lektion:** | ||
| - | * **Version 3** (gleiches Game aber sauber strukturiert) | ||
| - | * Lösung muss mit **LP besprochen** werden | ||
| - | * **HA 1:** Studiere [[talit: | ||
| - | * **HA 2: Version 4** | ||
| - | * Abgabe bis SA-Abend | ||
| - | * Halte dich an Abgaberegeln (gelten immer!): | ||
| - | * Nachricht an sca per Teams mit: | ||
| - | * **Link** zum File (jedes Mal aufs Neue, damit LP nicht lange suchen muss) | ||
| - | * **Rückmeldung: | ||
| - | |||
| - | |||
| - | |||
| - | === Lektion 1: 19.04.2023 === | ||
| - | |||
| - | * **Version 1** (Challenge, Asteroids v01) | ||
| - | * Besprechung: | ||
| - | * Auftrag 2 beginnen | ||
| - | * **Hausaufgabe: | ||
| - | * Bis Sonntagabend **Version 2** fertig ... | ||
| - | * auf GitHub (geteilt mit anschae, gehe auf GitHub und stelle sicher, dass alles geklappt hat) ... | ||
| - | * und Nachricht per Teams an sca mit: | ||
| - | * Link zu GitHub Repo | ||
| - | * kurze Nachricht: Was funktioniert? | ||
| - | |||
| - | ++++ | ||
| ===== Version 1: Challenge ===== | ===== Version 1: Challenge ===== | ||
| Zeile 161: | Zeile 48: | ||
| * Speichere den Zeitpunkt zu dem der Asteroid zuletzt bewegt wurde in einer Variablen. | * Speichere den Zeitpunkt zu dem der Asteroid zuletzt bewegt wurde in einer Variablen. | ||
| * Überprüfe in jedem Durchlauf, ob seit der letzten Bewegung genügend Zeit (z.B. 500ms) vergangen sind. Falls ja: Bewege Asteroid. | * Überprüfe in jedem Durchlauf, ob seit der letzten Bewegung genügend Zeit (z.B. 500ms) vergangen sind. Falls ja: Bewege Asteroid. | ||
| - | * kurzes Delay wie `sleep(20)` verhindert nervöses | + | * kurzes Delay wie `sleep(20)` verhindert nervöses |
| * **Programmierstil: | * **Programmierstil: | ||
| * Verwende sinnvolle, aussagekräftige Variablennamen, | * Verwende sinnvolle, aussagekräftige Variablennamen, | ||
| Zeile 189: | Zeile 76: | ||
| # CONSTANT | # CONSTANT | ||
| - | """ | + | """ |
| # VARIABLES | # VARIABLES | ||
| - | """ | + | """ |
| while True: | while True: | ||
| Zeile 281: | Zeile 168: | ||
| ===== Version Final ===== | ===== Version Final ===== | ||
| + | |||
| + | **Slides:** {{ : | ||
| Nun geht es in die finale Phase! Ziel ist, zuerst ein komplett abstraktes **Modell** des Games zu erstellen. Dieses soll dann genutzt werden, um verschiedene Versionen des Spiels zu erstellen: | Nun geht es in die finale Phase! Ziel ist, zuerst ein komplett abstraktes **Modell** des Games zu erstellen. Dieses soll dann genutzt werden, um verschiedene Versionen des Spiels zu erstellen: | ||
| Zeile 287: | Zeile 176: | ||
| 1. Micro-Bit | 1. Micro-Bit | ||
| 1. Desktop-App mit PyQt5 | 1. Desktop-App mit PyQt5 | ||
| + | |||
| + | Lasse (zumindest für den Anfang) allen Schnick-Schnack weg: kein Score, kein Restart, ... einfach nur 1x das Game spielen bis zu einer Collision | ||
| + | |||
| + | In deinem Repo sollst du dann (zusätzlich zu den bisherigen Files) vier neue Files haben: | ||
| + | |||
| + | * `asteroids_game_model.py`: | ||
| + | * `asteroids_game_microbit.py`: | ||
| + | * `asteroids_game_console.py`: | ||
| + | * `asteroids_game_pyqt.py`: | ||
| === Teil I: Modell === | === Teil I: Modell === | ||
| Zeile 293: | Zeile 191: | ||
| 1. Dieses Soll die bisherigen Klassen `Asteroid` und `Player` beinhalten. | 1. Dieses Soll die bisherigen Klassen `Asteroid` und `Player` beinhalten. | ||
| 1. Erstelle weiter eine Klasse `Game`, die das gesamte Game beinhaltet. Halte dich dabei an die Vorgaben im **Template** unten. | 1. Erstelle weiter eine Klasse `Game`, die das gesamte Game beinhaltet. Halte dich dabei an die Vorgaben im **Template** unten. | ||
| - | 1. **Entferne alles**, was **nichts mit dem Modell** zu tun hat. Das ganze Dokument darf also keine `print()`, `display...` usw. enthalten. Achtung: Zeitabfragen funktionieren auf dem Computer anders als auf dem Mircobit. Verwende deshalb die Funktion `get_time_in_ms()` im Template. | + | 1. **Entferne alles**, was **nichts mit dem Modell** zu tun hat. |
| + | 1. Das ganze Dokument darf also keine `print()`, `display...` usw. enthalten. | ||
| + | 1. Auch sollen die Klassen keine Attribute wie `self.brightness` haben, da diese zur View gehört: Stellt man Asteroiden in einer Desktop-App dar, haben sie vielleicht eine Farbe oder ein Bild anstelle einer brightness. | ||
| + | 1. Achtung: Zeitabfragen funktionieren auf dem Computer anders als auf dem Mircobit. Verwende deshalb die Funktion `get_time_in_ms()` im Template. | ||
| ++++Template| | ++++Template| | ||
| Zeile 308: | Zeile 209: | ||
| """ | """ | ||
| if sys.platform == ' | if sys.platform == ' | ||
| - | return time.ticks_ms() | + | |
| - | return time.time()*1000 | + | |
| + | except Exception as e: | ||
| + | print(" | ||
| + | | ||
| + | try: | ||
| + | | ||
| + | except Exception as e: | ||
| + | print(" | ||
| class Player: | class Player: | ||
| Zeile 362: | Zeile 270: | ||
| ++++ | ++++ | ||
| - | === Teil II: Mirco-Bit === | + | === Teil II: Micro-Bit === |
| 1. Erstelle im Online-Editor ein neues File (heisst `main.py`). | 1. Erstelle im Online-Editor ein neues File (heisst `main.py`). | ||
| Zeile 395: | Zeile 303: | ||
| 1. Erstelle ein neues File (im gleichen Ordner) mit Namen `asteroids_game_console.py`. | 1. Erstelle ein neues File (im gleichen Ordner) mit Namen `asteroids_game_console.py`. | ||
| - | 1. Importiere in diesem deine Game-Klasse (siehe Template unten) ... | + | 1. Importiere in diesem deine Game-Klasse (wie in Mirobit-Version) ... |
| - | 1. ... und implementiere | + | 1. ... und implementiere |
| + | 1. Achtung: Keyevents und damit die Player-Navigation kann in der Konsole problematisch sein (zumindest auf Mac). Es ist deshalb auch i.O., wenn man hier: | ||
| + | 1. den Player nicht anzeigt | ||
| + | 1. Collisions deaktiviert | ||
| + | 1. damit einfach eine Art ' | ||
| === Teil IV: Desktop-App === | === Teil IV: Desktop-App === | ||
| + | |||
| + | 1. Erstelle ein neues File (im gleichen Ordner) mit Namen `asteroids_game_pyqt.py`. | ||
| + | 1. Studiere das Template unten, führe es aus und verstehe die wichtigsten Schritte (nicht alle Details) zu verstehen. | ||
| + | 1. Importiere wieder deine Game-Klasse ... | ||
| + | 1. ... und implementiere das Spiel. | ||
| ++++PyQt5 Template| | ++++PyQt5 Template| | ||
| Zeile 405: | Zeile 323: | ||
| <code python> | <code python> | ||
| + | from asteroids_game_model import Game | ||
| import sys | import sys | ||
| import random | import random | ||
| Zeile 494: | Zeile 413: | ||
| ++++ | ++++ | ||
| + | === Teil V (falls Zeit / für Schnelle): Pimp my Desktop-App === | ||
| + | |||
| + | Wandle deine Desktop-App-Version in ein richtig cooles Game: | ||
| + | |||
| + | * Bilder für Asteroiden und Player (auch versch. Asteroiden-Bilder möglich) | ||
| + | * Explosion-Bild bei Collision. | ||
| + | * Schnick-Schnack wieder einbauen: | ||
| + | * Restart | ||
| + | * Score | ||
| + | * ... | ||
| + | * Asteroiden abschiessen können | ||
| + | * ... | ||
| + | |||
| + | ++++Tipps| | ||
| + | |||
| + | **Bilder Laden:** | ||
| + | Es bietet sich an, Bilder in Unterordnern abzulegen. Lädt man das Bild in Python, muss der relative Pfad (in Bezug auf Location von Python-File) angegeben werden. Da Pfade auf versch. Systemen (z.B. Windows und Mac) anders angegeben werden, muss man die `os.path.join(...)` Funktion verwenden. | ||
| + | |||
| + | Beispiel: Bild `asteroid.png` ist im Unterordner `images`. Gebe Pfad dann wie folgt an: | ||
| + | <code python> | ||
| + | import os | ||
| + | ... | ||
| + | |||
| + | PATH_IMG_ASTEROID = os.path.join(' | ||
| + | </ | ||
| + | |||
| + | **Bild in Cell anzeigen:** | ||
| + | |||
| + | <code python> | ||
| + | ... | ||
| + | pixmap = QPixmap(PATH_IMG_ASTEROID) | ||
| + | cell.setPixmap(pixmap.scaled(cell.size(), | ||
| + | </ | ||
| + | |||
| + | ++++ | ||
| ===== Lösungen ===== | ===== Lösungen ===== | ||