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 Python Setup
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. Hier findest du mehr Infos zu den Programmier-Konventionen.
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:
import os.path
# KORREKT:
path = os.path.join("myfolder", "myfile.txt")
# falsch 1:
path = "myfolder/myfile.txt")
# falsch 2:
path = "myfolder\\myfile.txt")
Für dein/euer PyGame-Projekt ist es Pflicht, dieses objektorientiert zu programmieren. Verwende dafür das Template unten. Theoretisch kann man das ganze Game in einem einzigen File programmieren. Gerade für grössere Projekte und wenn man zusammen am gleichen Code arbeitet, so lohnt es sich, das Projekt auf mehrere Files aufzuteilen. Wir verfolgen hier den Grundsatz: für jede Klasse ein eigenes File.
Template herunterladen
Template anzeigen
- main.py
from settings import Settings
from game import Game
import os
import sys
"""
MAIN FILE
- execute this file
- for VSC: template includes launch.json file which includes line '"program": "main.py",' -> always launch this file
"""
if __name__ == "__main__":
os.chdir(sys.path[0]) # changes current working directory to file directory
# define some settings
settings_default = Settings()
settings_slow = Settings(speed=1)
# create game object and play
game = Game(settings_default)
game.play()
- settings.py
class Settings:
"""
class containing all settings
remember: use CAPITAL letters for CONSTANTS (variables that don't change)
"""
def __init__(self,win_height=800,win_width=500,bg_color=(255,255,255),fps=30,speed=12):
self.NAME = "sloppy bird"
# WINDOWS SIZE
self.WIN_HEIGHT = win_height
self.WIN_WIDTH = win_width
# COLOR SETTINGS
self.BG_COLOR = bg_color
# FRAMERATE
self.FPS = fps # frames per second
self.TIME_DELAY = int(1000 / self.FPS) # calculate delay time between two frames
# GAME CONSTANTS
self.SPEED = speed
- game.py
import os
import pygame
import sys
from player import Player
from ball import Ball
class Game:
"""
Main GAME class
"""
def __init__(self,settings):
pygame.init()
pygame.font.init()
self.settings = settings
self.time_delay = self.settings.TIME_DELAY
size = (self.settings.WIN_WIDTH, self.settings.WIN_HEIGHT)
self.screen = pygame.display.set_mode(size) # create screen which will display everything
self.win = pygame.display.set_mode(size)
pygame.display.set_caption(self.settings.NAME) # Game title
def quit(self):
pygame.quit()
sys.exit(0)
def play(self):
# CREATE GAME OBJECTS
# PLAYER:
player = Player(os.path.join("data","battleship.png"),(150,550))
# OTHER OBJECTS:
"""
if you have multiple objects of the same class (e.g. enemies), use a SPRITE GROUP:
"""
balls = pygame.sprite.Group()
balls.add(Ball(os.path.join("data","ball_blue.png"),[100,200]))
balls.add(Ball(os.path.join("data","ball_black.png"),[200,400]))
balls.add(Ball(os.path.join("data","ball_green.png"),[300,600]))
# GAME PERMANENT LOOP
while True:
pygame.time.delay(self.settings.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 -= self.settings.SPEED
if keys[pygame.K_DOWN]:
player.rect.top += self.settings.SPEED
# and so on ...
# COLLISION DETECTION
"""
see manual for all types of collisions: https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.spritecollide
"""
for ball in balls: # use loop to iterate through sprite group easily
pass
# UPDATE ALL GAME OBJECTS
balls.update() # can update all members of a group with a single command
player.update()
# DRAW
self.screen.fill(self.settings.BG_COLOR) # draw empty screen
balls.draw(self.screen) # draw all group members
self.screen.blit(player.image, player.rect) # draw single object
# UPDATE DISPLAY
pygame.display.update()
pygame.quit()
- player.py
import pygame
import os
class Player(pygame.sprite.Sprite):
def __init__(self, img_path, xy_center):
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 = xy_center # set center coords of player
self.mask = pygame.mask.from_surface(self.image) # creates a mask, used for collision detection (see manual about pygame.sprite.collide_mask())
def update(self):
"""
- update function gets executed in every step
- determines motion of player
"""
pass
def collide(self,ball):
"""
player collides with ball, given as argument
this method updates velocities of BOTH player and ball
"""
pass
- ball.py
import pygame
import os
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):
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 = xy_center # 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())
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
Plan erstellen auf Papier:
Welche Klassen? Welche Attribute und Methoden?
Skizzen für Graphiken anfertigen
Neues GitHub Repo erstellen. Alle Gruppenmitglieder und Lehrperson einladen.
Template von oben hinein kopieren und als Startpunkt verwenden.
Programmieren: siehe Tipps unten
Tipps zum Arbeiten in Gruppen an Programmierprojekten: