import pygame import sys from random import * BREITE = 60 HOEHE = 30 # EINHEIT gibt die Seitenlänge eines Quadrats in Pixel an. EINHEIT = 25 # Dictionary: Speichert die Farben für die Zustände eines Feldes: farbe = { 'leer' : [0, 0, 0], 'raster' : [150, 155, 165], 'rand' : [0, 0, 255], 'schlange' : [255, 0, 0], 'apfel' : [0, 255, 0], 'schrift' : [255, 255, 255], } def zeichne_quadrat_ohne_update(x, y, zeichenfarbe): rechteck = pygame.Rect(x*EINHEIT, HOEHE*EINHEIT-y*EINHEIT-EINHEIT, EINHEIT, EINHEIT) pygame.draw.rect(surface=fenster, color=farbe['raster'], rect=rechteck) rechteck = pygame.Rect(x*EINHEIT, HOEHE*EINHEIT-y*EINHEIT-EINHEIT, EINHEIT-1, EINHEIT-1) pygame.draw.rect(surface=fenster, color=zeichenfarbe, rect=rechteck) def zeichne_quadrat_mit_update(x, y, zeichenfarbe): rechteck = pygame.Rect(x*EINHEIT, HOEHE*EINHEIT-y*EINHEIT-EINHEIT, EINHEIT, EINHEIT) q1 = pygame.draw.rect(surface=fenster, color=farbe['raster'], rect=rechteck) rechteck = pygame.Rect(x*EINHEIT, HOEHE*EINHEIT-y*EINHEIT-EINHEIT, EINHEIT-1, EINHEIT-1) q2 = pygame.draw.rect(surface=fenster, color=zeichenfarbe, rect=rechteck) pygame.display.update([q1, q2]) def schreibe(x, y, text, groesse=1): # schrift = pygame.font.Font('freesansbold.ttf', round(groesse * faktor)) # Mit pygame.font.SysFont kann man wohl jede der Fonts aus der Liste # pygame.font.get_fonts() # verwenden. schrift = pygame.font.SysFont('freemono', round(groesse * EINHEIT)) formatierter_text = schrift.render(text, True, farbe['schrift'], farbe['leer']) # formatierter_text.set_alpha(127) rechteck = formatierter_text.get_rect() rechteck.center = [x*EINHEIT, HOEHE*EINHEIT-y*EINHEIT-EINHEIT] # rechteck.bottomleft = fenster.blit(formatierter_text, rechteck) pygame.display.update() def feld(x, y): if x == 0 or x == BREITE-1 or y == 0 or y == HOEHE-1: return 'rand' if x==apfel[0] and y == apfel[1]: return 'apfel' for a, b in schlange: if x==a and y == b: return 'schlange' return 'leer' def neue_schlange(): while True: x = randrange(BREITE//3, 2*BREITE//3) y = randrange(HOEHE//3, 2*HOEHE//3) if feld(x, y) == 'leer': schlange = [[x, y] for _ in range(laenge)] break richtung = [[1, 0], [-1, 0], [0, 1], [0, -1]][randrange(4)] return schlange, richtung def neuer_apfel(): while True: x = randrange(1, BREITE-1) y = randrange(1, HOEHE-1) if feld(x, y) == 'leer': return [x, y] pygame.init() pygame.display.set_caption("Snake") uhr = pygame.time.Clock() fenster = pygame.display.set_mode((BREITE*EINHEIT, HOEHE*EINHEIT+3*EINHEIT)) print(""" Snake Steuerung mit Pfeiltasten. Für jeden gefressenen Apfel gibt es einen Punkt, die Schlange verlängert sich um ein Feld und die Frame rate wächst um 1. Du hast 5 Leben. Fenster schliessen per Maus oder per Taste 'q' """) # Initialisierung for x in range(BREITE): for y in range(HOEHE): zeichne_quadrat_ohne_update(x, y, farbe['leer']) for x in range(BREITE): zeichne_quadrat_ohne_update(x, 0, farbe['rand']) zeichne_quadrat_ohne_update(x, HOEHE-1, farbe['rand']) for y in range(HOEHE): zeichne_quadrat_ohne_update(0, y, farbe['rand']) zeichne_quadrat_ohne_update(BREITE-1, y, farbe['rand']) # Dummy-Definitionen schlange = [] apfel = [0, 0] laenge = 5 schlange, richtung = neue_schlange() for x, y in schlange: zeichne_quadrat_ohne_update(x, y, farbe['schlange']) apfel = neuer_apfel() zeichne_quadrat_ohne_update(apfel[0], apfel[1], farbe['apfel']) pygame.display.flip() punkte = 0 leben = 5 frames_pro_sekunde = 25 spielende = False # wird True, sobald der Benutzer das Fenster schliesst oder die Taste 'q' drückt. while True: for ereignis in pygame.event.get(): if ereignis.type == pygame.QUIT: print('Fenster schliessen.') spielende = True elif ereignis.type == pygame.KEYDOWN: if ereignis.key == pygame.K_q: print('Taste "q" gedrückt.') spielende = True elif ereignis.key == pygame.K_UP: print('Pfeiltaste UP gedrückt') richtung = [0, 1] elif ereignis.key == pygame.K_DOWN: print('Pfeiltaste DOWN gedrückt') richtung = [0, -1] if ereignis.key == pygame.K_RIGHT: print('Pfeiltaste RIGHT gedrückt') richtung = [1, 0] if ereignis.key == pygame.K_LEFT: print('Pfeiltaste LEFT gedrückt') richtung = [-1, 0] x, y = schlange[0] xneu, yneu = x + richtung[0], y + richtung[1] feldtyp = feld(xneu, yneu) if feldtyp in {'rand', 'schlange'}: print(f"Spielende, Crash mit {feldtyp}") if leben == 0: spielende = True else: leben -= 1 print(f'{punkte=}, {leben=}') for x, y in schlange: zeichne_quadrat_mit_update(x, y, farbe['leer']) schlange, richtung = neue_schlange() elif feldtyp in {'leer', 'apfel'}: if feldtyp == 'leer': zeichne_quadrat_mit_update(schlange[-1][0], schlange[-1][1], farbe['leer']) schlange.pop() elif feldtyp == 'apfel': apfel = neuer_apfel() zeichne_quadrat_mit_update(apfel[0], apfel[1], farbe['apfel']) punkte += 1 laenge += 1 frames_pro_sekunde += 1 # print(f'{punkte=}, {leben=}, {laenge=}, {frames_pro_sekunde}') zeichne_quadrat_mit_update(xneu, yneu, farbe['schlange']) schlange.insert(0, [xneu, yneu]) schreibe(BREITE//2, -2.5, f'{punkte=}, {leben=}, {laenge=}, {frames_pro_sekunde=:.1f}') if spielende: pygame.time.wait(1000) pygame.quit() sys.exit() uhr.tick(frames_pro_sekunde)