Python—数字推盘游戏设计

发布时间:2025-12-09 22:28:32 浏览次数:17

目标:

了解pygame模块的框架与基础函数;
熟悉MVC设计模式;
掌握自顶向下的程序设计方式。

内容:

完成数字推盘游戏设计

步骤:

代码如下:

import pygameimport timeimport randomimport sysimport randomfrom pygame.locals import *#定义常量WINWIDTH = 640#窗口宽度WINHEIGHT = 480#窗口高度ROW = 3COL = 3BLANK = None#####颜色预设####DARKGRAY = ( 60, 60, 60)WHITE = (255, 255, 255)BLUE= ( 32, 178, 170)GRAY = (128, 128, 128)BRIGHTBLUE = (138, 228, 221)BLEAK = (50,255,50)#######颜色变量#####BLANKCOLOR = DARKGRAY#预设背景颜色MSGCOLOR = WHITE#提示信息颜色BTCOLOR = BLUE#按钮底色BTTEXTCOLOR = GRAY#选项字体颜色BDCOLOR = BRIGHTBLUEBTCOLOR_NEW = BLEAK#######静态常量#####BLOCKSIZE = 80#滑块边长FPS = 60UP = 'up'DOWN = 'down'LEFT = 'left'RIGHT = 'right'NEWGAME = 'newgame'AUTOMOVE = random.randint(50,100)print(AUTOMOVE)def main():global FPSCLOCK,WINSET,STATICSURF,BASICFONTglobal NEW_SURF,NEW_RECTglobal SOLVEDBOARD##流程pygame.init()FPSCLOCK = pygame.time.Clock()BASICFONT = pygame.font.Font('STKAITI.TTF',24)#初始化initBoard = getStartingBoard()print(initBoard)WINSET,NEW_SURF,NEW_RECT = drawStaticWin()STATICSURF = WINSET.copy()mainBoard = generateNewPuzzle(AUTOMOVE)msg = Nonewhile True:FPSCLOCK.tick(FPS)drawBoard(mainBoard,msg)pygame.display.update()checkForQuit()userInput = getInput(mainBoard)mainBoard,msg = processing(userInput,mainBoard,msg)def getInput(mainBoard):events = pygame.event.get()userInput= Nonefor event in events:if event.type == MOUSEBUTTONUP:spotx,spoty = getSpotClicked(mainBoard,event.pos[0],event.pos[1])if (spotx,spoty)==(None,None) and NEW_RECT.collidepoint(event.pos):userInput = NEWGAMEelse:if mainBoard == getStartingBoard():breakblankx,blanky = getBlankPosition(mainBoard)if spotx == blankx + 1 and spoty == blanky:userInput = LEFT elif spotx == blankx -1 and spoty == blanky: userInput = RIGHTelif spotx == blankx and spoty == blanky + 1:userInput = UPelif spotx == blankx and spoty == blanky - 1:userInput = DOWNreturn userInputdef processing(userInput,mainBoard,msg):if mainBoard == getStartingBoard():msg = ' very good!'else:msg = '任何你想说的话,这里老师要求我们班级加姓名'if userInput:if userInput == NEWGAME:initBoard = getStartingBoard()mainBoard = generateNewPuzzle(AUTOMOVE)else:slideAnimation(mainBoard,userInput,msg,8)makeMove(mainBoard,userInput)return mainBoard,msgdef getSpotClicked(board,x,y):for tilex in range(len(board)):for tiley in range(len(board[0])):left,top = getLeftTopOfTile(tilex,tiley)tileRect = pygame.Rect(left,top,BLOCKSIZE,BLOCKSIZE)if tileRect.collidepoint(x,y):#如果x,y在碎方块内return tilex,tiley#返回方块坐标return None,Nonedef getStartingBoard():initBoard = []for i in range(COL):i = i+1column = []for j in range(ROW):column.append(i)i += COL initBoard.append(column)initBoard[ROW-1][COL-1] = BLANKreturn initBoarddef generateNewPuzzle(numSlides):mianBoard = getStartingBoard()drawBoard(mianBoard,'')lastMove = Nonefor i in range(numSlides):move = getRandomMove(mianBoard,lastMove)slideAnimation(mianBoard,move,'初始化中...',animationSpeed=int(BLOCKSIZE / 3))makeMove(mianBoard,move)lastMove = movereturn mianBoarddef makeMove(board,move):blankx,blanky = getBlankPosition(board)if move == UP:board[blankx][blanky],board[blankx][blanky+1] = board[blankx][blanky+1],board[blankx][blanky]elif move == DOWN:board[blankx][blanky],board[blankx][blanky-1] = board[blankx][blanky-1],board[blankx][blanky]elif move == LEFT:board[blankx][blanky],board[blankx+1][blanky] = board[blankx+1][blanky],board[blankx][blanky]elif move == RIGHT:board[blankx][blanky],board[blankx-1][blanky] = board[blankx-1][blanky],board[blankx][blanky]def getRandomMove(board,lastMove=None):validMoves = [UP,DOWN,LEFT,RIGHT]if lastMove == UP or not isValidMove(board,DOWN):validMoves.remove(DOWN)if lastMove == DOWN or not isValidMove(board,UP):validMoves.remove(UP)if lastMove == LEFT or not isValidMove(board,RIGHT):validMoves.remove(RIGHT)if lastMove == RIGHT or not isValidMove(board,LEFT):validMoves.remove(LEFT)return random.choice(validMoves)def isValidMove(board,move):blankx,blanky = getBlankPosition(board)if move == UP:return blanky != len(board[0])-1if move == DOWN:return blanky != 0if move == LEFT:return blankx != len(board)-1if move == RIGHT:return blankx != 0def getBlankPosition(board):for x in range(COL):for y in range(ROW):if board[x][y] == BLANK:return (x,y)def drawStaticWin():#窗口winSet = pygame.display.set_mode((WINWIDTH,WINHEIGHT))#名字pygame.display.set_caption('数字推盘')#背景图片image = pygame.image.load('bg.jpg')#绘制到窗口中winSet.blit(image,(0,0))#新游戏按钮new_surf,new_rect = makeText('新游戏',BTTEXTCOLOR,BTCOLOR_NEW,WINWIDTH-85,WINHEIGHT-40)#绘制到窗口中winSet.blit(new_surf,new_rect)#返回return winSet,new_surf,new_rectdef makeText(text,tColor,btColor,top,left):textSurf = BASICFONT.render(text,True,tColor,btColor)textRect = textSurf.get_rect()textRect.topleft = (top,left)return textSurf,textRectdef slideAnimation(board,direction,msg,animationSpeed):blankx,blanky = getBlankPosition(board)if direction == UP:movex = blankxmovey = blanky + 1elif direction == DOWN:movex = blankxmovey = blanky - 1elif direction == LEFT:movex = blankx + 1movey = blankyelif direction == RIGHT:movex = blankx - 1movey = blankydrawBoard(board,msg)BASESURF = WINSET.copy()moveLeft,moveTop = getLeftTopOfTile(movex,movey)pygame.draw.rect(BASESURF,BLANKCOLOR,(moveLeft,moveTop,BLOCKSIZE,BLOCKSIZE))for i in range(0,BLOCKSIZE,animationSpeed):checkForQuit()WINSET.blit(BASESURF,(0,0))if direction == UP:drawTile(movex,movey,board[movex][movey],0,-i)if direction == DOWN:drawTile(movex,movey,board[movex][movey],0,i)if direction == LEFT:drawTile(movex,movey,board[movex][movey],-i,0)if direction == RIGHT:drawTile(movex,movey,board[movex][movey],i,0)pygame.display.update()FPSCLOCK.tick(FPS)#动态界面def drawBoard(board,msg):WINSET.blit(STATICSURF,(0,0))#提示信息if msg:msgSurf,msgRect = makeText(msg,MSGCOLOR,None,5,5)pygame.image.save(msgSurf,'msg.png')imgSurf = pygame.image.load('msg.png')WINSET.blit(imgSurf,msgRect)#绘制推盘for i in range(len(board)):for j in range(len(board[0])):if board[i][j]:#绘制方块drawTile(i,j,board[i][j])#计算方块距离原点的横纵坐标left,top= getLeftTopOfTile(0,0)width = COL * BLOCKSIZEheight = ROW * BLOCKSIZE#绘制外边框pygame.draw.rect(WINSET,BDCOLOR,(left - 5,top - 5,width + 11,height + 11),4)def drawTile(tilex,tiley,number,adjx=0,adjy=0):left,top = getLeftTopOfTile(tilex,tiley)pygame.draw.rect(WINSET,BTCOLOR,(left+adjx,top+adjy,BLOCKSIZE,BLOCKSIZE))textSurf = BASICFONT.render(str(number),True,BTTEXTCOLOR)textRect = textSurf.get_rect()textRect.center = left+int(BLOCKSIZE/2)+adjx,top+int(BLOCKSIZE/2)+adjyWINSET.blit(textSurf,textRect)def getLeftTopOfTile(tilex,tiley):xMargin = int((WINWIDTH - (BLOCKSIZE * COL + (COL -1)))/2)yMargin = int((WINHEIGHT - (BLOCKSIZE * ROW + (ROW-1)))/2)left = xMargin + (tilex * BLOCKSIZE) + (tilex - 1)top = yMargin + (tiley * BLOCKSIZE) + (tiley - 1)return left,topdef checkForQuit():for event in pygame.event.get(QUIT): terminate() for event in pygame.event.get(KEYUP): if event.key == K_ESCAPE: terminate() pygame.event.post(event) def terminate():pygame.quit()sys.exit()if __name__ == '__main__':main()

运行结果:

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477