Apr-24-2017, 04:41 PM
A simple little breakout program I wrote using 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 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
############################################################################################################# # ________ ___ ___ ________ ________ _______ ________ ___ __ ________ ___ ___ __________ # # |\ __ \|\ \ / /|\ __ \|\ __ \|\ ___ \ |\ __ \|\ \|\ \ |\ __ \|\ \|\ \|\___ ___\ # # \ \ \|\ \ \ \/ / | \ \|\ /\ \ \|\ \ \ __/|\ \ \|\ \ \ \/ /|\ \ \|\ \ \ \\\ \|___ \ \_| # # \ \ ____\ \ / / \ \ __ \ \ _ _\ \ \_|/_\ \ __ \ \ ___ \ \ \\\ \ \ \\\ \ \ \ \ # # \ \ \___|\/ / / \ \ \|\ \ \ \\ \\ \ \_|\ \ \ \ \ \ \ \\ \ \ \ \\\ \ \ \\\ \ \ \ \ # # \ \__\ __/ / / \ \_______\ \__\\ _\\ \_______\ \__\ \__\ \__\\ \__\ \_______\ \_______\ \ \__\ # # \|__||\___/ / \|_______|\|__|\|__|\|_______|\|__|\|__|\|__| \|__|\|_______|\|_______| \|__| # # \|___|/ # # v1.0 # ############################################################################################################# # PyBreakout 1.0 # Terry Ritchie # 04/24/17 # ----------------------------------------------------------------------------------------------------------- # - IMPORT LIBRARIES ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- import pygame # pygame graphics engine import random # random number library import os # operating system library import winsound # windows sound library import sys # system functions from pygame. locals import * # pygame constants # ----------------------------------------------------------------------------------------------------------- # - DEFINE CONSTANTS ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- FPS = 240 # frames per second of game play BLACK = ( 0 , 0 , 0 ) # define bright colors BLUE = ( 0 , 0 , 255 ) GREEN = ( 0 , 255 , 0 ) CYAN = ( 0 , 255 , 255 ) RED = ( 255 , 0 , 0 ) PURPLE = ( 255 , 0 , 255 ) YELLOW = ( 255 , 255 , 0 ) WHITE = ( 255 , 255 , 255 ) DBLUE = ( 0 , 0 , 127 ) # define dark colors DGREEN = ( 0 , 127 , 0 ) DCYAN = ( 0 , 127 , 127 ) DRED = ( 127 , 0 , 0 ) DPURPLE = ( 127 , 0 , 127 ) DYELLOW = ( 127 , 127 , 0 ) GRAY = ( 127 , 127 , 127 ) SILVER = ( 191 , 191 , 191 ) COLOR = (BLUE, GREEN, CYAN, RED, PURPLE, YELLOW, DBLUE, DGREEN, DCYAN, DRED, DPURPLE, DYELLOW) STARS = 100 # number of stars in starfield STARX = 0 # star x index within star list STARY = 1 # star y index within star list STARSPEED = 2 # star speed index within star list STARCOLOR = 3 # star color index within star list STARCLDIR = 4 # star color direction index within star list INPLAY = 4 # brick in play index within brick list BRICKHIT = 5 # number of times brick hit index within brick list # ----------------------------------------------------------------------------------------------------------- # - DEFINE VARIABLES ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- brick = [] # master brick list star = [] # master star list saying = [] # rendered font surface images of each level text scoretext = [] # custom number font launch = False # ball has been launched newgame = False # new game in progress levelshown = False # has level saying been shown extra = False # extra paddle awarded spacebar = 0 # rendered font surface image p1txt = 0 # rendered font surface image hitxt = 0 # rendered font surface image welcome = 0 # rendered font surface image screen = 0 # window surface px = 0 # player paddle x coordinate py = 516 # player paddle y coordinate prect = 0 # paddle collision rectangle paddles = 3 # number of player paddles bx = 0.0 # ball x coordinate by = 0.0 # ball y coordinate brect = 0 # ball collision rectangle bxdir = 0.0 # ball x direction bydir = 0.0 # ball y direction bspeed = 0.0 # ball speed maxbspeed = 0.0 # ball maximum speed minxspeed = 0.0 # ball minimum horizontal speed bspeedinc = 0.0 # ball speed increment trajectory = 0.0 # ball trajectory when hit paddle score = 0 # player score hiscore = 0 # high score level = 0 # current level of play bhit = 0 # number of times brick must be hit bricks = 0 # total number of bricks clock = 0 # FPS timer countdown = 0 # count down timer frame = 0 # frame counter # ----------------------------------------------------------------------------------------------------------- # - DEFINE FUNCTIONS ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- def Setup(): # creates the assets needed to play the game Setup() # ----------------------------------------------------------------------------------------------------------- global screen, clock, star, brick, spacebar, p1txt, hitxt, saying, welcome os.environ[ "SDL_VIDEO_CENTERED" ] = "1" # center the surface on desktop pygame.init() # start pygame engine screen = pygame.display.set_mode(( 768 , 576 )) # create the surface window pygame.display.set_caption( "PyBreakout!" ) # give window a caption pygame.mouse.set_visible( False ) # hide mouse pointer clock = pygame.time.Clock() # start clock routines font = pygame.font.SysFont( "Calibri" , 40 , True , False ) # create font and rendered surfaces spacebar = font.render( "PRESS SPACEBAR TO LAUNCH" , True , WHITE) p1txt = font.render( "PLAYER 1" , True , YELLOW) hitxt = font.render( "HIGH" , True , YELLOW) welcome = font.render( "WELCOME TO PYBREAKOUT!" , True , WHITE) saying.append(font.render( "Try Again" , True , CYAN)) saying.append(font.render( "Level 1 - Easy Peasy" , True , CYAN)) saying.append(font.render( "Level 2 - Here We Go!" , True , CYAN)) saying.append(font.render( "Level 3 - Twice As Fun" , True , CYAN)) saying.append(font.render( "Level 4 - Even Faster" , True , CYAN)) saying.append(font.render( "Level 5 - Outstanding!" , True , CYAN)) saying.append(font.render( "Level 6 - Double Whammy" , True , CYAN)) saying.append(font.render( "Level 7 - Super Human" , True , CYAN)) saying.append(font.render( "Level 8 - Unstoppable!" , True , CYAN)) saying.append(font.render( "Level 9 - Here Be Dragons" , True , CYAN)) saying.append(font.render( "Breakout Master!" , True , CYAN)) scoretext.append([ "0000 00 00 0000" ]) # create custom number strings list scoretext.append([ " 1 1 1 1 1" ]) scoretext.append([ "222 22222 222" ]) scoretext.append([ "333 3333 3333" ]) scoretext.append([ "4 44 4444 4 4" ]) scoretext.append([ "5555 555 5555" ]) scoretext.append([ "6666 6666 6666" ]) scoretext.append([ "777 7 7 7 7" ]) scoretext.append([ "8888 88888 8888" ]) scoretext.append([ "9999 9999 9999" ]) for i in range (STARS): # create starfield sx = random.randrange( 0 , 767 ) sy = random.randrange( 0 , 575 ) cd = 0 while not (cd): cd = random.randrange( - 1 , 2 ) ss = 0 while ss < . 25 : ss = random.random() star.append([sx, sy, ss, random.randrange( 1 , 255 ), cd]) for i in range ( 6 ): # create bricks b = [] for j in range ( 16 ): b.append([j * 48 + 1 , 96 + (i * 24 ) + 1 , 47 , 23 , True , 0 ]) brick.append(b) # ----------------------------------------------------------------------------------------------------------- def Draw_Digit(dx, dy, d, c, s): # draw a large digit to the screen Draw_Digit() # ----------------------------------------------------------------------------------------------------------- # dx = digit top left x coordinate # dy = digit top left y coordinate # d = digit (0 - 9) # c = digit color # s = size of digit squares # The large digits are drawn as follows: # # x # --------- # 0 1 2 # +---+---+---+ +---+---+---+ If there is a character (non-space) in the text a # | 0 | * | * | * | | * | * | * | square is drawn in that position. As the nested for # | +---+---+---+ +---+---+---+ statements progress a number is drawn from the text # | 1 | * | | * | | | | * | that describes where a square should be placed in # | +---+---+---+ +---+---+---+ each row. # y | 2 | * | | * | | * | * | * | # | +---+---+---+ +---+---+---+ # | 3 | * | | * | | | | * | # | +---+---+---+ +---+---+---+ # | 4 | * | * | * | | * | * | * | # | +---+---+---+ +---+---+---+ # # "0000 00 00 0000" "333 3333 3333" # |||---|||---||| |||---|||---||| # Row-> 0 1 2 3 4 0 1 2 3 4 p = - 1 # current position in text string for y in range ( 5 ): for x in range ( 3 ): p + = 1 # increment text position if scoretext[d][ 0 ][p] ! = " " : # if character in position draw square pygame.draw.rect(screen, c, [dx + x * s, dy + y * s, s, s], 0 ) # ----------------------------------------------------------------------------------------------------------- def New_Game(): # starts a new game of pybreakout New_Game() # ----------------------------------------------------------------------------------------------------------- global level, launch, newgame, levelshown, score, paddles, extra launch = False # reset booleans newgame = True levelshown = False while newgame: # loop while in new game mode Play_Round() score = 0 # reset player score level = 0 # reset level of play paddles = 3 # reset number of player paddles extra = False # reset extra paddle # ----------------------------------------------------------------------------------------------------------- def Next_Level(): # sets up the next level of the game Next_Level() # ----------------------------------------------------------------------------------------------------------- global level, bspeed, bxdir, bydir, brick, bhit, maxbspeed, bspeedinc, bricks global launch, trajectory, levelshown, countdown, minxspeed, frame level + = 1 # increment level of play bspeed = 1 # reset ball characteristics bxdir = . 5 bydir = - 1 if not (level % 3 ): # bricks hit twice every third level bhit = 2 else : bhit = 1 for i in range ( 6 ): # reset brick characteristics for j in range ( 16 ): brick[i][j][INPLAY] = True brick[i][j][BRICKHIT] = 0 bricks = 96 maxbspeed = 2 + (level / 8 ) # calculate maximum ball speed if maxbspeed > 4 : maxbspeed = 4 minxspeed = maxbspeed / 4 * ( 1 + (maxbspeed / 4 )) # calculate minimum ball horizontal speed bspeedinc = level / 96 # calculate ball speed increments trajectory = ( 100 / (level * 100 )) * 200 # calculate level trajectory launch = True # reset booleans levelshown = False countdown = 9 # reset countdown frame = 0 # ----------------------------------------------------------------------------------------------------------- def Draw_Frame(): # draws a frame of the game Draw_Frame() # ----------------------------------------------------------------------------------------------------------- global countdown, frame, launch screen.fill(BLACK) Draw_Stars() # draw starfield Draw_Bricks() # draw bricks pygame.draw.circle(screen, RED, [px - 40 , 526 ], 10 , 0 ) # draw paddle pygame.draw.circle(screen, RED, [px + 40 , 526 ], 10 , 0 ) pygame.draw.rect(screen, WHITE, [px - 40 , 516 , 80 , 20 ], 0 ) for i in range (paddles): # draw paddles remaining x = (i + 1 ) * 60 pygame.draw.circle(screen, RED, [x - 20 , 560 ], 5 , 0 ) pygame.draw.circle(screen, RED, [x + 20 , 560 ], 5 , 0 ) pygame.draw.rect(screen, WHITE, [x - 19 , 555 , 38 , 10 ], 0 ) screen.blit(hitxt, [ 525 , 0 ]) # display text screen.blit(p1txt, [ 155 , 0 ]) scoretxt = (( 6 - len ( str (score))) * "0" ) + str (score) # format scores hiscoretxt = (( 6 - len ( str (hiscore))) * "0" ) + str (hiscore) for i in range ( 6 ): # draw scores Draw_Digit( 326 + (i * 20 ), 5 , int (scoretxt[i]), WHITE, 5 ) Draw_Digit( 628 + (i * 20 ), 5 , int (hiscoretxt[i]), WHITE, 5 ) leveltxt = (( 2 - len ( str (level))) * "0" ) + str (level) for i in range ( 2 ): Draw_Digit( 740 + (i * 8 ), 555 , int (leveltxt[i]), WHITE, 2 ) if launch: # display level text lev = 0 if not (levelshown): lev = level if lev > 10 : lev = 10 if paddles > 0 : screen.blit(saying[lev], [( 768 - pygame.Surface.get_width(saying[lev])) / / 2 , 265 ]) screen.blit(spacebar, [ 140 , 400 ]) if countdown > 6 : # display count down timer clr = GREEN elif countdown > 3 : clr = YELLOW else : clr = RED Draw_Digit( 369 , 325 , countdown, clr, 10 ) frame + = 1 if frame = = FPS: frame = 0 countdown - = 1 winsound.Beep( 2200 , 5 ) if countdown = = 0 : launch = False if newgame: screen.blit(welcome, [ 145 , 300 ]) else : pygame.draw.circle(screen, CYAN, [ int (bx), int (by)], 7 , 0 ) # draw ball pygame.display.flip() # ----------------------------------------------------------------------------------------------------------- def Draw_Stars(): # draws the moving starfield Draw_Stars() # ----------------------------------------------------------------------------------------------------------- global star for i in range (STARS): # cycle through all stars star[i][STARY] + = star[i][STARSPEED] # update speed star[i][STARCOLOR] + = star[i][STARCLDIR] # update color if star[i][STARCOLOR] = = 0 or star[i][STARCOLOR] = = 255 : # keep color in limits star[i][STARCLDIR] * = - 1 if star[i][STARY] > = 767 : # star went off bottom of screen star[i][STARY] = random.randrange( - 30 , - 10 ) star[i][STARX] = random.randrange( 0 , 768 ) c = star[i][STARCOLOR] pygame.draw.circle(screen, [c, c, c], [star[i][STARX], int (star[i][STARY])], 0 , 0 ) # ----------------------------------------------------------------------------------------------------------- def Draw_Bricks(): # check for ball/brick collisions while bricks being drawn Draw_Bricks() # ----------------------------------------------------------------------------------------------------------- global bxdir, bydir, score, hiscore, bspeed, bricks, brick, extra, paddles alreadyhit = False for i in range ( 6 ): # cycle through all bricks for j in range ( 16 ): if brick[i][j][INPLAY]: # draw brick if in play brick_rect = pygame.Rect(brick[i][j][ 0 : 4 ]) pygame.draw.rect(screen, COLOR[i + brick[i][j][BRICKHIT] * 6 ], brick_rect, 0 ) if not (newgame): if brect.colliderect(brick_rect) and not (alreadyhit): # first brick hit? brick[i][j][BRICKHIT] + = 1 # update brick hits if brick[i][j][BRICKHIT] = = bhit: # max number of hits? brick[i][j][INPLAY] = False # brick out of play bricks - = 1 score + = ( 6 - i) * 10 winsound.Beep(( 6 - i) * 200 , 10 ) else : # brick still in play score + = ( 6 - i) * 5 winsound.Beep( 2200 , 10 ) if score > = 10000 and not (extra): # award extra ship paddles + = 1 extra = True for i in range ( 5 ): winsound.Beep((i + 1 ) * 1000 , 5 ) alreadyhit = True # no more collision checks this loop bspeed + = bspeedinc # increase ball speed if bspeed > maxbspeed: # keep ball speed in limits bspeed = maxbspeed if score > hiscore: # update high score hiscore = score if sgn(bxdir) = = 1 : # ball traveling right bdx = int (brick_rect[ 0 ] - bx) # ball distance from left side of brick else : # ball traveling left bdx = int (bx - brick_rect[ 0 ]) - 46 # ball distance from right side of brick if sgn(bydir) = = 1 : # ball traveling down bdy = int (brick_rect[ 1 ] - by) # ball distance from top of brick else : # ball traveling up bdy = int (by - brick_rect[ 1 ]) - 22 # ball distance from bottom of brick if bdx = = bdy: # hit corner of brick bxdir = - bxdir bydir = - bydir elif bdx > bdy: # hit left/right side of brick bxdir = - bxdir else : # hit top/bottom of brick bydir = - bydir # ----------------------------------------------------------------------------------------------------------- def Get_Input(): # gets user input and processes Get_Input() # ----------------------------------------------------------------------------------------------------------- global px, launch, levelshown, newgame pygame.event.pump() # update keyboard buffer key = pygame.key.get_pressed() # get all keys pressed if key[K_SPACE] and launch: # launch ball with space bar? launch = False levelshown = True for event in pygame.event.get(): # cycle through events if event. type = = QUIT or key[K_ESCAPE]: # leave game if closed or ESC pressed pygame.quit() sys.exit() elif (event. type = = KEYUP or event. type = = MOUSEBUTTONUP) and newgame: # start a new game? newgame = False launch = True elif event. type = = MOUSEBUTTONUP and launch: # launch ball with mouse button? launch = False levelshown = True elif event. type = = MOUSEMOTION: # mouse moved? px = event.pos[ 0 ] # set player paddle x to mouse x if px < 50 : # keep paddle on screen px = 50 elif px > 718 : px = 718 pygame.mouse.set_pos(px, py) # bind mouse to paddle # ----------------------------------------------------------------------------------------------------------- def Play_Round(): # plays a round of pybreakout Play_Round() # ----------------------------------------------------------------------------------------------------------- global bx, by, bxdir, bydir, px, brect, launch, paddles, bspeed, countdown Get_Input() # get user input and process if launch or newgame: # keep ball on paddle bx = px by = 511 else : # update ball position bx + = bxdir by + = bydir * bspeed if bx < = 7 : # hit left side of screen? bx = 7 bxdir = - bxdir elif bx > = 760 : # hit right side of screen? bx = 760 bxdir = - bxdir if by < = 7 : # hit top of screen? bydir = - bydir elif by > = 568 : # player missed ball? paddles - = 1 launch = True bspeed = 1 bxdir = . 5 bydir = - 1 countdown = 9 brect = pygame.Rect(bx - 5 , by - 5 , 10 , 10 ) # create ball rectangle object prect = pygame.Rect(px - 50 , 516 , 100 , 1 ) # create paddle rectangle object if brect.colliderect(prect): # did the objects collide? bydir = - bydir by = 511 bxdir + = (bx - px) / trajectory # add some trajectory if abs (bxdir) > maxbspeed: # keep horizontal ball speed in limits bxdir = sgn(bxdir) * maxbspeed elif abs (bxdir) < minxspeed: bxdir = sgn(bxdir) * minxspeed winsound.Beep( 440 , 10 ) Draw_Frame() # draw the next frame of game clock.tick(FPS) # limit FPS # ----------------------------------------------------------------------------------------------------------- def sgn(n): # returns the sign of a number (-1, 0, or 1) sgn() # ----------------------------------------------------------------------------------------------------------- # n = any numeric value if n > 0 : # positive return 1 elif n < 0 : # negative return - 1 else : # must be zero return 0 # ----------------------------------------------------------------------------------------------------------- # - MAIN PROGRAM LOOP --------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------- Setup() # generate game assets while True : # main loop New_Game() # initiate a new game while paddles > 0 : # loop until player loses all paddles Next_Level() # set up next level of play while paddles > 0 and bricks: # loop until no paddles or bricks cleared Play_Round() # play the round |