Installiere PyGame. Achtung: Typischerweise funktioniert dieses nicht mit der aktuellsten Python Version. Stand Januar 2021 läuft es sicher mit Python 3.78. Benötigt man für verschiedene Projekte verschiedene Installationen und verschiedene Versionen von Python, so lohnt sich die Verwendung von Virtual Environments. Verwende pip um Module wie PyGame zu installieren.
Recherchiere, was Virtual Environments sind, und wie man mit diesen arbeitet. Erstelle dann ein neues für Pygame Projekte und installiere darin (mit pip) PyGame.
Quellen:
pygame_exercises
UpperCamelCase
Stil und Variablen im snake_case
Stil notiert werden. Studiere für weitere Infos den folgenden Convention Guide: https://www.fcodelabs.com/2018/12/03/Python-Coding-Standard/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:import os.path path = os.path.join("myfolder", "myfile.txt")
Programmiere ein Spiel, welches Ähnlichkeiten mit dem Spiel Billard hat. Es soll schlussendlich beinhalten:
Alles was du an Mathematik und Physik wissen musst, findest du hier: Vektoren, Kinematik & Python
Dir wird ein Template (siehe ZIP-File unten) zur Verfügung gestellt, welches dir als Grundlage dienen soll. Erstelle wie weiter oben erklärt ein GitHub Repo für diesen Auftrag und füge den Inhalt des ZIPs hinzu.
Verschaffe dir nun einen Überblick über den Code. Setze dazu einen Breakpoint ganz zu Beginn der play()
-Methode und gehe Schritt-für-Schritt durch den Code. Es ist wichtig, dass du verstehst, was in jedem Schritt passiert! Konsultiere Regelmässig das Manual https://www.pygame.org/docs/, um mehr über die verschiednen Features von PyGame zu lernen!
Gib dem Player eine Anfangsgeschwindigkeit. Implementiere die Kollisionen an den Wänden. Es soll noch keine Reibung vorkommen, d.h., die Geschwindigkeit muss konstant bleiben! Die Bewegung des Players ist also eine uniforme (gleichförmige) Bewegung in 2D.
Studiere zuerst die Theorie zur uniformen Bewegung und zu Vektoren mit Numpy
Mache eine Kopie der ersten Version des Spiels und benenne diese billard_v02.py
.
Implementiere Reibung. Ziehe dazu in jedem Schritt einen bestimmten, immer gleich bleibenden Wert vom Betrag der Geschwindigkeit ab.
File name: billard_03.py
(Mache dies für jede Version, wird dann nicht mehr explizit erwähnt.
Der Player soll nun in eine beliebige Richtung mit einer bestimmten Geschwindigkeit abgeschossen werden können. Überlege dir zuerst, wie du das machen möchtest und setze es dann um.
Füge weitere Bälle hinzu. Sämtliche Kollisionen sollen physikalisch korrekt sein. Studiere dazu die Seite Kollisionen und insbesondere das PDF dort.
Überlege die ein Spielsystem und setze es um.
Der Spielstand soll angezeigt angezeigt werden. Was das ist, hängt vom Spiel ab: Gesammelte Punkte, verstrichene Zeit, …
Verschönere nun dein Spiel. Es muss enthalten:
Programmiere das Spiel Autoscooter, welches wie folgt funktionieren soll:
Dir wird ein Template (siehe ZIP-File unten) zur Verfügung gestellt, welches dir als Grundlage dienen soll. Erstelle wie weiter oben erklärt ein GitHub Repo für diesen Auftrag und füge das Template hinzu.
Verschaffe dir nun einen Überblick über den Code. Setze dazu einen Breakpoint ganz zu Beginn der play()
-Methode und gehe Schritt-für-Schritt durch den Code. Es ist wichtig, dass du verstehst, was in jedem Schritt passiert! Konsultiere Regelmässig das Manual https://www.pygame.org/docs/, um mehr über die verschiednen Features von PyGame zu lernen!
import os import sys import pygame from PIL import Image, ImageDraw from pathlib import Path print(f"python executable: {sys.executable}") ### CONSTANTS ### # Convention: use capital letters for constants (= variables you leave unchanged) # Windows WIN_HEIGHT = 800 WIN_WIDTH = 500 # Define colors WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) BG_COLOR = WHITE # Framerate FPS = 30 TIME_DELAY = int(1000 / FPS) # Game Constants SPEED = 12 ### FUNCTIONS ### ### CLASSES ### class Player(pygame.sprite.Sprite): def __init__(self, img_path, xy_center, v, mass): super().__init__() # call __init__ of parent class (i.e. of pygame.sprite.Sprite) # ASSIGN CLASS ATTRIBUTES if not os.path.exists(img_path): raise Exception("THE FOLLOWING FILE DOES NOT EXIST: {0}".format(img_path)) self.image = pygame.image.load(str(img_path)) # load image self.rect = self.image.get_rect() # create rectangle containing ball image self.rect.center = (int(xy_center[0]),int(xy_center[1])) # set center coords of ball self.mask = pygame.mask.from_surface(self.image) # creates a mask, used for collision detection (see manual about pygame.sprite.collide_mask()) self.mass = mass # give sprite a mass -> realistic collisions def update(self): # in each step, this method is called if self.rect.left <= 0: self.rect.left = 0 elif self.rect.right >= WIN_WIDTH: self.rect.right = WIN_WIDTH if self.rect.top <= 0: self.rect.top = 0 elif self.rect.bottom >= WIN_HEIGHT: self.rect.bottom = WIN_HEIGHT def collide(self,ball): pass class Ball(pygame.sprite.Sprite): """ Class for balls, derive from pygame's sprite class -> makes your life easier since you can use e.g. the collision detection of the sprite class """ def __init__(self, img_path, xy_center, v, mass): super().__init__() # call __init__ of parent class (i.e. of pygame.sprite.Sprite) # ASSIGN CLASS ATTRIBUTES if not os.path.exists(img_path): # check if folder of image exists raise Exception("THE FOLLOWING FILE DOES NOT EXIST: {0}".format(img_path)) self.image = pygame.image.load(str(img_path)) # load image self.rect = self.image.get_rect() # create rectangle containing ball image self.rect.center = (int(xy_center[0]),int(xy_center[1])) # set center coords of ball self.mask = pygame.mask.from_surface(self.image) # creates a mask, used for collision detection (see manual about pygame.sprite.collide_mask()) self.mass = mass # is relevant for realistic collisions def update(self): """ - update function gets executed in every step - determines motion of ball """ pass def collide(self,ball): """ ball self collides with other ball, given as argument this method updates velocities of BOTH balls """ pass class Game: """ Main GAME class """ def __init__(self): pygame.init() pygame.font.init() self.time_delay = TIME_DELAY self.screen = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT)) # create screen which will display everything self.win = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT)) pygame.display.set_caption("Bouncing Balls") # Game title def quit(self): pygame.quit() sys.exit(0) def play(self): # CREATE PLAYER player = Player(os.path.join("data","ball_r=100_col=0_255_0.png"),[150,550],[0,0],1) # CREATE GAME GROUPS Balls = pygame.sprite.Group() # CREATE OBJECTS AND ASSIGN TO GROUPS balls_list = [ Ball(os.path.join("data","ball_r=100_col=0_0_255.png"),[100,200],[0,0],1), Ball(os.path.join("data","ball_r=100_col=0_0_255.png"),[200,400],[0,0],1) ] Balls.add(balls_list) # GAME PERMANENT LOOP while True: pygame.time.delay(TIME_DELAY) # KEY EVENTS for event in pygame.event.get(): # Exit app if click quit button if event.type == pygame.QUIT: self.quit() # Naviation of player keys = pygame.key.get_pressed() if keys[pygame.K_UP]: player.rect.top -= SPEED # and so on ... # COLLISION DETECTION # see manual for all types of collisions: https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.spritecollide # TODO: check for collisions between any two balls. If there is any, call the collision() method of the Ball class. for ball in balls_list: pass # UPDATE Balls.update() player.update() # DRAW self.screen.fill(BG_COLOR) # draw empty screen Balls.draw(self.screen) self.screen.blit(player.image, player.rect) pygame.display.update() pygame.quit() if __name__ == "__main__": Game().play()
Implementiere nun eine Steuerung für den Player.
Programmiere mit PyGame ein eigenes Game, welches folgende Eigenschaften haben muss: