俄罗斯方块
来自网上,修改,供学习,不记得来自哪里,谢谢大神,如有侵权,请告知。
代码:
import random, time, pygame, sys from pygame.locals import * #Frame(画面、帧),p就是Per(每),s就是Second(秒) FPS = 25 #FPS=刷新率(单位为Hz),电影以每秒25张画面的速度播放 WINWIDTH = 1040 WINHEIGHT = 480 BOXSIZE = 20 BOARDWIDTH = 10 BOARDHEIGHT = 20 BLANK = '.' #表示空白空格 MOVESIDEWAYSFREQ = 0.1 MOVEDOWNFREQ = 0.1 XMARGIN = int((WINWIDTH - BOARDWIDTH * BOXSIZE) / 2) TOPMARGIN = WINHEIGHT - (BOARDHEIGHT * BOXSIZE) - 5 #定义颜色 # R G B WHITE = (255, 255, 255)#白色 GRAY = (185, 185, 185)#灰色 BLACK = ( 0, 0, 0)#黑色 RED = (155, 0, 0)#红色 GREEN = ( 0, 155, 0)#绿色 BLUE = ( 0, 0, 155)#蓝色 YELLOW = (155, 155, 0)#黄色 BORDERCOLOR = GRAY#边界颜色 BGCOLOR = BLACK#背景颜色 TEXTCOLOR = WHITE#文字颜色 COLORS = (BLUE,GREEN,RED,YELLOW) TEMPLATEWIDTH = 5#砖块模板宽 TEMPLATEHEIGHT = 5#砖块模板高 S_SHAPE_TEMPLATE = [['.....', #S形状的模板 '.....', '..OO.', '.OO..', '.....'], ['.....', #S逆时针变化的形状 '..O..', '..OO.', '...O.', '.....']] Z_SHAPE_TEMPLATE = [['.....', #Z形模板 '.....', '.OO..', '..OO.', '.....'], ['.....', '..O..', '.OO..', '.O...', '.....']] I_SHAPE_TEMPLATE = [['..O..', #I型模板 '..O..', '..O..', '..O..', '.....'], ['.....', '.....', 'OOOO.', '.....', '.....']] O_SHAPE_TEMPLATE = [['.....', #O型模板 '.....', '.OO..', '.OO..', '.....']] J_SHAPE_TEMPLATE = [['.....', #J型模板 '.O...', '.OOO.', '.....', '.....'], ['.....', '..OO.', '..O..', '..O..', '.....'], ['.....', '.....', '.OOO.', '...O.', '.....'], ['.....', '..O..', '..O..', '.OO..', '.....']] L_SHAPE_TEMPLATE = [['.....', #L型模板 '...O.', '.OOO.', '.....', '.....'], ['.....', '..O..', '..O..', '..OO.', '.....'], ['.....', '.....', '.OOO.', '.O...', '.....'], ['.....', '.OO..', '..O..', '..O..', '.....']] T_SHAPE_TEMPLATE = [['.....', #T型模板 '..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, FONT1, BIGFONT pygame.init() FPSCLOCK = pygame.time.Clock() DISPLAYSURF = pygame.display.set_mode((WINWIDTH, WINHEIGHT)) FONT1 = pygame.font.Font('hwfs.ttf', 30) BIGFONT = pygame.font.Font('hwfs.ttf', 100) pygame.display.set_caption('俄罗斯方块v1.0') showTextScreen('俄罗斯方块') while True: pygame.mixer.music.load('123.mp3') pygame.mixer.music.play(-1, 0.0) runGame() pygame.mixer.music.stop() showTextScreen('游戏结束') def runGame(): board = getBlankBoard() lastMoveDownTime = time.time() lastMoveSidewaysTime = time.time() lastFallTime = time.time() movingDown = False movingLeft = False movingRight = False score = 0 level, fallFreq = calculateLevelAndFallFreq(score) fallingPiece = getNewPiece() nextPiece = getNewPiece() while True: if fallingPiece == None: fallingPiece = nextPiece nextPiece = getNewPiece() lastFallTime = time.time() if not isValidPosition(board, fallingPiece): return for event in pygame.event.get(): if event.type== QUIT: sys.exit() elif event.type == KEYUP: if (event.key == K_LEFT): movingLeft = False elif (event.key == K_RIGHT): movingRight = False elif (event.key == K_DOWN): movingDown = False elif event.type == KEYDOWN: if (event.key == K_LEFT) and isValidPosition(board, fallingPiece, adjX=-1): fallingPiece['x'] = fallingPiece['x'] -1 movingLeft = True movingRight = False lastMoveSidewaysTime = time.time() elif (event.key == K_RIGHT ) and isValidPosition(board, fallingPiece, adjX=1): fallingPiece['x'] =fallingPiece['x'] + 1 movingRight = True movingLeft = False lastMoveSidewaysTime = time.time() elif event.key == K_UP : 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_DOWN ): movingDown = True if isValidPosition(board, fallingPiece, adjY=1): fallingPiece['y'] = fallingPiece['y'] +1 lastMoveDownTime = time.time() if (movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ: if movingLeft and isValidPosition(board, fallingPiece, adjX=-1): fallingPiece['x'] =fallingPiece['x'] - 1 elif movingRight and isValidPosition(board, fallingPiece, adjX=1): fallingPiece['x'] =fallingPiece['x'] + 1 lastMoveSidewaysTime = time.time() if movingDown and time.time() - lastMoveDownTime > MOVEDOWNFREQ and isValidPosition(board, fallingPiece, adjY=1): fallingPiece['y'] = fallingPiece['y'] + 1 lastMoveDownTime = time.time() if time.time() - lastFallTime > fallFreq: if not isValidPosition(board, fallingPiece, adjY=1): addToBoard(board, fallingPiece) score=score + removeCompleteLines(board) level, fallFreq = calculateLevelAndFallFreq(score) fallingPiece = None else: fallingPiece['y'] = fallingPiece['y'] +1 lastFallTime = time.time() 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 checkForKeyPress(): for event in pygame.event.get([KEYDOWN, KEYUP]): if event.type == KEYDOWN: continue return event.key return None def calculateLevelAndFallFreq(score): level = int(score / 10) + 1 fallFreq = 0.27 - (level * 0.02) return level, fallFreq def getNewPiece(): 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, 'color': random.randint(0, len(COLORS) - 1) } return newPiece def addToBoard(board, piece): 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(): 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): 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): for x in range(BOARDWIDTH): if board[x][y] == BLANK: return False return True def removeCompleteLines(board): numLinesRemoved = 0 y = BOARDHEIGHT - 1 while y >= 0: if isCompleteLine(board, y): for pullDownY in range(y, 0, -1): for x in range(BOARDWIDTH): board[x][pullDownY] = board[x][pullDownY-1] for x in range(BOARDWIDTH): board[x][0]=BLANK numLinesRemoved=numLinesRemoved+1 else: y =y- 1 return numLinesRemoved def convertToPixelCoords(boxx, boxy): return (XMARGIN + (boxx * BOXSIZE)), (TOPMARGIN + (boxy * BOXSIZE)) def drawBoard(board): pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (XMARGIN - 3, TOPMARGIN - 7, (BOARDWIDTH * BOXSIZE) + 8, (BOARDHEIGHT * BOXSIZE) + 8), 5) pygame.draw.rect(DISPLAYSURF, BGCOLOR, (XMARGIN, TOPMARGIN, BOXSIZE * BOARDWIDTH, BOXSIZE * BOARDHEIGHT)) #填充游戏板的背景颜色 for x in range(BOARDWIDTH): for y in range(BOARDHEIGHT): drawBox(x, y, board[x][y]) def drawBox(boxx, boxy, color, pixelx=None, pixely=None): 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))#留出1像素的空白,这样才能在砖块中看到组成砖块 def drawPiece(piece, pixelx=None, pixely=None): shapeToDraw = PIECES[piece['shape']][piece['rotation']] if pixelx == None and pixely == None: pixelx, pixely = convertToPixelCoords(piece['x'], piece['y']) 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): nextSurf = FONT1.render('Next:', True, TEXTCOLOR) nextRect = nextSurf.get_rect() nextRect.topleft = (WINWIDTH - 120, 80) DISPLAYSURF.blit(nextSurf, nextRect) drawPiece(piece, pixelx=WINWIDTH-120, pixely=100) def drawStatus(score, level): scoreSurf = FONT1.render('Score: %s' % score, True, TEXTCOLOR) scoreRect = scoreSurf.get_rect() scoreRect.topleft = (WINWIDTH - 150, 20) DISPLAYSURF.blit(scoreSurf, scoreRect) levelSurf = FONT1.render('Level: %s' % level, True, TEXTCOLOR) levelRect = levelSurf.get_rect() levelRect.topleft = (WINWIDTH - 150, 50) DISPLAYSURF.blit(levelSurf, levelRect) def showTextScreen(text): titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR) titleRect.center = (int(WINWIDTH / 2) - 3, int(WINHEIGHT / 2) - 3) DISPLAYSURF.blit(titleSurf, titleRect) pressKeySurf, pressKeyRect = makeTextObjs('按任意键开始游戏......', FONT1, TEXTCOLOR) pressKeyRect.center = (int(WINWIDTH / 2), int(WINHEIGHT / 2) + 100) DISPLAYSURF.blit(pressKeySurf, pressKeyRect) while checkForKeyPress() == None: pygame.display.update() FPSCLOCK.tick() if __name__ == '__main__': main()