Guest User

Untitled

a guest
Apr 17th, 2013
470
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 27.14 KB | None | 0 0
  1. # Treasure Seeker
  2. # by Adam Binks
  3.  
  4. import random, pygame, sys, time, pygame._view
  5. from pygame.locals import *
  6.  
  7. FPS = 30
  8. WINDOWWIDTH = 640
  9. WINDOWHEIGHT = 480
  10. CELLSIZE = 20
  11. HALFCELLSIZE = int(CELLSIZE / 2)
  12. assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size."
  13. assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size."
  14. XCELLNUM = int(WINDOWWIDTH / CELLSIZE)
  15. YCELLNUM = int(WINDOWHEIGHT / CELLSIZE)
  16. SKYGAP = 5                 # number of rows of sky above the grass layer
  17. GRASSLAYER = SKYGAP + 1    # y coord of grass layer
  18.  
  19.  
  20. LEFT = 'left'
  21. RIGHT = 'right'
  22. UP = 'up'
  23. COLOUR = 'colour'
  24. RECT = 'rect'
  25. SURF = 'surf'
  26. LIVES = 'lives'
  27. DIRECTION = 'direction'
  28. VELOCITY = 'velocity'
  29. BOMBSPLACED = 'bombsplaced'
  30.  
  31. MOVESPEED = 5 # horizontal move speed
  32. JUMPSPEED = 2
  33. JUMPHEIGHT = -10
  34. FALLSPEED = -JUMPHEIGHT # is really FALLHEIGHT
  35. MAXLIVES = 3
  36. MAXBOMBS = 2 # inclusive
  37. FUSELENGTH = 2 # time before it goes BOOM in seconds
  38. NUMGEMS = 5 # per level
  39.  
  40. grassImg = pygame.image.load('grass.png')
  41. dirtImg = pygame.image.load('dirt.png')
  42. rockImg = pygame.image.load('rock.png')
  43. gemImg = pygame.image.load('gem.png')
  44. bombImg = pygame.image.load('bomb.png')
  45. fireImg = pygame.image.load('fire.png')
  46. titleImg = pygame.image.load('title.gif')
  47.  
  48. redPlayerRight = pygame.image.load('redPlayerRight.gif')
  49. redPlayerLeft = pygame.image.load('redPlayerLeft.gif')
  50. bluePlayerRight = pygame.image.load('bluePlayerRight.gif')
  51. bluePlayerLeft = pygame.image.load('bluePlayerLeft.gif')
  52. player1Rect = redPlayerRight.get_rect()
  53. player2Rect = bluePlayerLeft.get_rect()
  54. P1StartPos = [(3 * CELLSIZE), ((SKYGAP + 1) * CELLSIZE)]
  55. P2StartPos = [((XCELLNUM * CELLSIZE) - (2 * CELLSIZE)), ((SKYGAP + 1) * CELLSIZE)]
  56. P1score = P2score = 0
  57.  
  58. bigRedMan = pygame.transform.scale(redPlayerRight, (200, 200))
  59. redManRect = bigRedMan.get_rect()
  60. redManRect.center = (int(WINDOWWIDTH / 4), int(WINDOWHEIGHT / 3) * 2)
  61. bigBlueMan = pygame.transform.scale(bluePlayerLeft, (200, 200))
  62. blueManRect = bigBlueMan.get_rect()
  63. blueManRect.center = (int(WINDOWWIDTH / 4) * 3, int(WINDOWHEIGHT / 3) * 2)
  64.  
  65. # Set up blocks
  66. FIRE   = -1     # ^ NON SOLID
  67. AIR    = 0      # v
  68. DIRT   = 1      # ^
  69. ROCK   = 3      # | SOLID
  70. GRASS  = 4      # |
  71. GEM    = 5      # |
  72. BOMB   = 6      # v
  73.  
  74. # Colours     R    G    B
  75. WHITE     = (255, 255, 255)
  76. BLACK     = (  0,   0,   0)
  77. RED       = (255,   0,   0)
  78. DARKRED   = (255,  10,  10)
  79. BLUE      = (  0,   0, 255)
  80. GREEN     = (  0, 255,   0)
  81. ORANGE    = (255, 165,   0)
  82. DARKGREEN = (  0, 155,   0)
  83. DARKGREY  = ( 60,  60,  60)
  84. LIGHTGREY = (180, 180, 180)
  85. BROWN     = (139,  69,  19)
  86. BROWN2    = (160,  82,  45)
  87. SKYBLUE   = (176, 226, 255)
  88. TITLEBG   = (139, 130, 126)
  89.  
  90. SKYCOLOUR = SKYBLUE
  91. DIRTCOLOUR = BROWN
  92. DIRT2COLOUR = BROWN2
  93. ROCKCOLOUR = DARKGREY
  94. GRASSCOLOUR = GREEN
  95. GEMCOLOUR = RED
  96. BOMBCOLOUR = BLACK
  97. FIRECOLOUR = ORANGE
  98. BGCOLOUR = LIGHTGREY
  99.  
  100.  
  101.  
  102.  
  103.  
  104. def main():
  105.     global FPSCLOCK, DISPLAYSURF, BASICFONT, BIGFONT, jumpSound, clickSound, explosionSound, P1score, P2score, P1name, P2name
  106.  
  107.     pygame.init()
  108.     FPSCLOCK = pygame.time.Clock()
  109.     DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
  110.     BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
  111.     BIGFONT = pygame.font.Font('freesansbold.ttf', 42)
  112.     pygame.display.set_icon(rockImg)
  113.     pygame.display.set_caption('Treasure Seeker')
  114.     # Sounds
  115.     jumpSound = pygame.mixer.Sound('jump.ogg')
  116.     clickSound = pygame.mixer.Sound('click.ogg')
  117.     explosionSound = pygame.mixer.Sound('explosion.ogg')
  118.  
  119.     button = 0
  120.     while button != 1:
  121.         button = showStartScreen()
  122.         if button == 2: button = showCredits()
  123.         if button == 3: howToPlay()
  124.     while True:
  125.         winner = runGame(P1score, P2score)
  126.         P1score, P2score = showGameOverScreen(winner)
  127.  
  128.  
  129. def runGame(P1score, P2score):
  130.     # set up variables
  131.     global muted
  132.     P1 = {RECT: player1Rect, SURF: redPlayerRight, DIRECTION: None, VELOCITY: 0, COLOUR: RED,  LIVES: MAXLIVES, BOMBSPLACED: 0}
  133.     P2 = {RECT: player2Rect, SURF: bluePlayerLeft, DIRECTION: None, VELOCITY: 0, COLOUR: BLUE, LIVES: MAXLIVES, BOMBSPLACED: 0}
  134.     P1[RECT].bottomleft = P1StartPos
  135.     P2[RECT].bottomleft = P2StartPos
  136.     bombs = []
  137.     muted = False
  138.  
  139.     debugMode = False
  140.     mainBoard = generateTerrain()
  141.     drawBoard(mainBoard, P1, P2, P1score, P2score, True)
  142.     pygame.display.update()
  143.     pygame.time.wait(2000)
  144.    
  145.     while True: # main game loop
  146.         checkForQuit()
  147.         for event in pygame.event.get(): # event handling loop
  148.             if event.type == KEYDOWN:
  149.                 if (event.key == K_LEFT):
  150.                     P1[DIRECTION] = LEFT
  151.                     P1[SURF] = redPlayerLeft
  152.                 elif (event.key == K_RIGHT):
  153.                     P1[DIRECTION] = RIGHT
  154.                     P1[SURF] = redPlayerRight
  155.                 elif (event.key == K_UP):
  156.                     if not muted: jumpSound.play()
  157.                     if isOnGround(mainBoard, P1[RECT]):
  158.                         P1[VELOCITY] = JUMPHEIGHT
  159.                 elif (event.key == K_PERIOD):
  160.                     if P1[BOMBSPLACED] < MAXBOMBS:
  161.                         mainBoard, newBombDict, P1 = placeBomb(mainBoard, P1)
  162.                         bombs.append(newBombDict)
  163.                 elif (event.key == K_d):
  164.                     P2[DIRECTION] = RIGHT
  165.                     P2[SURF] = bluePlayerRight
  166.                 elif (event.key == K_a):
  167.                     P2[DIRECTION] = LEFT
  168.                     P2[SURF] = bluePlayerLeft
  169.                 elif (event.key == K_w):
  170.                     if not muted: jumpSound.play()
  171.                     if isOnGround(mainBoard, P2[RECT]):
  172.                         P2[VELOCITY] = JUMPHEIGHT
  173.                 elif (event.key == K_q):
  174.                     if P2[BOMBSPLACED] < MAXBOMBS:
  175.                         mainBoard, newBombDict, P2 = placeBomb(mainBoard, P2)
  176.                         bombs.append(newBombDict)
  177.                 elif (event.key == K_m):
  178.                     muted = not muted
  179.                 elif (event.key == K_0):
  180.                     debugMode = not debugMode
  181.                 elif (event.key == K_r): # reset player positions
  182.                     if debugMode:
  183.                         P1[RECT].bottomleft = P1StartPos
  184.                         P2[RECT].bottomleft =P2StartPos
  185.             elif event.type == KEYUP:
  186.                 if event.key == K_LEFT and P1[DIRECTION] == LEFT:
  187.                     P1[DIRECTION] = None
  188.                 elif event.key == K_RIGHT and P1[DIRECTION] == RIGHT:
  189.                     P1[DIRECTION] = None
  190.                 if event.key == K_a and P2[DIRECTION] == LEFT:
  191.                     P2[DIRECTION] = None
  192.                 elif event.key == K_d and P2[DIRECTION] == RIGHT:
  193.                     P2[DIRECTION] = None
  194.        
  195.         mainBoard, bombs = explodeBombs(mainBoard, bombs, P1, P2)
  196.         P1copy = P1
  197.         P2copy = P2
  198.         P1 = checkForDeath(mainBoard, P1)
  199.         if P1 == 'dead':
  200.             P1copy[SURF] = pygame.transform.rotate(P1copy[SURF], 90)
  201.             drawBoard(mainBoard, P1copy, P2copy, P1score, P2score)
  202.             gemSurf = BIGFONT.render('P1 exploded!', 1, DARKGREY)
  203.             gemRect = gemSurf.get_rect()
  204.             gemRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 5))
  205.             DISPLAYSURF.blit(gemSurf, gemRect)
  206.             pygame.display.update()
  207.             pygame.time.wait(2000)
  208.             return 'P2'
  209.         if P1 == 'gem':
  210.             P2copy[SURF] = pygame.transform.rotate(P2copy[SURF], 90)
  211.             drawBoard(mainBoard, P1copy, P2copy, P1score, P2score)
  212.             gemSurf = BIGFONT.render('P1 found a gem!', 1, DARKGREY)
  213.             gemRect = gemSurf.get_rect()
  214.             gemRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 5))
  215.             DISPLAYSURF.blit(gemSurf, gemRect)
  216.             pygame.display.update()
  217.             pygame.time.wait(2000)
  218.             return 'P1'
  219.         P2 = checkForDeath(mainBoard, P2)
  220.         if P2 == 'dead':
  221.             P2copy[SURF] = pygame.transform.rotate(P2copy[SURF], 90)
  222.             drawBoard(mainBoard, P1, P2copy, P1score, P2score)
  223.             gemSurf = BIGFONT.render('P2 exploded!', 1, DARKGREY)
  224.             gemRect = gemSurf.get_rect()
  225.             gemRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 5))
  226.             DISPLAYSURF.blit(gemSurf, gemRect)
  227.             pygame.display.update()
  228.             pygame.time.wait(2000)
  229.             return 'P1'
  230.         if P2 == 'gem':
  231.             P1copy[SURF] = pygame.transform.rotate(P1copy[SURF], 90)
  232.             drawBoard(mainBoard, P1copy, P1copy, P1score, P2score)
  233.             gemSurf = BIGFONT.render('P2 found a gem!', 1, DARKGREY)
  234.             gemRect = gemSurf.get_rect()
  235.             gemRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 5))
  236.             DISPLAYSURF.blit(gemSurf, gemRect)
  237.             pygame.display.update()
  238.             pygame.time.wait(2000)
  239.             return 'P2'
  240.         P1 = movePlayer(mainBoard, P1)
  241.         P2 = movePlayer(mainBoard, P2)
  242.  
  243.         drawBoard(mainBoard, P1, P2, P1score, P2score)
  244.         if debugMode: drawDebug(mainBoard, P1, P2)
  245.         pygame.display.update()
  246.         FPSCLOCK.tick(FPS)
  247.         pygame.time.get_ticks()
  248.  
  249.  
  250. def showStartScreen():
  251.     DISPLAYSURF.fill(ORANGE)
  252.     pygame.draw.rect(DISPLAYSURF, TITLEBG,  (20, 20, WINDOWWIDTH - 40, WINDOWHEIGHT - 40), 0)
  253.     titleRect = titleImg.get_rect()
  254.     titleRect.midbottom = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) - 40)
  255.     playSurf = BASICFONT.render('Play', 1, LIGHTGREY)
  256.     playRect = playSurf.get_rect()
  257.     playRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
  258.     creditsSurf = BASICFONT.render('Credits', 1, LIGHTGREY)
  259.     creditsRect = playSurf.get_rect()
  260.     creditsRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 25)
  261.     helpSurf = BASICFONT.render('Help', 1, LIGHTGREY)
  262.     helpRect = playSurf.get_rect()
  263.     helpRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 50)
  264.     quitSurf = BASICFONT.render('Quit', 1, LIGHTGREY)
  265.     quitRect = quitSurf.get_rect()
  266.     quitRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 75)
  267.     DISPLAYSURF.blit(bigRedMan, redManRect)
  268.     DISPLAYSURF.blit(bigBlueMan, blueManRect)
  269.     DISPLAYSURF.blit(titleImg, titleRect)
  270.     DISPLAYSURF.blit(playSurf, playRect)
  271.     DISPLAYSURF.blit(creditsSurf, creditsRect)
  272.     DISPLAYSURF.blit(helpSurf, helpRect)
  273.     DISPLAYSURF.blit(quitSurf, quitRect)
  274.     pygame.display.update()
  275.     pygame.time.wait(200)
  276.     pygame.mouse.get_pressed()
  277.     while True:
  278.         mousePosition = pygame.mouse.get_pos()
  279.         if pygame.mouse.get_pressed()[0]:
  280.                 if playRect.collidepoint(mousePosition):
  281.                     clickSound.play()
  282.                     return 1
  283.                 if creditsRect.collidepoint(mousePosition):
  284.                     clickSound.play()
  285.                     return 2
  286.                 if helpRect.collidepoint(mousePosition):
  287.                     clickSound.play()
  288.                     return 3
  289.                 if quitRect.collidepoint(mousePosition):
  290.                     clickSound.play()
  291.                     terminate()
  292.         checkForQuit()
  293.  
  294.  
  295. def showGameOverScreen(winner):
  296.     global P1score, P2score
  297.     DISPLAYSURF.fill(RED)
  298.     pygame.draw.rect(DISPLAYSURF, DARKGREY,  (20, 20, WINDOWWIDTH - 40, WINDOWHEIGHT - 40), 0)
  299.     titleSurf = BIGFONT.render('Game Over!', 1, RED)
  300.     titleRect = titleSurf.get_rect()
  301.     titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) - 150)
  302.  
  303.     if winner == 'P1':
  304.         man = bigRedMan
  305.         manRect = redManRect
  306.         P1score += 1
  307.     else:
  308.         man = bigBlueMan
  309.         manRect = blueManRect
  310.         P2score += 1
  311.  
  312.     manRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
  313.     backSurf = BASICFONT.render('Play again?', 1, LIGHTGREY)
  314.     backRect = backSurf.get_rect()
  315.     backRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 125)
  316.     quitSurf = BASICFONT.render('Quit', 1, LIGHTGREY)
  317.     quitRect = quitSurf.get_rect()
  318.     quitRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 150)
  319.     winnerSurf = BASICFONT.render('%s won' %(winner), 1, WHITE)
  320.     winnerRect = winnerSurf.get_rect()
  321.     winnerRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) - 120)
  322.     P1scoreSurf = BIGFONT.render('P1:' + str(P1score), 1, WHITE)
  323.     P1scoreRect = P1scoreSurf.get_rect()
  324.     P1scoreRect.midleft = (50, int(WINDOWHEIGHT / 2))
  325.     P2scoreSurf = BIGFONT.render('P2:' + str(P2score), 1, WHITE)
  326.     P2scoreRect = P2scoreSurf.get_rect()
  327.     P2scoreRect.midright = (WINDOWWIDTH - 50, int(WINDOWHEIGHT / 2))
  328.     DISPLAYSURF.blit(P1scoreSurf, P1scoreRect)
  329.     DISPLAYSURF.blit(P2scoreSurf, P2scoreRect)
  330.     DISPLAYSURF.blit(backSurf, backRect)
  331.     DISPLAYSURF.blit(quitSurf, quitRect)
  332.     DISPLAYSURF.blit(titleSurf, titleRect)
  333.     DISPLAYSURF.blit(man, manRect)
  334.     DISPLAYSURF.blit(winnerSurf, winnerRect)
  335.     pygame.display.update()
  336.     while True:
  337.         mousePosition = pygame.mouse.get_pos()
  338.         if pygame.mouse.get_pressed()[0]:
  339.                 if backRect.collidepoint(mousePosition):
  340.                     clickSound.play()
  341.                     return (P1score, P2score)
  342.                 if quitRect.collidepoint(mousePosition):
  343.                     clickSound.play()
  344.                     terminate()
  345.         checkForQuit()
  346.  
  347.  
  348. def showCredits():
  349.     DISPLAYSURF.fill(BLUE)
  350.     pygame.draw.rect(DISPLAYSURF, BLACK,  (20, 20, WINDOWWIDTH - 40, WINDOWHEIGHT - 40), 0)
  351.     creditsSurf = BIGFONT.render('A game by Adam Binks', 1, WHITE)
  352.     creditsRect = creditsSurf.get_rect()
  353.     creditsRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) - 50)
  354.     twitterSurf = BASICFONT.render('Follow me on Twitter! @thebinks98', 1, LIGHTGREY)
  355.     twitterRect = twitterSurf.get_rect()
  356.     twitterRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
  357.     backSurf = BASICFONT.render('Back', 1, LIGHTGREY)
  358.     backRect = backSurf.get_rect()
  359.     backRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 3))
  360.     gemRect = gemImg.get_rect()
  361.     gemRect.center = (int(WINDOWWIDTH / 2), 2 * int(WINDOWHEIGHT / 3))
  362.     DISPLAYSURF.blit(creditsSurf, creditsRect)
  363.     DISPLAYSURF.blit(twitterSurf, twitterRect)
  364.     DISPLAYSURF.blit(backSurf, backRect)
  365.     DISPLAYSURF.blit(gemImg, gemRect)
  366.     pygame.display.update()
  367.     pygame.mouse.get_pressed()
  368.     while True:
  369.         mousePosition = pygame.mouse.get_pos()
  370.         if pygame.mouse.get_pressed()[0]:
  371.                 if backRect.collidepoint(mousePosition):
  372.                     clickSound.play()
  373.                     return 0
  374.         checkForQuit()
  375.  
  376.  
  377. def howToPlay():
  378.     DISPLAYSURF.fill(ORANGE)
  379.     pygame.draw.rect(DISPLAYSURF, BLACK,  (20, 20, WINDOWWIDTH - 40, WINDOWHEIGHT - 40), 0)
  380.     playSurf = BASICFONT.render('Back', 1, LIGHTGREY)
  381.     playRect = playSurf.get_rect()
  382.     playRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 3))
  383.     questionMarkSurf = BIGFONT.render('?', 1, BLUE)
  384.     questionMarkRect = questionMarkSurf.get_rect()
  385.     questionMarkRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) - 30)
  386.     line1Surf = BASICFONT.render('P1 moves with <^>v keys and places a bomb with .', 1, LIGHTGREY)
  387.     line1Rect = line1Surf.get_rect()
  388.     line1Rect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
  389.     line2Surf = BASICFONT.render('P2 moves with WASD keys and places a bomb with Q', 1, LIGHTGREY)
  390.     line2Rect = line2Surf.get_rect()
  391.     line2Rect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 25)
  392.     line3Surf = BASICFONT.render('Find a gem or blow up your opponent to win! (Press M to mute.)', 1, LIGHTGREY)
  393.     line3Rect = line3Surf.get_rect()
  394.     line3Rect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 50)
  395.     line4Surf = BASICFONT.render('TIP: Stuck in a hole? Jump on an unexploded bomb!', 1, LIGHTGREY)
  396.     line4Rect = line4Surf.get_rect()
  397.     line4Rect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 75)
  398.     DISPLAYSURF.blit(line1Surf, line1Rect)
  399.     DISPLAYSURF.blit(line2Surf, line2Rect)
  400.     DISPLAYSURF.blit(line3Surf, line3Rect)
  401.     DISPLAYSURF.blit(line4Surf, line4Rect)
  402.     DISPLAYSURF.blit(playSurf, playRect)
  403.     DISPLAYSURF.blit(questionMarkSurf, questionMarkRect)
  404.     pygame.display.update()
  405.     pygame.mouse.get_pressed()
  406.     while True:
  407.         mousePosition = pygame.mouse.get_pos()
  408.         if pygame.mouse.get_pressed()[0]:
  409.                 if playRect.collidepoint(mousePosition):
  410.                     clickSound.play()
  411.                     return 1
  412.         checkForQuit()
  413.  
  414.  
  415. def movePlayer(board, P):
  416.     # jumping
  417.     if P[VELOCITY] < 0:
  418.         if board[toBoard(P[RECT].right - 1)][toBoard(P[RECT].top + P[VELOCITY])] in (AIR, FIRE, GEM)\
  419.         and board[toBoard(P[RECT].left + 1)][toBoard(P[RECT].top + P[VELOCITY])] in (AIR, FIRE, GEM): # if space above is free move there
  420.             P[RECT].move_ip(0, P[VELOCITY])
  421.             P[VELOCITY] += 1
  422.         else: P[VELOCITY] = 0 # else velocity = 0 so start falling next turn
  423.  
  424.     # falling
  425.     if not isOnGround(board, P[RECT]):
  426.         if P[VELOCITY] > 0:
  427.             if P[VELOCITY] < FALLSPEED: # velocity is not maximum increment it
  428.                 P[VELOCITY] += 1
  429.             P[RECT].move_ip(0, P[VELOCITY])
  430.             for i in reversed(range(1, P[VELOCITY])):
  431.                 while board[toBoard(P[RECT].left + 1)][toBoard(P[RECT].bottom - 1)]\
  432.                 or board[toBoard(P[RECT].right - 1)][toBoard(P[RECT].bottom - 1)]not in (AIR, FIRE, GEM):
  433.                     P[RECT].move_ip(0, -i)
  434.             if P[RECT].bottom - 1 % 20 in (9, 19):
  435.                 P[RECT].move_ip(0, 1)
  436.             for i in reversed(range(1, P[VELOCITY])):
  437.                 if board[toBoard(P[RECT].left + 1)][toBoard(P[RECT].bottom + i)] in (AIR, FIRE, GEM)\
  438.                 and board[toBoard(P[RECT].right - 1)][toBoard(P[RECT].bottom + i)] in (AIR, FIRE, GEM): #if i pixels above ground fall i pixels
  439.                     P[RECT].move_ip(0, i)
  440.                     break # break if can fall, else continue trying smaller values of i
  441.         if P[VELOCITY] == 0:
  442.             P[VELOCITY] = 1
  443.  
  444.     # moving left/right
  445.     if P[DIRECTION] == LEFT:
  446.         if P[RECT].left+1 - MOVESPEED > 0 and board[toBoard(P[RECT].left + 1 - MOVESPEED)][toBoard(P[RECT].top)] in (AIR, FIRE, GEM)\
  447.         and board[toBoard(P[RECT].left + 1 - MOVESPEED)][toBoard(P[RECT].bottom - 1)] in (AIR, FIRE, GEM):
  448.             P[RECT].move_ip(-MOVESPEED, 0)
  449.     elif P[DIRECTION] == RIGHT:
  450.         if P[RECT].right-1 + MOVESPEED < WINDOWWIDTH and board[toBoard(P[RECT].right - 1 + MOVESPEED)][toBoard(P[RECT].top)] in (AIR, FIRE, GEM)\
  451.         and board[toBoard(P[RECT].right - 1 + MOVESPEED)][toBoard(P[RECT].bottom - 1)] in (AIR, FIRE, GEM):
  452.             P[RECT].move_ip(MOVESPEED, 0)
  453.  
  454.     # standing
  455.     if isOnGround(board, P[RECT]): P[VELOCITY] = 0
  456.  
  457.     return P
  458.  
  459.  
  460. def checkForDeath(board, P):
  461.     Px, Py = P[RECT].midtop
  462.     Px2, Py2 = P[RECT].midbottom
  463.     if board[toBoard(Px)][toBoard(Py)] == FIRE:
  464.         P[LIVES] -= 1
  465.         P[RECT].bottomleft = P1StartPos
  466.     if P[LIVES] == 0:
  467.         return 'dead'
  468.     if board[toBoard(Px)][toBoard(Py)] == GEM or board[toBoard(Px2)][toBoard(Py2)] == GEM:
  469.         return 'gem'
  470.     return P
  471.  
  472.  
  473. def placeBomb(board, P):
  474.     pos = (toBoard(P[RECT].centerx), toBoard(P[RECT].centery)) # tuple of board coords
  475.     board[toBoard(P[RECT].centerx)][toBoard(P[RECT].centery)] = BOMB
  476.     bombValues = {'coords': pos, 'placeTime': time.time(), 'whoPlaced': P}
  477.     P[BOMBSPLACED] += 1
  478.     return (board, bombValues, P)
  479.  
  480.  
  481. def explodeBombs(board, bombs, P1, P2):
  482.     for bomb in bombs[:]:
  483.         if time.time() - FUSELENGTH > bomb['placeTime']:
  484.             if not muted: explosionSound.play()
  485.             bombx, bomby = bomb['coords']
  486.             x = y = True
  487.             if bombx > XCELLNUM - 3: x = False
  488.             if bomby > YCELLNUM - 3: y = False  # these variables check if explosion is outside board
  489.             if board[bombx - 1][bomby    ] not in (ROCK, BOMB, GEM): board[bombx - 1][bomby    ] = FIRE
  490.             if y and board[bombx    ][bomby + 1] not in (ROCK, BOMB, GEM): board[bombx    ][bomby + 1] = FIRE
  491.             if x and board[bombx + 1][bomby    ] not in (ROCK, BOMB, GEM): board[bombx + 1][bomby    ] = FIRE
  492.             if board[bombx    ][bomby - 1] not in (ROCK, BOMB, GEM): board[bombx    ][bomby - 1] = FIRE
  493.             if board[bombx - 1][bomby - 1] not in (ROCK, BOMB, GEM): board[bombx - 1][bomby - 1] = FIRE
  494.             if x and y and board[bombx + 1][bomby + 1] not in (ROCK, BOMB, GEM): board[bombx + 1][bomby + 1] = FIRE
  495.             if x and board[bombx + 1][bomby - 1] not in (ROCK, BOMB, GEM): board[bombx + 1][bomby - 1] = FIRE
  496.             if y and board[bombx - 1][bomby + 1] not in (ROCK, BOMB, GEM): board[bombx - 1][bomby + 1] = FIRE
  497.             if board[bombx - 2][bomby    ] not in (ROCK, BOMB, GEM): board[bombx - 2][bomby    ] = FIRE
  498.             if y and board[bombx    ][bomby + 2] not in (ROCK, BOMB, GEM): board[bombx    ][bomby + 2] = FIRE
  499.             if x and board[bombx + 2][bomby    ] not in (ROCK, BOMB, GEM): board[bombx + 2][bomby    ] = FIRE
  500.             if board[bombx    ][bomby - 2] not in (ROCK, BOMB, GEM): board[bombx    ][bomby - 2] = FIRE
  501.             board[bombx][bomby] = FIRE
  502.             if bomb['whoPlaced'] == P1:
  503.                 P1[BOMBSPLACED] -= 1
  504.             elif bomb['whoPlaced'] == P2:
  505.                 P2[BOMBSPLACED] -= 1
  506.             bombs.remove(bomb)
  507.     return (board, bombs)
  508.  
  509.  
  510. def generateTerrain():
  511.     checkForQuit()
  512.     board = [] # Create data structure
  513.     for x in range(XCELLNUM):
  514.         column = []
  515.         for y in range(YCELLNUM):
  516.             if y <= SKYGAP:
  517.                 column.append(AIR)
  518.             if y == GRASSLAYER:
  519.                 column.append(GRASS)
  520.             if y > GRASSLAYER:
  521.                 randblock = random.choice([DIRT, DIRT, ROCK])
  522.                 column.append(randblock)
  523.         board.append(column)
  524.     for i in range(NUMGEMS):
  525.         board[random.randint(3, XCELLNUM - 2)][random.randint(int(YCELLNUM / 2), YCELLNUM - 4)] = GEM
  526.  
  527.     return board
  528.  
  529.  
  530. def drawBoard(board, P1, P2, P1score, P2score, isFirstTime=False):
  531.     DISPLAYSURF.fill(BGCOLOUR)
  532.     pygame.draw.rect(DISPLAYSURF, SKYCOLOUR, (0, 0, WINDOWWIDTH, (SKYGAP + 1) * CELLSIZE), 0)
  533.     # draw blocks
  534.     for cellx in range(len(board)):
  535.         for celly in range(len(board[0])):
  536.             if board[cellx][celly] != 0:
  537.                 board[cellx][celly] = drawCell(cellx, celly, board[cellx][celly])
  538.     # draw objects
  539.     drawObjects(P1, P2)
  540.     if isFirstTime:
  541.         P1Label = BASICFONT.render('P1', 1, DARKGREY)
  542.         P1LabelRect = P1Label.get_rect()
  543.         P1LabelRect.midbottom = (P1[RECT].centerx, P1[RECT].top - 5)
  544.         P2Label = BASICFONT.render('P2', 1, DARKGREY)
  545.         P2LabelRect = P2Label.get_rect()
  546.         P2LabelRect.midbottom = (P2[RECT].centerx, P2[RECT].top - 5)
  547.         DISPLAYSURF.blit(P1Label, P1LabelRect)
  548.         DISPLAYSURF.blit(P2Label, P2LabelRect)
  549.     # draw lives
  550.     for i in range(1, P1[LIVES] + 1):
  551.         pos = Rect(2 + (i * 20), 5, CELLSIZE, CELLSIZE)
  552.         DISPLAYSURF.blit(redPlayerRight, pos)
  553.     for i in range(2, P2[LIVES] + 2):
  554.         pos2 = Rect(WINDOWWIDTH - (2 + (i * 20)), 5, CELLSIZE, CELLSIZE)
  555.         DISPLAYSURF.blit(bluePlayerLeft, pos2)
  556.     # draw scores
  557.     P1scoreSurf = BASICFONT.render(str(P1score), 1, DARKGREY)
  558.     P1scoreRect = P1scoreSurf.get_rect()
  559.     P1scoreRect.topleft = (5, 5)
  560.     DISPLAYSURF.blit(P1scoreSurf, P1scoreRect)
  561.    
  562.     P2scoreSurf = BASICFONT.render(str(P2score), 1, DARKGREY)
  563.     P2scoreRect = P2scoreSurf.get_rect()
  564.     P2scoreRect.topright = (WINDOWWIDTH - 5, 5)
  565.     DISPLAYSURF.blit(P2scoreSurf, P2scoreRect)
  566.  
  567.  
  568. def drawObjects(P1, P2):
  569.     # draw players
  570.     DISPLAYSURF.blit(P1[SURF], P1[RECT]) # P1
  571.     DISPLAYSURF.blit(P2[SURF], P2[RECT]) # P2
  572.  
  573.    
  574. def drawCell(cellx, celly, block):
  575.     # blocks only, not players
  576.     left, top = boardToPixels(cellx, celly)
  577.     if block == DIRT:
  578.         dirtRect = dirtImg.get_rect()
  579.         dirtRect.topleft = (left, top)
  580.         DISPLAYSURF.blit(dirtImg, dirtRect)
  581.         return DIRT
  582.     elif block == ROCK:
  583.         rockRect = rockImg.get_rect()
  584.         rockRect.topleft = (left, top)
  585.         DISPLAYSURF.blit(rockImg, rockRect)
  586.         return ROCK
  587.     elif block == GRASS:
  588.         grassRect = grassImg.get_rect()
  589.         grassRect.topleft = (left, top)
  590.         DISPLAYSURF.blit(grassImg, grassRect)
  591.         return GRASS
  592.     elif block == GEM:
  593.         gemRect = gemImg.get_rect()
  594.         gemRect.topleft = (left, top)
  595.         DISPLAYSURF.blit(gemImg, gemRect)
  596.         return GEM
  597.     elif block == BOMB:
  598.         bombRect = bombImg.get_rect()
  599.         bombRect.topleft = (left, top)
  600.         DISPLAYSURF.blit(bombImg, bombRect)
  601.         return BOMB
  602.     elif block == FIRE:
  603.         fireRect = fireImg.get_rect()
  604.         fireRect.topleft = (left, top)
  605.         DISPLAYSURF.blit(fireImg, fireRect)
  606.         if random.randint(0, 20) > 18: return AIR  # fire goes out, becomes air
  607.         return FIRE
  608.  
  609.  
  610. def drawDebug(board, P1, P2):
  611.     P1ground, P2ground = isOnGround(board, P1[RECT]), isOnGround(board, P2[RECT])
  612.     P1x, P1y = pixelsToBoard(P1[RECT].center)
  613.  
  614.     debugText = BASICFONT.render("P1 midbottom: %s, P1 bottomright %s, P1 dir: %s, P2 dir: %s" \
  615.         %(P1[RECT].midbottom, P1[RECT].bottomright, P1[DIRECTION], P2[DIRECTION]), 1, WHITE)
  616.     debugText2 = BASICFONT.render("P1 onGround = %s, P2 onGround = %s, board[P1x][P1y+1]: %s" %(P1ground, P2ground, board[P1x][P1y+1]), 1, WHITE)
  617.     debugText3 = BASICFONT.render("P1 board coords: %s, P2 board coords: %s, P1 vel: %s, P2 vel %s" \
  618.         %(pixelsToBoard(P1[RECT].center), pixelsToBoard(P2[RECT].center), P1[VELOCITY], P2[VELOCITY]), 1, WHITE)
  619.     DISPLAYSURF.blit(debugText, (0, 300))
  620.     DISPLAYSURF.blit(debugText2, (0, 320))
  621.     DISPLAYSURF.blit(debugText3, (0, 340))
  622.  
  623.  
  624. def boardToPixels(cellX, cellY):
  625.     # !! returns TOP LEFT point of cell !!
  626.     left = (cellX * CELLSIZE)
  627.     top = (cellY * CELLSIZE)
  628.     return [left, top]
  629.  
  630.  
  631. def pixelsToBoard(coords):
  632.     # returns cell that x and y pixel is in when passed (x, y).
  633.     pixX, pixY = coords
  634.     return [int(pixX / CELLSIZE), int(pixY / CELLSIZE)]
  635.  
  636.  
  637. def toBoard(coord):
  638.     # same as pixelsToBoard() but takes a single coord
  639.     return (int(coord / CELLSIZE))
  640.  
  641.  
  642. def isOnGround(board, rect):
  643.     if rect.bottom % 20 != 0: #if not on a horizontal gridline return False
  644.         return False
  645.     x, y = pixelsToBoard((rect.centerx, rect.bottom - 1))
  646.     if board[x][y+1] not in (AIR, FIRE, GEM):
  647.         return True
  648.     return False
  649.  
  650.  
  651. def checkForKeyPress():
  652.     checkForQuit()
  653.  
  654.     keyUpEvents = pygame.event.get(KEYUP)
  655.     if len(keyUpEvents) == 0:
  656.         return False
  657.     return True
  658.  
  659.  
  660. def checkForQuit():
  661.     for event in pygame.event.get(QUIT): # get all the QUIT events
  662.         terminate() # terminate if any QUIT events are present
  663.     for event in pygame.event.get(KEYUP): # get all the KEYUP events
  664.         if event.key == K_ESCAPE:
  665.             terminate() # terminate if the KEYUP event was for the Esc key
  666.         pygame.event.post(event) # put the other KEYUP event objects back
  667.  
  668.  
  669. def terminate():
  670.     pygame.quit()
  671.     sys.exit()
  672.  
  673.  
  674. if __name__ == '__main__':
  675.     main()
Advertisement
Add Comment
Please, Sign In to add comment