|

楼主 |
发表于 2020-3-2 20:00:15
|
显示全部楼层
- import pygame, sys, random #
- from pygame.locals import * #导入pygame库中的一些常量
- # 音乐的路径
- #file=r'C:\Users\hp\Desktop\作业\D.mp3'
- file='D.mp3'
- # 初始化
- pygame.mixer.init()
- # 加载音乐文件
- track = pygame.mixer.music.load(file)
- # 开始播放音乐流
- pygame.mixer.music.play(-1,0.0)
- #暂停音乐
- pygame.mixer.music.pause()
- #一开始游戏打乱时鼠标点击按钮不会生效,
- #要将音乐先停下来,如果不喜欢这个音乐就不会感到反感了
- #背景图片的路径
- Pictures = "1.jpg"
- background1 = pygame.image.load(Pictures)
- # 创建常量(继续用不同的值进行实验)
- BOARDWIDTH = 4 #板中的列数
- BOARDHEIGHT = 4 #板中的行数
- TILESIZE = 80 #游戏板块大小
- WINDOWWIDTH = 1400 #窗口大小 640 480
- WINDOWHEIGHT = 600
- FPS = 80 #游戏帧数(越大开头乱序越快)
- 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,MS_SURF, MS_RECT,DOWN_SURF,\
- DOWN_RECT,Music_SURF,Music_RECT,CH_SURF,CH_RECT
- #上面是全局变量
- f=1
- pygame.init()
- #初始化所有导入的pygame模块。
- FPSCLOCK = pygame.time.Clock()
- #创建一个对象来帮助跟踪时间
- DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
- #创建窗口
- pygame.display.set_caption('game')
- #窗口标题
- BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE)
- #从一个字体文件创建一个 Font 对象
- # 将选项按钮及其矩形存储在选项中。
- 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)
- MS_SURF, MS_RECT = makeText('Music Stop',TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 120)
- Music_SURF, Music_RECT = makeText('Music', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 150)
- CH_SURF, CH_RECT = makeText('change', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 180)
- mainBoard, solutionSeq = generateNewPuzzle(80)
- SOLVEDBOARD = getStartingBoard()
- #游戏胜利对比数据
- allMoves = []
- # 游戏移动方向数据
- while True:
- # 开始游戏的主循环
- slideTo = None
- # 平铺应滑动的方向(如果有的话)
- msg = 'Click tile or press arrow keys to slide.'
- # 游戏开始提示
-
- if mainBoard == SOLVEDBOARD:
-
- msg = 'Congratulations on your victory!You can do it all over again.'
-
-
- drawBoard(mainBoard, msg)
-
- checkForQuit()
- for event in pygame.event.get():
- # event handling loop事件处理循环
- if event.type == MOUSEBUTTONUP:
- #鼠标点击按钮
- spotx, spoty = getSpotClicked(mainBoard, event.pos[0], event.pos[1])
- #鼠标点击碰撞
- if (spotx, spoty) == (None, None):
- #如果没有在游戏方块上
-
- if CH_RECT.collidepoint(event.pos):
- f=2
- if MS_RECT.collidepoint(event.pos):
- pygame.mixer.music.pause()
- #音乐暂停
- if Music_RECT.collidepoint(event.pos):
- pygame.mixer.music.unpause()
- #音乐结束暂停
- 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 = []
- else:
- # check if the clicked tile was next to the blank spot
- 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
- #如果按键触发在右按键和d按键并且可以移动方块
- 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)
- # 执行滑动动画,8是速度
- makeMove(mainBoard, slideTo)
- #修改游戏坐标数据
- allMoves.append(slideTo)
- # 添加移动记录
-
- pygame.display.update()
- FPSCLOCK.tick(FPS)
- def terminate():
- #退出游戏
- pygame.quit()
- sys.exit()
- #执行推出
- #玩家单击游戏窗口的关闭按钮时,
- #将检测到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()
- #如果KEYUP事件是针对Esc键的,则终止
- pygame.event.post(event)
- # 将其他KEYUP事件对象放回
- def getStartingBoard():
- #生成游戏板数据结构
- # 返回数据坐标
- # For example, if BOARDWIDTH and BOARDHEIGHT are both 3, this function
- # returns [[1, 4, 7], [2, 5, 8], [3, 6, BLANK]]
- counter = 1
- board = []
- for x in range(BOARDWIDTH):
- column = []
- for y in range(BOARDHEIGHT):
- column.append(counter)
- #添加y轴数据
- counter += BOARDWIDTH
- board.append(column)
- #添加x轴数据
- 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):
- #记录数据移动方块
- # This function does not check if the move is valid.
- bushu=0
- bushu =bushu+1
- blankx, blanky = getBlankPosition(board)
- if move == UP:
- #上升空白快
- #blanky + 1 下个格子的y坐标,下降空白格,向上移动格子
- board[blankx][blanky], board[blankx][blanky + 1] = board[blankx][blanky + 1], board[blankx][blanky]
- elif move == DOWN:
- #下降空白快
- #blanky - 1 上个格子的y坐标,上升空白格,向下移动格子
- board[blankx][blanky], board[blankx][blanky - 1] = board[blankx][blanky - 1], board[blankx][blanky]
- elif move == LEFT:
- #右移空白快
- #blankx + 1 右个格子的x坐标,右移空白格,向左移动格子
- board[blankx][blanky], board[blankx + 1][blanky] = board[blankx + 1][blanky], board[blankx][blanky]
- elif move == RIGHT:
- #左移空白快
- #blankx - 1 左个格子的x坐标,左移空白格,向右移动格子
- board[blankx][blanky], board[blankx - 1][blanky] = board[blankx - 1][blanky], board[blankx][blanky]
- return(bushu)
- def isValidMove(board, move):
- #移动限制
- blankx, blanky = getBlankPosition(board)
- #获取空白位置的坐标
- #如果是上升的话,空白格的坐标不能等于y边界的坐标,如果返回Flase
- #下降,空白坐标不能等于y零界点左边,如果等于返回False
- 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) #获取左边的像素坐标(tile_x-1)格子间的间距
- top = YMARGIN + (tileY * TILESIZE) + (tileY - 1) #获取头部坐标
- return (left, top)
- #返回像素left,top坐标
- def getSpotClicked(board, x, y):
- #像素坐标转化为游戏板坐标
- # from the x & y pixel coordinates, get the x & y board coordinates
- 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):
- #绘制游戏方块
- # 在板坐标tilex和tiley处绘制一个平铺,可以选择一些
- # 像素超过(由adjx和adjy决定)
-
- 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):
- #创建字体对象
- # 为某些文本创建Surface和Rect对象。
- textSurf = BASICFONT.render(text, True, color, bgcolor)#创建文本
- #定位文字矩形块
- textRect = textSurf.get_rect()
- textRect.topleft = (top, left)
- return (textSurf, textRect)
- def drawBoard1(board, message):
- #绘制画板
-
- DISPLAYSURF.blit(background1,(0,0))
-
- 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)
-
-
- def slideAnimation1(board, direction, message, animationSpeed):
- #绘制滑动动画
- # Note: This function does not check if the move is valid.
- 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
- # prepare the base surface
- drawBoard(board, message)
- #绘制画板
- baseSurf = DISPLAYSURF.copy()
- #复制一个新的窗口对象
- # draw a blank space over the moving tile on the baseSurf Surface.
- moveLeft, moveTop = getLeftTopOfTile(movex, movey)
- #绘制空白区(这时候有2块空白区域)
- pygame.draw.rect(baseSurf, BGCOLOR, (moveLeft, moveTop, TILESIZE, TILESIZE))
- def drawBoard(board, message):
- #绘制画板
-
- DISPLAYSURF.blit(background1,(0,0))
-
- if message:
- #如果有提示信息显示提示信息
- textSurf, textRect = makeText(message, MESSAGECOLOR, BGCOLOR, 5,210)
- #获取文本对象和定位对象
- DISPLAYSURF.blit(textSurf, textRect)
- #显示消息
- textSurf, textRect = makeText('You can press exc to launch the game.', MESSAGECOLOR, BGCOLOR, 5,5)
- #告知退出方法
- DISPLAYSURF.blit(textSurf, textRect)
- textSurf, textRect = makeText('Press the Music to turn on the music.', MESSAGECOLOR, BGCOLOR, 5,30)
- DISPLAYSURF.blit(textSurf, textRect)
- textSurf, textRect = makeText('Press Music Stop to pause music.', MESSAGECOLOR, BGCOLOR, 5,60)
- DISPLAYSURF.blit(textSurf, textRect)
- textSurf, textRect = makeText('You can restart a game through New Game.', MESSAGECOLOR, BGCOLOR, 5,120)
- DISPLAYSURF.blit(textSurf, textRect)
- textSurf, textRect = makeText('You can use Solve to help you achieve your goals.', MESSAGECOLOR, BGCOLOR, 5,150)
- DISPLAYSURF.blit(textSurf, textRect)
- textSurf, textRect = makeText('You can cancel all your moves via Reset.', MESSAGECOLOR, BGCOLOR, 5,90)
- DISPLAYSURF.blit(textSurf, textRect)
- textSurf, textRect = makeText('I hope you can have a good time.', MESSAGECOLOR, BGCOLOR, 5,180)
- 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)
- DISPLAYSURF.blit(MS_SURF, MS_RECT)
- DISPLAYSURF.blit(Music_SURF, Music_RECT)
- #DISPLAYSURF.blit(CH_SURF, CH_RECT)
-
- def slideAnimation(board, direction, message, animationSpeed):
- #绘制滑动动画
- # Note: This function does not check if the move is valid.
- 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
- # prepare the base surface
- drawBoard(board, message)
- #绘制画板
- baseSurf = DISPLAYSURF.copy()
- #复制一个新的窗口对象
- # draw a blank space over the moving tile on the baseSurf Surface.
- moveLeft, moveTop = getLeftTopOfTile(movex, movey)
- #绘制空白区(这时候有2块空白区域)
- pygame.draw.rect(baseSurf, BGCOLOR, (moveLeft, moveTop, TILESIZE, TILESIZE))
- #绘制滑动效果
- for i in range(0, TILESIZE, animationSpeed):
- #animation_speed步长偏移速度,每次循环后方块的位置向指定方向移动
- # animate the tile sliding over
- checkForQuit()
- DISPLAYSURF.blit(baseSurf, (0, 0))
- if direction == UP:
- drawTile(movex, movey, board[movex][movey], 0, -i)# x不动,y轴向上偏移
- if direction == DOWN:
- drawTile(movex, movey, board[movex][movey], 0, i) # x不动,y轴向下偏移
- if direction == LEFT:
- drawTile(movex, movey, board[movex][movey], -i, 0)# x不动,y轴向左偏移
- if direction == RIGHT:
- drawTile(movex, movey, board[movex][movey], i, 0) # x不动,y轴向右偏移
- pygame.display.update()
- FPSCLOCK.tick(FPS)
- def generateNewPuzzle(numSlides):
- #重新开始游戏
- # From a starting configuration, make numSlides number of moves (and
- # animate these moves).
-
- sequence = []#移动数据
- board = getStartingBoard()#重新生成游戏数据
- drawBoard(board, '')#显示开始画板
- pygame.display.update()
- pygame.time.wait(500) # 等待500毫秒
- lastMove = None
- for i in range(numSlides):#执行移动打乱游戏数据
- move = getRandomMove(board, lastMove)#获取随机移动方向
- slideAnimation(board, move, 'Generating new game...', animationSpeed=int(TILESIZE / 3))
- makeMove(board, move)#数据坐标移动
- sequence.append(move)#记录移动信息
- lastMove = move
- return (board, sequence)
- def resetAnimation(board, allMoves):
- #重置步骤
- revAllMoves = allMoves[:] # gets a copy of the list
- 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()
复制代码 |
|