„Pong“ war das erste Videospiel, das ich gespielt habe. Ursprünglich wurde der Spieleklassiker zwischen 1966 und 1968 von Ralph H. Baer für die Konsole Odyssee der Firma Magnavox entwickelt. Weltweite Bekanntheit erlangte das Spiel aber unter dem Namen „Pong“ (da „Ping Pong“ bereits rechtlich geschützt war) durch den Konsolenhersteller Atari. Der kopierte das Spielkonzept und veröffentlichte es 1972 unter eigenem Brand auf seinen Spielekonsolen. Einfach aber genial bietet das Spiel auch heute noch einen unterhaltsamen und leichten Einstieg in die Spieleprogrammierung – hier mit pygame in Python 3 umgesetzt.
Die Mutter der meisten modernen Programmiersprachen ist und bleibt für mich zwar C/C++. Einfacheren und auch wesentlich schöneren – weil übersichtlicheren – Code bietet allerdings die relativ junge Programmiersprache Python. Gerade Einsteiger – obwohl ich Programmierneulingen ehr C/C++ als Einstiegssprache empfehle – kommen mit Python schnell und effizient ans Ziel. Bedient man sich bei der Spieleentwicklung der beliebten und einfach zu beherrschenden Library (pygame, stellen sich spielbare Erfolgserlebnisse auch bei Kindern und Jugendlichen schnell ein.

Pong in Python3 mit pygame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# P O N G (Grundversion) # # # Hinweis: Ja, normalerweise werden Variablen, Funktionen mit englischen Begriffen benamt. Da das Code-Beispiel # aber in einem deutschsprachigen Blog veröffentlicht wird, sollen auch $menschen, die der # englischen Sprache (noch) nicht mächtig sind (und dazu zählen insbesondere Kinder), einen leichteren Zugang zum Codeverständnis finden können. # An internationale Konventionen gewöhnt man sich bekanntlich später schnell. # Bibliothek pygame importieren # (Installationsanleitung findet sich im Blog oder bei pygame.org import pygame, sys from pygame.locals import * # Anzahl der Bilder pro Sekunde # Ändern, um die Spielgeschwindigkeit zu ändern BPS = 200 # Globale Variablen SPIELFELD_BREITE = 800 SPIELFELD_HOEHE = 600 LINIENSTAERKE = 20 SCHLAEGER_GROESSE = 100 SCHLAEGER_ABSTAND = 40 # Farbeinstellungen SCHWARZ = (0 ,0 ,0 ) WEISS = (255,255,255) # Spielffeld zeichnen, auf dem gespielt wird def zeichneSpielfeld(): DISPLAYSURF.fill((0,0,0)) #Spielfeldbegrenzung zeichnen pygame.draw.rect(DISPLAYSURF, WEISS, ((0,0),(SPIELFELD_BREITE,SPIELFELD_HOEHE)), LINIENSTAERKE*2) #Mittellinie zeichnen pygame.draw.line(DISPLAYSURF, WEISS, ((SPIELFELD_BREITE//2),0),((SPIELFELD_BREITE//2),SPIELFELD_HOEHE), (LINIENSTAERKE//4)) # Schläger zeichnen def zeichneSchlaeger(schlaeger): # Verhindern, dass Schläger über die untere Spielfeldbegrenzung hinaus geht if schlaeger.bottom > SPIELFELD_HOEHE - LINIENSTAERKE: schlaeger.bottom = SPIELFELD_HOEHE - LINIENSTAERKE # Verhindern, dass Schläger über die obere Spielfeldbegrenzung hinaus geht elif schlaeger.top < LINIENSTAERKE: schlaeger.top = LINIENSTAERKE # Schläger zeichnen pygame.draw.rect(DISPLAYSURF, WEISS, schlaeger) # Ball zeichnen def zeichneBall(ball): pygame.draw.rect(DISPLAYSURF, WEISS, ball) # Bewegt den Ball und gibt neue Position des Balls zurück def bewegeBall(ball, ballrichtung_X, ballrichtung_Y): ball.x += ballrichtung_X ball.y += ballrichtung_Y return ball # Überprüft, ob der Ball die Wand getroffen hat und lässt den Ball wieder abprallen. # Gibt neue Ballrichtung zurück def pruefe_Kollision_Wand(ball, ballrichtung_X, ballrichtung_Y): if ball.top == (LINIENSTAERKE) or ball.bottom == (SPIELFELD_HOEHE - LINIENSTAERKE): ballrichtung_Y = ballrichtung_Y * -1 if ball.left == (LINIENSTAERKE) or ball.right == (SPIELFELD_BREITE - LINIENSTAERKE): ballrichtung_X = ballrichtung_X * -1 return ballrichtung_X, ballrichtung_Y # Überprüft, ob der Ball den Schläger getroffen hat und lässt den Ball wieder vom Schläger abprallen def pruefe_Kollision_schlaeger(ball, schlaeger1, schlaeger2, ballrichtung_X): if ballrichtung_X == -1 and schlaeger1.right == ball.left and schlaeger1.top < ball.top and schlaeger1.bottom > ball.bottom: return -1 elif ballrichtung_X == 1 and schlaeger2.left == ball.right and schlaeger2.top < ball.top and schlaeger2.bottom > ball.bottom: return -1 else: return 1 # Prüft, ob ein neuer Spielpunkt gemacht wurde und gibt den neuen score zurück def pruefescore(schlaeger1, ball, score, ballrichtung_X): # score zurücksetzen falls linker Spielfeldrand getroffen wurde if ball.left == LINIENSTAERKE: return 0 # 1 Punkt beim Treffen des Balls zum Spielstand addieren elif ballrichtung_X == -1 and schlaeger1.right == ball.left and schlaeger1.top < ball.top and schlaeger1.bottom > ball.bottom: score += 1 return score # 5 Punkte für das Besiegen des Gegners addieren elif ball.right == SPIELFELD_BREITE - LINIENSTAERKE: score += 5 return score # Wenn kein Spielpunkt erzielt wurde, score unverändert zurückgeben else: return score # Künstliche Intelligenz des Computerspielers def kuenstlicheIntelligenz(ball, ballrichtung_X, schlaeger2): #If ball is moving away from schlaeger, center bat if ballrichtung_X == -1: if schlaeger2.centery < (SPIELFELD_HOEHE//2): schlaeger2.y += 1 elif schlaeger2.centery > (SPIELFELD_HOEHE//2): schlaeger2.y -= 1 #if ball moving towards bat, track its movement. elif ballrichtung_X == 1: if schlaeger2.centery < ball.centery: schlaeger2.y += 1 else: schlaeger2.y -=1 return schlaeger2 # Spielstandanzeige def zeigeSpielstand(score): resultSurf = BASICFONT.render('Punkte: %s' %(score), True, WEISS) resultRect = resultSurf.get_rect() resultRect.topleft = (SPIELFELD_BREITE - 150, 25) DISPLAYSURF.blit(resultSurf, resultRect) # Hauptprogramm def main(): pygame.init() global DISPLAYSURF # Schriftart einrichten global BASICFONT, BASICFONTSIZE BASICFONTSIZE = 20 BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE) BPSCLOCK = pygame.time.Clock() DISPLAYSURF = pygame.display.set_mode((SPIELFELD_BREITE,SPIELFELD_HOEHE)) pygame.display.set_caption('Pong') # Variablen initialisieren und Startposition setzen # Alle zukünftigen Änderungen der Rechtecke ballX = SPIELFELD_BREITE//2 - LINIENSTAERKE//2 ballY = SPIELFELD_HOEHE//2 - LINIENSTAERKE//2 playerOnePosition = (SPIELFELD_HOEHE - SCHLAEGER_GROESSE) //2 playerTwoPosition = (SPIELFELD_HOEHE - SCHLAEGER_GROESSE) //2 score = 0 # Ballrichtung ballrichtung_X = -1 ## -1 = links 1 = rechts ballrichtung_Y = -1 ## -1 = hoch 1 = runter # Rechtecke für Ball und Schläger zeichnen schlaeger1 = pygame.Rect(SCHLAEGER_ABSTAND,playerOnePosition, LINIENSTAERKE,SCHLAEGER_GROESSE) schlaeger2 = pygame.Rect(SPIELFELD_BREITE - SCHLAEGER_ABSTAND - LINIENSTAERKE, playerTwoPosition, LINIENSTAERKE,SCHLAEGER_GROESSE) ball = pygame.Rect(ballX, ballY, LINIENSTAERKE, LINIENSTAERKE) # Startzustand auf dem Spielfeld zeichnen zeichneSpielfeld() zeichneSchlaeger(schlaeger1) zeichneSchlaeger(schlaeger2) zeichneBall(ball) pygame.mouse.set_visible(0) # Cursor unsichtbar machen while True: # Spielschleife for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Mausbewegung -> Schläger elif event.type == MOUSEMOTION: mousex, mousey = event.pos schlaeger1.y = mousey zeichneSpielfeld() zeichneSchlaeger(schlaeger1) zeichneSchlaeger(schlaeger2) zeichneBall(ball) ball = bewegeBall(ball, ballrichtung_X, ballrichtung_Y) ballrichtung_X, ballrichtung_Y = pruefe_Kollision_Wand(ball, ballrichtung_X, ballrichtung_Y) score = pruefescore(schlaeger1, ball, score, ballrichtung_X) ballrichtung_X = ballrichtung_X * pruefe_Kollision_schlaeger(ball, schlaeger1, schlaeger2, ballrichtung_X) schlaeger2 = kuenstlicheIntelligenz (ball, ballrichtung_X, schlaeger2) zeigeSpielstand(score) pygame.display.update() BPSCLOCK.tick(BPS) if __name__=='__main__': main() |