做爰高潮a片〈毛片〉,尤物av天堂一区二区在线观看,一本久久A久久精品VR综合,添女人荫蒂全部过程av

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實例

來源:懂視網 責編:小采 時間:2020-11-27 14:35:00
文檔

Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實例

Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實例:文章先介紹了關于俄羅斯方塊游戲的幾個術語。 邊框——由10*20個空格組成,方塊就落在這里面。 盒子——組成方塊的其中小方塊,是組成方塊的基本單元。 方塊——從邊框頂掉下的東西,游戲者可以翻轉和改變位置。每個方塊由4個盒子組成。 形狀——不同類型的
推薦度:
導讀Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實例:文章先介紹了關于俄羅斯方塊游戲的幾個術語。 邊框——由10*20個空格組成,方塊就落在這里面。 盒子——組成方塊的其中小方塊,是組成方塊的基本單元。 方塊——從邊框頂掉下的東西,游戲者可以翻轉和改變位置。每個方塊由4個盒子組成。 形狀——不同類型的
文章先介紹了關于俄羅斯方塊游戲的幾個術語。

  • 邊框——由10*20個空格組成,方塊就落在這里面。
  • 盒子——組成方塊的其中小方塊,是組成方塊的基本單元。
  • 方塊——從邊框頂掉下的東西,游戲者可以翻轉和改變位置。每個方塊由4個盒子組成。
  • 形狀——不同類型的方塊。這里形狀的名字被叫做T, S, Z ,J, L, I , O。如下圖所示:
  • 2015128143118229.png (490×159)

    模版——用一個列表存放形狀被翻轉后的所有可能樣式。全部存放在變量里,變量名字如S_SHAPE_TEMPLATE or J_SHAPE_TEMPLATE
    著陸——當一個方塊到達邊框的底部或接觸到在其他的盒子話,我們就說這個方塊著陸了。那樣的話,另一個方塊就會開始下落。
    下面先把代碼敲一遍,試著了解作者意圖,體會俄羅斯方塊游戲的制作過程。

    import random, time, pygame, sys 
    from pygame.locals import * 
     
    FPS = 25 
    WINDOWWIDTH = 640 
    WINDOWHEIGHT = 480 
    BOXSIZE = 20 
    BOARDWIDTH = 10 
    BOARDHEIGHT = 20 
    BLANK = '.' 
     
    MOVESIDEWAYSFREQ = 0.15 
    MOVEDOWNFREQ = 0.1 
     
    XMARGIN = int((WINDOWWIDTH - BOARDWIDTH * BOXSIZE) / 2) 
    TOPMARGIN = WINDOWHEIGHT - (BOARDHEIGHT * BOXSIZE) - 5 
    # R G B 
    WHITE = (255, 255, 255) 
    GRAY = (185, 185, 185) 
    BLACK = ( 0, 0, 0) 
    RED = (155, 0, 0) 
    LIGHTRED = (175, 20, 20) 
    GREEN = ( 0, 155, 0) 
    LIGHTGREEN = ( 20, 175, 20) 
    BLUE = ( 0, 0, 155) 
    LIGHTBLUE = ( 20, 20, 175) 
    YELLOW = (155, 155, 0) 
    LIGHTYELLOW = (175, 175, 20) 
     
    BORDERCOLOR = BLUE 
    BGCOLOR = BLACK 
    TEXTCOLOR = WHITE 
    TEXTSHADOWCOLOR = GRAY 
    COLORS = ( BLUE, GREEN, RED, YELLOW) 
    LIGHTCOLORS = (LIGHTBLUE, LIGHTGREEN, LIGHTRED, LIGHTYELLOW) 
    assert len(COLORS) == len(LIGHTCOLORS) # each color must have light color 
     
    TEMPLATEWIDTH = 5 
    TEMPLATEHEIGHT = 5 
     
    S_SHAPE_TEMPLATE = [['.....', 
     '.....', 
     '..OO.', 
     '.OO..', 
     '.....'], 
     ['.....', 
     '..O..', 
     '..OO.', 
     '...O.', 
     '.....']] 
     
    Z_SHAPE_TEMPLATE = [['.....', 
     '.....', 
     '.OO..', 
     '..OO.', 
     '.....'], 
     ['.....', 
     '..O..', 
     '.OO..', 
     '.O...', 
     '.....']] 
     
    I_SHAPE_TEMPLATE = [['..O..', 
     '..O..', 
     '..O..', 
     '..O..', 
     '.....'], 
     ['.....', 
     '.....', 
     'OOOO.', 
     '.....', 
     '.....']] 
     
    O_SHAPE_TEMPLATE = [['.....', 
     '.....', 
     '.OO..', 
     '.OO..', 
     '.....']] 
     
    J_SHAPE_TEMPLATE = [['.....', 
     '.O...', 
     '.OOO.', 
     '.....', 
     '.....'], 
     ['.....', 
     '..OO.', 
     '..O..', 
     '..O..', 
     '.....'], 
     ['.....', 
     '.....', 
     '.OOO.', 
     '...O.', 
     '.....'], 
     ['.....', 
     '..O..', 
     '..O..', 
     '.OO..', 
     '.....']] 
     
    L_SHAPE_TEMPLATE = [['.....', 
     '...O.', 
     '.OOO.', 
     '.....', 
     '.....'], 
     ['.....', 
     '..O..', 
     '..O..', 
     '..OO.', 
     '.....'], 
     ['.....', 
     '.....', 
     '.OOO.', 
     '.O...', 
     '.....'], 
     ['.....', 
     '.OO..', 
     '..O..', 
     '..O..', 
     '.....']] 
     
    T_SHAPE_TEMPLATE = [['.....', 
     '..O..', 
     '.OOO.', 
     '.....', 
     '.....'], 
     ['.....', 
     '..O..', 
     '..OO.', 
     '..O..', 
     '.....'], 
     ['.....', 
     '.....', 
     '.OOO.', 
     '..O..', 
     '.....'], 
     ['.....', 
     '..O..', 
     '.OO..', 
     '..O..', 
     '.....']] 
     
    PIECES = {'S': S_SHAPE_TEMPLATE, 
     'Z': Z_SHAPE_TEMPLATE, 
     'J': J_SHAPE_TEMPLATE, 
     'L': L_SHAPE_TEMPLATE, 
     'I': I_SHAPE_TEMPLATE, 
     'O': O_SHAPE_TEMPLATE, 
     'T': T_SHAPE_TEMPLATE} 
     
     
    def main(): 
     global FPSCLOCK, DISPLAYSURF, BASICFONT, BIGFONT 
     pygame.init() 
     FPSCLOCK = pygame.time.Clock() 
     DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) 
     BASICFONT = pygame.font.Font('freesansbold.ttf', 18) 
     BIGFONT = pygame.font.Font('freesansbold.ttf', 100) 
     pygame.display.set_caption('Tetromino') 
     
     showTextScreen('Tetromino') 
     while True: # game loop 
     if random.randint(0, 1) == 0: 
     pygame.mixer.music.load('tetrisb.mid') 
     else: 
     pygame.mixer.music.load('tetrisc.mid') 
     pygame.mixer.music.play(-1, 0.0) 
     runGame() 
     pygame.mixer.music.stop() 
     showTextScreen('Game Over') 
     
     
    def runGame(): 
     # setup variables for the start of the game 
     board = getBlankBoard() 
     lastMoveDownTime = time.time() 
     lastMoveSidewaysTime = time.time() 
     lastFallTime = time.time() 
     movingDown = False # note: there is no movingUp variable 
     movingLeft = False 
     movingRight = False 
     score = 0 
     level, fallFreq = calculateLevelAndFallFreq(score) 
     
     fallingPiece = getNewPiece() 
     nextPiece = getNewPiece() 
     
     while True: # game loop 
     if fallingPiece == None: 
     # No falling piece in play, so start a new piece at the top 
     fallingPiece = nextPiece 
     nextPiece = getNewPiece() 
     lastFallTime = time.time() # reset lastFallTime 
     
     if not isValidPosition(board, fallingPiece): 
     return # can't fit a new piece on the board, so game over 
     
     checkForQuit() 
     for event in pygame.event.get(): # event handling loop 
     if event.type == KEYUP: 
     if (event.key == K_p): 
     # Pausing the game 
     DISPLAYSURF.fill(BGCOLOR) 
     pygame.mixer.music.stop() 
     showTextScreen('Paused') # pause until a key press 
     pygame.mixer.music.play(-1, 0.0) 
     lastFallTime = time.time() 
     lastMoveDownTime = time.time() 
     lastMoveSidewaysTime = time.time() 
     elif (event.key == K_LEFT or event.key == K_a): 
     movingLeft = False 
     elif (event.key == K_RIGHT or event.key == K_d): 
     movingRight = False 
     elif (event.key == K_DOWN or event.key == K_s): 
     movingDown = False 
     
     elif event.type == KEYDOWN: 
     # moving the piece sideways 
     if (event.key == K_LEFT or event.key == K_a) and isValidPosition(board, fallingPiece, adjX=-1): 
     fallingPiece['x'] -= 1 
     movingLeft = True 
     movingRight = False 
     lastMoveSidewaysTime = time.time() 
     
     elif (event.key == K_RIGHT or event.key == K_d) and isValidPosition(board, fallingPiece, adjX=1): 
     fallingPiece['x'] += 1 
     movingRight = True 
     movingLeft = False 
     lastMoveSidewaysTime = time.time() 
     
     # rotating the piece (if there is room to rotate) 
     elif (event.key == K_UP or event.key == K_w): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) 
     if not isValidPosition(board, fallingPiece): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) 
     elif (event.key == K_q): # rotate the other direction 
     fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) 
     if not isValidPosition(board, fallingPiece): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) 
     
     # making the piece fall faster with the down key 
     elif (event.key == K_DOWN or event.key == K_s): 
     movingDown = True 
     if isValidPosition(board, fallingPiece, adjY=1): 
     fallingPiece['y'] += 1 
     lastMoveDownTime = time.time() 
     
     # move the current piece all the way down 
     elif event.key == K_SPACE: 
     movingDown = False 
     movingLeft = False 
     movingRight = False 
     for i in range(1, BOARDHEIGHT): 
     if not isValidPosition(board, fallingPiece, adjY=i): 
     break 
     fallingPiece['y'] += i - 1 
     
     # handle moving the piece because of user input 
     if (movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ: 
     if movingLeft and isValidPosition(board, fallingPiece, adjX=-1): 
     fallingPiece['x'] -= 1 
     elif movingRight and isValidPosition(board, fallingPiece, adjX=1): 
     fallingPiece['x'] += 1 
     lastMoveSidewaysTime = time.time() 
     
     if movingDown and time.time() - lastMoveDownTime > MOVEDOWNFREQ and isValidPosition(board, fallingPiece, adjY=1): 
     fallingPiece['y'] += 1 
     lastMoveDownTime = time.time() 
     
     # let the piece fall if it is time to fall 
     if time.time() - lastFallTime > fallFreq: 
     # see if the piece has landed 
     if not isValidPosition(board, fallingPiece, adjY=1): 
     # falling piece has landed, set it on the board 
     addToBoard(board, fallingPiece) 
     score += removeCompleteLines(board) 
     level, fallFreq = calculateLevelAndFallFreq(score) 
     fallingPiece = None 
     else: 
     # piece did not land, just move the piece down 
     fallingPiece['y'] += 1 
     lastFallTime = time.time() 
     
     # drawing everything on the screen 
     DISPLAYSURF.fill(BGCOLOR) 
     drawBoard(board) 
     drawStatus(score, level) 
     drawNextPiece(nextPiece) 
     if fallingPiece != None: 
     drawPiece(fallingPiece) 
     
     pygame.display.update() 
     FPSCLOCK.tick(FPS) 
     
     
    def makeTextObjs(text, font, color): 
     surf = font.render(text, True, color) 
     return surf, surf.get_rect() 
     
     
    def terminate(): 
     pygame.quit() 
     sys.exit() 
     
     
    def checkForKeyPress(): 
     # Go through event queue looking for a KEYUP event. 
     # Grab KEYDOWN events to remove them from the event queue. 
     checkForQuit() 
     
     for event in pygame.event.get([KEYDOWN, KEYUP]): 
     if event.type == KEYDOWN: 
     continue 
     return event.key 
     return None 
     
     
    def showTextScreen(text): 
     # This function displays large text in the 
     # center of the screen until a key is pressed. 
     # Draw the text drop shadow 
     titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTSHADOWCOLOR) 
     titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2)) 
     DISPLAYSURF.blit(titleSurf, titleRect) 
     
     # Draw the text 
     titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR) 
     titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3) 
     DISPLAYSURF.blit(titleSurf, titleRect) 
     
     # Draw the additional "Press a key to play." text. 
     pressKeySurf, pressKeyRect = makeTextObjs('Press a key to play.', BASICFONT, TEXTCOLOR) 
     pressKeyRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 100) 
     DISPLAYSURF.blit(pressKeySurf, pressKeyRect) 
     
     while checkForKeyPress() == None: 
     pygame.display.update() 
     FPSCLOCK.tick() 
     
     
    def checkForQuit(): 
     for event in pygame.event.get(QUIT): # get all the QUIT events 
     terminate() # terminate if any QUIT events are present 
     for event in pygame.event.get(KEYUP): # get all the KEYUP events 
     if event.key == K_ESCAPE: 
     terminate() # terminate if the KEYUP event was for the Esc key 
     pygame.event.post(event) # put the other KEYUP event objects back 
     
     
    def calculateLevelAndFallFreq(score): 
     # Based on the score, return the level the player is on and 
     # how many seconds pass until a falling piece falls one space. 
     level = int(score / 10) + 1 
     fallFreq = 0.27 - (level * 0.02) 
     return level, fallFreq 
     
    def getNewPiece(): 
     # return a random new piece in a random rotation and color 
     shape = random.choice(list(PIECES.keys())) 
     newPiece = {'shape': shape, 
     'rotation': random.randint(0, len(PIECES[shape]) - 1), 
     'x': int(BOARDWIDTH / 2) - int(TEMPLATEWIDTH / 2), 
     'y': -2, # start it above the board (i.e. less than 0) 
     'color': random.randint(0, len(COLORS)-1)} 
     return newPiece 
     
     
    def addToBoard(board, piece): 
     # fill in the board based on piece's location, shape, and rotation 
     for x in range(TEMPLATEWIDTH): 
     for y in range(TEMPLATEHEIGHT): 
     if PIECES[piece['shape']][piece['rotation']][y][x] != BLANK: 
     board[x + piece['x']][y + piece['y']] = piece['color'] 
     
     
    def getBlankBoard(): 
     # create and return a new blank board data structure 
     board = [] 
     for i in range(BOARDWIDTH): 
     board.append([BLANK] * BOARDHEIGHT) 
     return board 
     
     
    def isOnBoard(x, y): 
     return x >= 0 and x < BOARDWIDTH and y < BOARDHEIGHT 
     
     
    def isValidPosition(board, piece, adjX=0, adjY=0): 
     # Return True if the piece is within the board and not colliding 
     for x in range(TEMPLATEWIDTH): 
     for y in range(TEMPLATEHEIGHT): 
     isAboveBoard = y + piece['y'] + adjY < 0 
     if isAboveBoard or PIECES[piece['shape']][piece['rotation']][y][x] == BLANK: 
     continue 
     if not isOnBoard(x + piece['x'] + adjX, y + piece['y'] + adjY): 
     return False 
     if board[x + piece['x'] + adjX][y + piece['y'] + adjY] != BLANK: 
     return False 
     return True 
     
    def isCompleteLine(board, y): 
     # Return True if the line filled with boxes with no gaps. 
     for x in range(BOARDWIDTH): 
     if board[x][y] == BLANK: 
     return False 
     return True 
     
     
    def removeCompleteLines(board): 
     # Remove any completed lines on the board, move everything above them down, and return the number of complete lines. 
     numLinesRemoved = 0 
     y = BOARDHEIGHT - 1 # start y at the bottom of the board 
     while y >= 0: 
     if isCompleteLine(board, y): 
     # Remove the line and pull boxes down by one line. 
     for pullDownY in range(y, 0, -1): 
     for x in range(BOARDWIDTH): 
     board[x][pullDownY] = board[x][pullDownY-1] 
     # Set very top line to blank. 
     for x in range(BOARDWIDTH): 
     board[x][0] = BLANK 
     numLinesRemoved += 1 
     # Note on the next iteration of the loop, y is the same. 
     # This is so that if the line that was pulled down is also 
     # complete, it will be removed. 
     else: 
     y -= 1 # move on to check next row up 
     return numLinesRemoved 
     
     
    def convertToPixelCoords(boxx, boxy): 
     # Convert the given xy coordinates of the board to xy 
     # coordinates of the location on the screen. 
     return (XMARGIN + (boxx * BOXSIZE)), (TOPMARGIN + (boxy * BOXSIZE)) 
     
     
    def drawBox(boxx, boxy, color, pixelx=None, pixely=None): 
     # draw a single box (each tetromino piece has four boxes) 
     # at xy coordinates on the board. Or, if pixelx & pixely 
     # are specified, draw to the pixel coordinates stored in 
     # pixelx & pixely (this is used for the "Next" piece). 
     if color == BLANK: 
     return 
     if pixelx == None and pixely == None: 
     pixelx, pixely = convertToPixelCoords(boxx, boxy) 
     pygame.draw.rect(DISPLAYSURF, COLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 1, BOXSIZE - 1)) 
     pygame.draw.rect(DISPLAYSURF, LIGHTCOLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 4, BOXSIZE - 4)) 
     
     
    def drawBoard(board): 
     # draw the border around the board 
     pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (XMARGIN - 3, TOPMARGIN - 7, (BOARDWIDTH * BOXSIZE) + 8, (BOARDHEIGHT * BOXSIZE) + 8), 5) 
     
     # fill the background of the board 
     pygame.draw.rect(DISPLAYSURF, BGCOLOR, (XMARGIN, TOPMARGIN, BOXSIZE * BOARDWIDTH, BOXSIZE * BOARDHEIGHT)) 
     # draw the individual boxes on the board 
     for x in range(BOARDWIDTH): 
     for y in range(BOARDHEIGHT): 
     drawBox(x, y, board[x][y]) 
     
     
    def drawStatus(score, level): 
     # draw the score text 
     scoreSurf = BASICFONT.render('Score: %s' % score, True, TEXTCOLOR) 
     scoreRect = scoreSurf.get_rect() 
     scoreRect.topleft = (WINDOWWIDTH - 150, 20) 
     DISPLAYSURF.blit(scoreSurf, scoreRect) 
     
     # draw the level text 
     levelSurf = BASICFONT.render('Level: %s' % level, True, TEXTCOLOR) 
     levelRect = levelSurf.get_rect() 
     levelRect.topleft = (WINDOWWIDTH - 150, 50) 
     DISPLAYSURF.blit(levelSurf, levelRect) 
     
     
    def drawPiece(piece, pixelx=None, pixely=None): 
     shapeToDraw = PIECES[piece['shape']][piece['rotation']] 
     if pixelx == None and pixely == None: 
     # if pixelx & pixely hasn't been specified, use the location stored in the piece data structure 
     pixelx, pixely = convertToPixelCoords(piece['x'], piece['y']) 
     
     # draw each of the boxes that make up the piece 
     for x in range(TEMPLATEWIDTH): 
     for y in range(TEMPLATEHEIGHT): 
     if shapeToDraw[y][x] != BLANK: 
     drawBox(None, None, piece['color'], pixelx + (x * BOXSIZE), pixely + (y * BOXSIZE)) 
     
     
    def drawNextPiece(piece): 
     # draw the "next" text 
     nextSurf = BASICFONT.render('Next:', True, TEXTCOLOR) 
     nextRect = nextSurf.get_rect() 
     nextRect.topleft = (WINDOWWIDTH - 120, 80) 
     DISPLAYSURF.blit(nextSurf, nextRect) 
     # draw the "next" piece 
     drawPiece(piece, pixelx=WINDOWWIDTH-120, pixely=100) 
     
     
    if __name__ == '__main__': 
     main() 
    
    

    代碼一開始仍是一些變量的初始化,我們這里還加載了time模塊,后面會用到。BOXSIZE, BOARDWIDTH, BOARDHEIGHT與前面貪吃蛇相關初始化類似,使其與屏幕像素點聯系起來。

    MOVESIDEWAYSFREQ = 0.15
    MOVEDOWNFREQ = 0.1
    

    這兩個變量的作用是這樣的,每當游戲者按下左鍵或右鍵,下降的方塊相應的向左或右移一個格子。然而游戲者也可以一直按下方向左鍵或右鍵讓方塊保持移動。MOVESIDEWAYSFREQ這個固定值表示如果一直按下方向左鍵或右鍵那么每0.15秒方塊才會繼續移動。
    MOVEDOWNFREQ 這個固定值與上面的是一樣的除了它是告訴當游戲者一直按下方向下鍵時方塊下落的頻率。

    XMARGIN = int((WINDOWWIDTH - BOARDWIDTH * BOXSIZE) / 2)
    TOPMARGIN = WINDOWHEIGHT - (BOARDHEIGHT * BOXSIZE) - 5
    

    這兩句的意思就看下面這個圖就明白了。

    2015128143232882.png (477×389)

    然后是一些顏色值的定義。其中要注意的是COLORS和LIGHTCOLORS,COLORS是組成方塊的小方塊的顏色,而LIGHTCOLORS是圍繞在小方塊周圍的顏色,為了強調出輪廓而設計的。
    接著是定義方塊了。游戲必須知道每個類型的方塊有多少種形狀,在這里我們用在列表中嵌入含有字符串的列表來構成這個模版,一個方塊類型的模版含有了這個方塊可能變換的所有形狀。比如I的模版如下:

    I_SHAPE_TEMPLATE = [['..O..', 
     '..O..', 
     '..O..', 
     '..O..', 
     '.....'], 
     ['.....', 
     '.....', 
     'OOOO.', 
     '.....', 
     '.....']] 
    

    TEMPLATEWIDTH = 5和TEMPLATEHEIGHT = 5則表示組成形狀的行和列,如下圖所示:

    2015128143252602.png (316×322)

    在看這段定義。

    PIECES = {'S': S_SHAPE_TEMPLATE, 
     'Z': Z_SHAPE_TEMPLATE, 
     'J': J_SHAPE_TEMPLATE, 
     'L': L_SHAPE_TEMPLATE, 
     'I': I_SHAPE_TEMPLATE, 
     'O': O_SHAPE_TEMPLATE, 
     'T': T_SHAPE_TEMPLATE} 
    

    PIECES這個變量是一個字典,里面儲存了所有的不同模版。因為每個又有一個類型的方塊的所有變換形狀。那就意味著PIECES變量包含了每個類型的方塊和所有的的變換形狀。這就是存放我們游戲中用到的形狀的數據結構。(又加強了對字典的理解)
    主函數main()
    主函數的前部分主要是創建一些全局變量和在游戲開始之前顯示一個開始畫面。

    while True: # game loop 
     if random.randint(0, 1) == 0: 
     pygame.mixer.music.load('tetrisb.mid') 
     else: 
     pygame.mixer.music.load('tetrisc.mid') 
     pygame.mixer.music.play(-1, 0.0) 
     runGame() 
     pygame.mixer.music.stop() 
     showTextScreen('Game Over') 
    
    

    上面這段代碼中runGame()是程序的核心部分。循環中首先簡單的隨機決定采用哪個背景音樂。然后調用runGame(),當游戲失敗,runGame()就會返回到main()函數,這時會停止背景音樂和顯示游戲失敗的畫面。
    當游戲者按下一個鍵,showTextScreen()顯示游戲失敗的函數就會返回。游戲循環會再次開始然后繼續下一次游戲。
    runGame()

    def runGame(): 
     # setup variables for the start of the game 
     board = getBlankBoard() 
     lastMoveDownTime = time.time() 
     lastMoveSidewaysTime = time.time() 
     lastFallTime = time.time() 
     movingDown = False # note: there is no movingUp variable 
     movingLeft = False 
     movingRight = False 
     score = 0 
     level, fallFreq = calculateLevelAndFallFreq(score) 
     
     fallingPiece = getNewPiece() 
     nextPiece = getNewPiece() 
    
    

    在游戲開始和方塊掉落之前,我們需要初始化一些跟游戲開始相關的變量。fallingPiece變量被賦值成當前掉落的變量,nextPiece變量被賦值成游戲者可以在屏幕NEXT區域看見的下一個方塊。

    while True: # game loop 
     if fallingPiece == None: 
     # No falling piece in play, so start a new piece at the top 
     fallingPiece = nextPiece 
     nextPiece = getNewPiece() 
     lastFallTime = time.time() # reset lastFallTime 
     
     if not isValidPosition(board, fallingPiece): 
     return # can't fit a new piece on the board, so game over 
     
     checkForQuit() 
    
    

    這部分包含了當方塊往底部掉落時的的所有代碼。fallingPiece變量在方塊著陸后被設置成None。這意味著nextPiece變量中的下一個方塊應該被賦值給fallingPiece變量,然后一個隨機的方塊又會被賦值給nextPiece變量。lastFallTime變量也被賦值成當前時間,這樣我們就可以通過fallFreq變量控制方塊下落的頻率。
    來自getNewPiece函數的方塊只有一部分被放置在方框區域中。但是如果這是一個非法的位置,比如此時游戲方框已經被填滿(isVaildPostion()函數返回False),那么我們就知道方框已經滿了,游戲者輸掉了游戲。當這些發生時,runGame()函數就會返回。
    事件處理循環
    事件循環主要處理當翻轉方塊,移動方塊時或者暫停游戲時的一些事情。
    暫停游戲

    if (event.key == K_p): 
     # Pausing the game 
     DISPLAYSURF.fill(BGCOLOR) 
     pygame.mixer.music.stop() 
     showTextScreen('Paused') # pause until a key press 
     pygame.mixer.music.play(-1, 0.0) 
     lastFallTime = time.time() 
     lastMoveDownTime = time.time() 
     lastMoveSidewaysTime = time.time() 
    
    

    如果游戲者按下P鍵,游戲就會暫停。我們應該隱藏掉游戲界面以防止游戲者作弊(否則游戲者會看著畫面思考怎么處理方塊),用DISPLAYSURF.fill(BGCOLOR)就可以實現這個效果。注意的是我們還要保存一些時間變量值。

    elif (event.key == K_LEFT or event.key == K_a): 
     movingLeft = False 
    elif (event.key == K_RIGHT or event.key == K_d): 
     movingRight = False 
    elif (event.key == K_DOWN or event.key == K_s): 
     movingDown = False 
    
    

    停止按下方向鍵或ASD鍵會把moveLeft,moveRight,movingDown變量設置為False.,表明游戲者不再想要在此方向上移動方塊。后面的代碼會基于moving變量處理一些事情。注意的上方向鍵和W鍵是用來翻轉方塊的而不是移動方塊。這就是為什么沒有movingUp變量.

    elif event.type == KEYDOWN: 
     # moving the piece sideways 
     if (event.key == K_LEFT or event.key == K_a) and isValidPosition(board, fallingPiece, adjX=-1): 
     fallingPiece['x'] -= 1 
     movingLeft = True 
     movingRight = False 
     lastMoveSidewaysTime = time.time() 
    
    

    當左方向鍵按下(而且往左移動是有效的,通過調用isVaildPosition()函數知道的),那么我們應該改變一個方塊的位置使其向左移動一個通過讓rallingPiece['x']減1.isVaildPosition()函數有個參數選項是adjX和adjY.平常,isVaildPostion()函數檢查方塊的位置通過函數的第二個參數的傳遞。然而,有時我們不想檢查方塊當前的位置,而是偏離當前方向幾個格子的位置。
    比如adjX=-1,則表示向左移動一個格子后方塊的位置,為+1則表示向右移動一個格子后的位置。adjY同理如此。
    movingLeft變量會被設置為True,確保方塊不會向右移動,此時movingRight變量設置為False。同時需要更新lastMoveSidewaysTime的值。
    這個lastMoveSidewaysTime變量設置的原因是這樣。因為游戲者有可能一直按著方向鍵讓其方塊移動。如果moveLeft被設置為True,程序就會知道方向左鍵已經被按下。如果在lastMoveSidewaysTime變量儲存的時間基礎上,0.15秒(儲存在MOVESIDEAYSFREQ變量中)過去后,那么此時程序就會將方塊再次向左移動一個格子。

    elif (event.key == K_UP or event.key == K_w): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) 
     if not isValidPosition(board, fallingPiece): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) 
    
    

    如果方向鍵上或W鍵被按下,那么就會翻轉方塊。上面的代碼做的就是將儲存在fallingPiece字典中的‘rotation'鍵的鍵值加1.然而,當增加的'rotation'鍵值大于所有當前類型方塊的形狀的數目的話(此變量儲存在len(SHAPES[fallingPiece['shape']])變量中),那么它翻轉到最初的形狀。

    if not isValidPosition(board, fallingPiece): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) 
    

    如果翻轉后的形狀無效因為其中的一些小方塊已經超過邊框的范圍,那么我們就要把它變回原來的形狀通過將fallingPiece['rotation')減去1.

    elif (event.key == K_q): # rotate the other direction 
     fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) 
     if not isValidPosition(board, fallingPiece): 
     fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) 
    
    

    這段代碼與上面之前的那段代碼是一個意思,不同的是這段代碼是當游戲者按下Q鍵時翻轉方塊朝相反的方向。這里我們減去1而不是加1.

    elif (event.key == K_DOWN or event.key == K_s): 
     movingDown = True 
     if isValidPosition(board, fallingPiece, adjY=1): 
     fallingPiece['y'] += 1 
     lastMoveDownTime = time.time() 
    

    如果下鍵被按下,游戲者此時希望方塊下降的比平常快。fallingPiece['y'] += 1使方塊下落一個格子(前提是這是一個有效的下落)moveDown被設置為True,lastMoceDownTime變量也被設置為當前時間。這個變量以后將被檢查當方向下鍵一直按下時從而保證方塊以一個比平常快的速率下降。

    elif event.key == K_SPACE: 
     movingDown = False 
     movingLeft = False 
     movingRight = False 
     for i in range(1, BOARDHEIGHT): 
     if not isValidPosition(board, fallingPiece, adjY=i): 
     break 
     fallingPiece['y'] += i - 1 
    

    當游戲者按下空格鍵,方塊將會迅速的下落至著陸。程序首先需要找出到它著陸需要下降個多少個格子。其中有關moving的三個變量都要被設置為False(保證程序后面部分的代碼知道游戲者已經停止了按下所有的方向鍵)。

    if (movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ: 
     if movingLeft and isValidPosition(board, fallingPiece, adjX=-1): 
     fallingPiece['x'] -= 1 
     elif movingRight and isValidPosition(board, fallingPiece, adjX=1): 
     fallingPiece['x'] += 1 
     lastMoveSidewaysTime = time.time() 
    

    這段代碼是處理一直按下某個方向鍵時的情況。
    如果用戶按住鍵超過0.15秒。那么表達式(movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ:返回True。這樣的話我們就可以移動方塊向左或向右移動一個格子。
    這個做法是很用的,因為如果用戶重復的按下方向鍵讓方塊移動多個格子是很煩人的。好的做法是,用戶可以按住方向鍵讓方塊保持移動直到松開鍵為止。最后別忘了更新lastMoveSideWaysTime變量。

    if movingDown and time.time() - lastMoveDownTime > MOVEDOWNFREQ and isValidPosition(board, fallingPiece, adjY=1): 
     fallingPiece['y'] += 1 
     lastMoveDownTime = time.time() 
    
    

    這段代碼的意思跟上面的代碼差不多。

    if time.time() - lastFallTime > fallFreq: 
     # see if the piece has landed 
     if not isValidPosition(board, fallingPiece, adjY=1): 
     # falling piece has landed, set it on the board 
     addToBoard(board, fallingPiece) 
     score += removeCompleteLines(board) 
     level, fallFreq = calculateLevelAndFallFreq(score) 
     fallingPiece = None 
     else: 
     # piece did not land, just move the piece down 
     fallingPiece['y'] += 1 
     lastFallTime = time.time() 
    
    

    方塊自然下落的速率由lastFallTime變量決定。如果自從上個方塊掉落了一個格子后過去了足夠的時間,那么上面代碼就會再讓方塊移動一個格子。

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實例

    Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實例:文章先介紹了關于俄羅斯方塊游戲的幾個術語。 邊框——由10*20個空格組成,方塊就落在這里面。 盒子——組成方塊的其中小方塊,是組成方塊的基本單元。 方塊——從邊框頂掉下的東西,游戲者可以翻轉和改變位置。每個方塊由4個盒子組成。 形狀——不同類型的
    推薦度:
    標簽: 游戲 代碼 模塊
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 嘉祥县| 永平县| 杂多县| 株洲县| 永寿县| 峡江县| 石楼县| 东城区| 淅川县| 祁东县| 荣成市| 台中县| 远安县| 宁陵县| 高邮市| 惠水县| 赤城县| 报价| 托里县| 宁夏| 白河县| 岐山县| 南充市| 天门市| 开封县| 宿迁市| 正蓝旗| 酉阳| 舟曲县| 福泉市| 松溪县| 介休市| 孟村| 屏山县| 招远市| 友谊县| 澎湖县| 海安县| 台中县| 贺州市| 姜堰市|