import pygame
import time
import random
import sys
import random
from pygame.locals import *
#定义常量
WINWIDTH = 640 #窗口宽度
WINHEIGHT = 480 #窗口高度
ROW = 3
COL = 3
BLANK = 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 = BRIGHTBLUE
BTCOLOR_NEW = BLEAK
#######静态常量#####
BLOCKSIZE = 80 #滑块边长
FPS = 60
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
NEWGAME = 'newgame'
AUTOMOVE = random.randint(50,100)
print(AUTOMOVE)
def main():
global FPSCLOCK,WINSET,STATICSURF,BASICFONT
global NEW_SURF,NEW_RECT
global SOLVEDBOARD
##流程
pygame.init()
FPSCLOCK = pygame.time.Clock()
BASICFONT = pygame.font.Font('assetsSourceSansPro-Bold.TTF',24)
#初始化
initBoard = getStartingBoard()
print(initBoard)
WINSET,NEW_SURF,NEW_RECT = drawStaticWin()
STATICSURF = WINSET.copy()
mainBoard = generateNewPuzzle(AUTOMOVE)
msg = None
while 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= None
for 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 = NEWGAME
else:
if mainBoard == getStartingBoard():
break
blankx,blanky = getBlankPosition(mainBoard)
if spotx == blankx + 1 and spoty == blanky:
userInput = LEFT
elif spotx == blankx -1 and spoty == blanky:
userInput = RIGHT
elif spotx == blankx and spoty == blanky + 1:
userInput = UP
elif spotx == blankx and spoty == blanky - 1:
userInput = DOWN
return userInput
def 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,msg
def 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,None
def getStartingBoard():
initBoard = []
for i in range(COL):
i = i+1
column = []
for j in range(ROW):
column.append(i)
i += COL
initBoard.append(column)
initBoard[ROW-1][COL-1] = BLANK
return initBoard
def generateNewPuzzle(numSlides):
mianBoard = getStartingBoard()
drawBoard(mianBoard,'')
lastMove = None
for i in range(numSlides):
move = getRandomMove(mianBoard,lastMove)
slideAnimation(mianBoard,move,'初始化中...',animationSpeed=int(BLOCKSIZE / 3))
makeMove(mianBoard,move)
lastMove = move
return mianBoard
def 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])-1
if move == DOWN:
return blanky != 0
if move == LEFT:
return blankx != len(board)-1
if move == RIGHT:
return blankx != 0
def 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_rect
def makeText(text,tColor,btColor,top,left):
textSurf = BASICFONT.render(text,True,tColor,btColor)
textRect = textSurf.get_rect()
textRect.topleft = (top,left)
return textSurf,textRect
def slideAnimation(board,direction,msg,animationSpeed):
blankx,blanky = getBlankPosition(board)
if direction == UP:
movex = blankx
movey = blanky + 1
elif direction == DOWN:
movex = blankx
movey = blanky - 1
elif direction == LEFT:
movex = blankx + 1
movey = blanky
elif direction == RIGHT:
movex = blankx - 1
movey = blanky
drawBoard(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 * BLOCKSIZE
height = 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)+adjy
WINSET.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,top
def 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()
在该代码中,插入模块,下载字体,加入了自己喜欢的背景图得出以下结果: