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:17] – [Teil III: Konsolen-App] 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 401: | Zeile 309: | ||
1. Collisions deaktiviert | 1. Collisions deaktiviert | ||
1. damit einfach eine Art ' | 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 412: | Zeile 323: | ||
<code python> | <code python> | ||
+ | from asteroids_game_model import Game | ||
import sys | import sys | ||
import random | import random | ||
Zeile 501: | 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 ===== | ||