Seite anzeigenÄltere VersionenLinks hierherCopy this pageFold/unfold allNach oben Diese Seite ist nicht editierbar. Du kannst den Quelltext sehen, jedoch nicht verändern. Kontaktiere den Administrator, wenn du glaubst, dass hier ein Fehler vorliegt. ====== - PyGame 2022 ====== ===== - Setup ===== ==== PyGame installieren ==== Installiere PyGame. Achtung: In der Vergangenheit habe ich die Erfahrung gemacht, dass PyGame manchmal nicht mit der neusten Versionen von Python läuft. Die neuste Version, mit der ich es getestet habe, ist Python 3.9.0, wahrscheinlich läuft es aber auch mit neueren Versionen. Es ist aber kein Problem, mehrere Python-Installationen parallel zu haben. Siehe dazu die Seite [[talit:python_setup|Python Setup]] ==== PyGame Links ==== **Offizielle Dokumentation:** https://www.pygame.org/docs/ ==== Git & GitHub ==== Siehe dazu die Seite [[talit:git_github|Git & GitHub]] ALLE Übungen und Aufträge, die du hier erledigst, werden mit Git verwaltet und auf GitHub gestellt werden. Die Repos werden mit der Lehrperson (Andreas Schärer: anschae) geteilt. Commit und pushe immer, nachdem du an einer Übung gearbeitet hast. Mache dies //unaufgefordert//! ==== Konventionen ==== Für unterschiedliche Programmiersprachen gibt es unterschiedliche Konventionen dazu, wie man Variablen, Klassen usw. benennt. Zum Beispiel sollten Klassen im `UpperCamelCase` Stil und Funktionen & Variablen im `snake_case` Stil notiert werden. [[talit:python_setup#programmier-konventionen|Hier findest du mehr Infos zu den Programmier-Konventionen.]] ==== Pfade in Python ==== Pfade von Ordner und Dokumente werden in Windows (`myfolder\\myfile.txt`) anders angegeben als in MacOS (`myfolder/myfile.txt`). Damit dein Code auf sämtlichen Plattformen funktioniert, musst du also solche Pfadangaben vermeiden. Stattdessen sollst du das os Modul verwenden: <code python> import os.path # KORREKT: path = os.path.join("myfolder", "myfile.txt") # falsch 1: path = "myfolder/myfile.txt") # falsch 2: path = "myfolder\\myfile.txt") </code> ===== - Projekt 1: Endless Runner I ===== ==== Ziele ==== * **Grundbausteine eines Games** verstehen * **PyGame** kennenlernen * Einfache **Physik (Gravitation)** implementieren ==== Auftrag in Kürze ==== Ziel ist es, mit PyGame ein eigenes Endless Runner Game zu programmieren. Bekannte Spiele in diesem Stil sind: * Dino Game von Google (https://trex-runner.com) * Flappy Bird (https://flappybird.io) Solche Spiele sind ziemlich einfach, können aber sehr fesselnd sein. Zum Beispiel wurde Flappy Bird ursprünglich für iOS und Android entwickelt und war sehr erfolgreich. Der Entwickler hat sich 2014 dafür entschieden, das Spiel wieder aus den App-Stores zu entfernen, da es süchtig mache, was seiner eigentlichen Absicht, Flappy Bird zu einem Gelegenheitsspiel zu machen, entgegenstünde. Das Game wird in zwei Versionen entwickelt: * Version I: Erste spielbare Version * Version II: Verbesserte Programmierung im Vergl. zu Version I, mit OOP. Plus zusätzliche Features ==== Abgabe ==== * **Deadline: 22.04.2022, @23.59** mit **Nachricht** and Lehrperson über Teams * Auftrag bis dann komplett und eigenständig erledigt * Aktuellste Version auf GitHub gepushed * Es steht genügend Zeit für Auftrag zur Verfügung, es wird deshalb kein Aufschub gewährt. === Teil 1: Setup === **Ziele:** GitHub-Repo einrichten, Template zum Laufen bringen, Plan für Game machen * Erstelle ein GitHub Repo `pygame_endless_runner`. Klone das Repo auf deinen Computer und arbeite für dieses Projekt in diesem Repo. * Lade das Template und das Bild in dein Repo. Ziel: Richte alles so ein, dass das Programm ausführbar ist. * Überlege dir, was für ein Endless Runner Game du programmieren möchtest: Dino-Style, Flappy-Bird-Style, ...? **Daten für Game:** * {{:talit:town_bg_2x_600.png?linkonly|}} * ++++Template| <code python endless_runner_i.py> import pygame import sys import os # Change current working directory to file location. Solves problem with relative path of images os.chdir(sys.path[0]) # initialize pygame s.t. is ready to use pygame.init() # GAME CONSTANTS WIDTH = 1000 HEIGHT = 600 # create display you're going to see when playing the game, determine windows size screen = pygame.display.set_mode((WIDTH,HEIGHT)) # label windows, typically game name pygame.display.set_caption("My Game") clock = pygame.time.Clock() # CREATE SPRITES, LOAD IMAGES, TEXT... # CREATE PLAYER () player_surface = pygame.Surface((80,150)) player_surface.fill('blue') player_rect = player_surface.get_rect(bottomleft = (20,500)) # load image for background, convert png/jpg to something pygame can deal better with (use .convert() or .convert_alpha() for non-rectangular images) background_surface = pygame.image.load(os.path.join('data','town_bg_2x_600.png')).convert() background_rect = background_surface.get_rect(topleft = (0,0)) # font and text my_font = pygame.font.Font(None,50) # set font type and size, use other fonts by adding respective file in folder and give reference here text = my_font.render('',False,'red') # 2nd argument is anti-aliasing, set False for pixel art # permanent game loop while True: # Deal with key events for event in pygame.event.get(): # Exit app if click quit button if event.type == pygame.QUIT: pygame.quit() sys.exit() # Naviation of player keys = pygame.key.get_pressed() if keys[pygame.K_SPACE]: pass # DISPLAY screen.blit(background_surface,background_rect) screen.blit(text,(400,50)) screen.blit(player_surface,player_rect) # COLLISION DETECTION # Update everything pygame.display.update() # Set maximum frame rate, typically to 60(fps) -> have at most 60fps clock.tick(60) </code> ++++ === Teil 2: Background === **Ziele:** Hintergrund bewegen * Das Hintergrundbild soll mit konstanter Geschwindigkeit am Player vorbei ziehen. * Implementiere dies für das vorgegebene Bild oder suche/erstelle dir selbst eins. Tipp: Am einfachsten machst du dir das Leben, wenn das Bild mind. doppelt so breit ist, wie der Screen des Games. Du kannst ein schmaleres Bild auch mit Photoshop verbreitern, in dem du es nebeneinander duplizierst, verdreifachen, ... === Teil 3: Jump === **Ziele:** Bewegung des Spielers physikalisch realistisch implementieren * Implementiere die Bewegung des Spielers. * In einem Endless-Runner-Game ist diese nur vertikal (y-Richtung). * Hängt vom Game-Typ (z.B. Dino-Style oder Flappy-Bird-Style) ab. * Muss physikalisch korrekt sein, Gravitation muss also realistisch umgesetzt werden (siehe unten). Achte bei Dino-Style Games darauf, dass ein Jump nur möglich ist, wenn der Player auf dem Boden steht. Diese Regel kann in weiteren Versionen gebrochen - wenn es //bewusst// gemacht wird! ++++Theorie zu Jumps| Die //vertikale// Bewegung ist eine **gleichförmige Beschleunigung**, gegeben durch die Formeln: $$a = -g = -9.81\text{m}/\text{s}^2 = \text{konst}$$ $$v(t) = v_0 + a t = v_0 - g t$$ $$s(t) = s_0 + v_0 t + \frac12 a t^2 = s_0 + v_0 t - \frac12 g t^2$$ Die Physik im Game soll realistisch wirken, d.h. die Bewegung soll mithilfe dieser Formeln implementiert werden, wobei die gewählten Werte z.B. für die Gravitationsbeschleunigung $g$ beliebig gewählt werden können (nicht $9.81\text{m}/\text{s}^2$). In einem Game wird ein Frame nach dem anderen angezeigt. Sagen wir, der Player fliege gerade durch die Luft (ist also nicht gerade beim Absprung) und habe zu einem gewissen Zeitpunkt die $y-$Geschwindigkeit $v$ und $y-$Position $s$. Wir können nun mithilfe der obigen Formeln die Position und Geschwindigkeit für den nächsten Frame bestimmen: $$s \:+\!\!= v \Delta t + \frac12 a (\Delta t)^2$$ $$v \:+\!\!= a \Delta t$$ Dabei ist $\Delta t$ die Zeit zwischen zwei Frames. Wir können festlegen, dass diese Zeit einfach $1$ ist - Einheiten werden hier höflich ignoriert (don't tell your physics teacher!). Damit vereinfachen sich unsere Formeln zu: $$s \:+\!\!= v + \frac12 a$$ $$v \:+\!\!= a$$ **Achtung Vorzeichen**: Beachte, dass in PyGame die $y-$Richtung in die gegengesetzte Richtung zeigt wie üblicherweise in der Mathe und Physik. Diese Formeln geben dir einen realistisch wirkenden Jump. Manchmal möchte man dies aber nicht, z.B. ist im Mario-Game die Gravitation auf dem Weg nach unten stärker als auf dem Weg nach oben. Der folgende Talk diskutiert dies und andere Aspekte von Jumps und ist durchaus sehenswert: https://www.youtube.com/watch?v=hG9SzQxaCm8 ++++ === Teil 4: Gegner I === **Ziele:** Einen Gegner mit Bewegung und Collision Detection * Erzeuge einen Gegner, der am anderen Ende des Bildschirms den Screen betritt und mit einer höheren Geschwindigkeit als der Hintergrund auf dich zu kommt. * Berührt der Gegner den Player, soll GameOver sein. Dazu braucht es eine Collision Detection. //Tipp:// PyGame Manual! === Teil 5: Gegner II === **Ziele:** Mehrere (verschiedene) Gegner, werden random erzeugt * Implementiere zuerst einen einzigen Typ Gegner, der immer wieder gespawned wird. * Dies soll zufällig passieren, zwei Gegner sollen aber nicht zu nahe aufeinander folgen können. * Der Code soll so geschrieben werden, dass problemlos eine beliebige Anzahl Gegner erzeugt werden kann. * //Tipp:// Mache dir Gedanken, wie du die Gegner speichern möchtest. `enemy1 = ...., enemy2 = ..., enemy3 = ...` ist keine gute Idee, da zu unflexibel und zu viel Coderepetition. * Implementiere nun mehrere (mind. 3) Arten von Gegner. Schreibe deinen Code so, dass dieser problemlos um weitere Gegner erweitert werden kann. === Teil 6: Levels === **Ziele:** Versch. Levels/Schwierigkeitsgrade implementieren * Das Spiel soll mit der Zeit schwieriger werden * schnellere und mehr Gegner * Auch möglich: neue, schwierigere Typen von Gegnern (z.B. grösser) kommen erst in späteren Levels hinzu === Teil 7: Bilder für Sprites === Ersetze die Rechtecke des Players und der Gegner durch passende Bilder. === Teil 8: Game-Balancing & Game-Testing === **Ziel:** Game testen, Feinschliff verpassen, Parameter so einstellen, dass Spass macht aber auch Herausforderung ist Unter **Game-Balancing** versteht man die Gestaltung des Spiels, so dass das Spielen des Spiels Spass macht - auch über einen längeren Zeitraum. Ist das Spiel zu einfach, wird man schnell gelangweilt und stellt ab. Ist es gleich von Beginn an zu schwierig, so wird man frustriert und stellt auch ab. Es ist also wichtig, eine gute Balance zwischen 'gut spielbar' und 'doch noch eine Herausforderung' zu finden. Weiter sollte das Spiel eine gewisse Abwechslung bieten, so dass man das Spiel auch länger spielen möchte. Das Spiel sollte sich also verändern: Verschiedene Levels, Gegner, ... und v.a. sollte der Schwierigkeitsgrad mit der Zeit etwas anziehen. Für ein Endless-Runner-Game ist besonders der letzte Punkt relevant. **Game-Testing:** Wie der Schwierigkeitsgrad eines Spiels bewertet wird, hängt immer von der befragten Person ab: Ist es eine Profi-Gamerin oder eine Person, die unerfahren ist mit Games? Deshalb sollte man ein Spiel **von verschiedenen Personen** mit unterschiedlich viel Game-Erfahrung testen lassen. * **Game-Testing:** Lasse verschiedene Personen das Spiel spielen (Kolleg:innen, Gamer, Papa, Oma, ...). Hohle Feedback ein: zu schwierig/einfach? Abwechslungsreich genug? Hat es Spass gemacht, das Spiel über einen längeren Zeitpunkt zu spielen? * **Game-Balancing:** Setze das von der Game-Testing-Phase eingeholte Feedback um, so dass dein Spiel möglichst balanciert ist. talit/python_pygame_2022.txt Zuletzt geändert: 2022-07-10 10:59von sca