用户:www_321查看:0 回复:1 评论:0 创建时间:2020-01-10T20:35:27
【作品展示】

【作品介绍】
新手第一次用pygame
【作品源代码】
import pygame, sys, random
from pygame.locals import *
# 导入模块
BOARDWIDTH = 4 # 每行有几个板
BOARDHEIGHT = 3 # 每列有几个板
TILESIZE = 80 # 板的大小
WINDOWWIDTH = 喵0 # 窗口的宽
WINDOWHEIGHT = 480 # 窗口的高
FPS = 30 # 帧
BLANK = None # 给游戏板中的空白定一个标志
# R G B
BLACK = (0 , 0, 0)
WHITE = (255, 255, 255)
BRIGHTBLUE = (0 , 50, 255)
DARKTURQUOISE = (3 , 54, 73)
GREEN = (0 , 204, 0)
BGCOLOR = DARKTURQUOISE
TILECOLOR = GREEN
TEXTCOLOR = WHITE
BORDERCOLOR = BRIGHTBLUE
BASICFONTSIZE = 20
BUTTONCOLOR = WHITE
BUTTONTEXTCOLOR = BLACK
MESSAGECOLOR = WHITE
XMARGIN = int((WINDOWWIDTH - (TILESIZE * BOARDWIDTH + (BOARDWIDTH - 1))) / 2)
YMARGIN = int(
(WINDOWHEIGHT - (TILESIZE * BOARDHEIGHT + (BOARDHEIGHT - 1))) / 2)
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
# 一些基本设置
def main():
global FPSCLOCK, DISPLAYSURF, BASICFONT, RESET_SURF, RESET_RECT, NEW_SURF, NEW_RECT, SOLVE_SURF, SOLVE_RECT
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('将它们排序好')
BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE)
# 游戏设置
RESET_SURF, RESET_RECT = makeText(
'Reset', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 90)
NEW_SURF, NEW_RECT = makeText(
'New Game', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 60)
SOLVE_SURF, SOLVE_RECT = makeText(
'Solve', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 30)
# 绘制左下角的三个按钮
mainBoard, solutionSeq = generateNewPuzzle(80)
# 创建一个排序好的游戏板,并随机打乱80次
SOLVEDBOARD = getStartingBoard()
# 创建游戏板数据结构
allMoves = []
# 存储在当前已排好的游戏板上进行了哪些对顺序的打乱
while True:
slideTo = None # 记录玩家想要向哪一个方向滑动贴片
msg = 'Click tile or press arrow keys to slide.' # msg变量记录了在窗口顶部显示什么字符串
if mainBoard == SOLVEDBOARD:
msg = 'Solved!'
# 如果游戏板状态为SOLVEDBOARD存储的已求解游戏板,则显示'Solved!'
drawBoard(mainBoard, msg)
# 调用drawBoard()将其绘制到屏幕的Surface对象
checkForQuit()
for event in pygame.event.get():
if event.type == MOUSEBUTTONUP:
spotx, spoty = getSpotClicked(
mainBoard, event.pos[0], event.pos[1])
if (spotx, spoty) == (None, None):
if RESET_RECT.collidepoint(event.pos):
resetAnimation(mainBoard, allMoves)
allMoves = []
elif NEW_RECT.collidepoint(event.pos):
mainBoard, solutionSeq = generateNewPuzzle(
80)
allMoves = []
elif SOLVE_RECT.collidepoint(event.pos):
resetAnimation(mainBoard, solutionSeq + allMoves)
allMoves = []
# 如果事件的类型是一个MOUSEBUTTONUP事件,即玩家在窗口上的某处释放了一次鼠标按钮,那么,我们将鼠标坐标传递给getSpotClicked()函数,它将会返回游戏板上释放鼠标
# 的位置的游戏板坐标。event.pos[0]是X坐标,而event.pos[1]是Y坐标。
else:
blankx, blanky = getBlankPosition(mainBoard)
if spotx == blankx + 1 and spoty == blanky:
slideTo = LEFT
elif spotx == blankx - 1 and spoty == blanky:
slideTo = RIGHT
elif spotx == blankx and spoty == blanky + 1:
slideTo = UP
elif spotx == blankx and spoty == blanky - 1:
slideTo = DOWN
# 用鼠标滑动贴片
elif event.type == KEYUP:
if event.key in (K_LEFT, K_a) and isValidMove(mainBoard, LEFT):
slideTo = LEFT
elif event.key in (K_RIGHT, K_d) and isValidMove(mainBoard, RIGHT):
slideTo = RIGHT
elif event.key in (K_UP, K_w) and isValidMove(mainBoard, UP):
slideTo = UP
elif event.key in (K_DOWN, K_s) and isValidMove(mainBoard, DOWN):
slideTo = DOWN
# 用键盘滑动贴片
if slideTo:
slideAnimation(mainBoard, slideTo,
'Click tile or press arrow keys to slide.', 8)
makeMove(mainBoard, slideTo)
allMoves.append(slideTo)
# 实际执行贴片滑动
pygame.display.update()
FPSCLOCK.tick(FPS)
def terminate():
"""程序结束"""
pygame.quit()
sys.exit()
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 getStartingBoard():
"""创建游戏板数据结构"""
counter = 1
board = []
for x in range(BOARDWIDTH):
column = []
for y in range(BOARDHEIGHT):
column.append(counter)
counter += BOARDWIDTH
board.append(column)
counter -= BOARDWIDTH * (BOARDHEIGHT - 1) + BOARDWIDTH - 1
board[BOARDWIDTH-1][BOARDHEIGHT-1] = BLANK
return board
def getBlankPosition(board):
"""不记录空白的位置"""
for x in range(BOARDWIDTH):
for y in range(BOARDHEIGHT):
if board[x][y] == BLANK:
return (x, y)
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 isValidMove(board, move):
"""何时不使用断言"""
blankx, blanky = getBlankPosition(board)
return (move == UP and blanky != len(board[0]) - 1) or \
(move == DOWN and blanky != 0) or \
(move == LEFT and blankx != len(board) - 1) or \
(move == RIGHT and blankx != 0)
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 getLeftTopOfTile(tileX, tileY):
"""将贴片坐标转换为像素坐标"""
left = XMARGIN + (tileX * TILESIZE) + (tileX - 1)
top = YMARGIN + (tileY * TILESIZE) + (tileY - 1)
return (left, top)
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, TILESIZE, TILESIZE)
if tileRect.collidepoint(x, y):
return (tileX, tileY)
return (None, None)
def drawTile(tilex, tiley, number, adjx=0, adjy=0):
"""绘制一个贴片"""
left, top = getLeftTopOfTile(tilex, tiley)
pygame.draw.rect(DISPLAYSURF, TILECOLOR,
(left + adjx, top + adjy, TILESIZE, TILESIZE))
textSurf = BASICFONT.render(str(number), True, TEXTCOLOR)
textRect = textSurf.get_rect()
textRect.center = left + int(TILESIZE / 2) + \
adjx, top + int(TILESIZE / 2) + adjy
DISPLAYSURF.blit(textSurf, textRect)
def makeText(text, color, bgcolor, top, left):
"""绘制文本"""
textSurf = BASICFONT.render(text, True, color, bgcolor)
textRect = textSurf.get_rect()
textRect.topleft = (top, left)
return (textSurf, textRect)
def drawBoard(board, message):
"""绘制游戏板"""
DISPLAYSURF.fill(BGCOLOR)
if message:
textSurf, textRect = makeText(message, MESSAGECOLOR, BGCOLOR, 5, 5)
DISPLAYSURF.blit(textSurf, textRect)
for tilex in range(len(board)):
for tiley in range(len(board[0])):
if board[tilex][tiley]:
drawTile(tilex, tiley, board[tilex][tiley])
left, top = getLeftTopOfTile(0, 0)
width = BOARDWIDTH * TILESIZE
height = BOARDHEIGHT * TILESIZE
pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (left - 5,
top - 5, width + 11, height + 11), 4)
DISPLAYSURF.blit(RESET_SURF, RESET_RECT)
DISPLAYSURF.blit(NEW_SURF, NEW_RECT)
DISPLAYSURF.blit(SOLVE_SURF, SOLVE_RECT)
def slideAnimation(board, direction, message, 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, message)
baseSurf = DISPLAYSURF.copy()
moveLeft, moveTop = getLeftTopOfTile(movex, movey)
pygame.draw.rect(baseSurf, BGCOLOR, (moveLeft,
moveTop, TILESIZE, TILESIZE))
for i in range(0, TILESIZE, animationSpeed):
checkForQuit()
DISPLAYSURF.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 generateNewPuzzle(numSlides):
"""创建新的谜题"""
sequence = []
board = getStartingBoard()
drawBoard(board, '')
pygame.display.update()
pygame.time.wait(500)
lastMove = None
for i in range(numSlides):
move = getRandomMove(board, lastMove)
slideAnimation(board, move, 'Generating new puzzle...',
animationSpeed=int(TILESIZE / 3))
makeMove(board, move)
sequence.append(move)
lastMove = move
return (board, sequence)
def resetAnimation(board, allMoves):
"""实现游戏板重置动画"""
revAllMoves = allMoves[:]
revAllMoves.reverse()
for move in revAllMoves:
if move == UP:
oppositeMove = DOWN
elif move == DOWN:
oppositeMove = UP
elif move == RIGHT:
oppositeMove = LEFT
elif move == LEFT:
oppositeMove = RIGHT
slideAnimation(board, oppositeMove, '',
animationSpeed=int(TILESIZE / 2))
makeMove(board, oppositeMove)
if __name__ == '__main__':
main()
【提示】
部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:
https://python.codemao.cn