Python—数字推盘游戏设计

Python—数字推盘游戏设计目标 了解 pygame 模块的框架与基础函数 熟悉 MVC 设计模式 掌握自顶向下的程序设计方式 内容 完成数字推盘游戏设计步骤 代码如下 importpygame localsimport 定义常量 WINWIDTH 640 窗口宽度 WINHEIGHT 480 窗口高度 ROW 3COL 3BLANK None

目标:

内容:

完成数字推盘游戏设计

步骤:

代码如下:

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('STKAITI.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() 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/198551.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午2:57
下一篇 2026年3月26日 下午2:57


相关推荐

  • Gmap使用说明,通过输入经纬度查询位置

    Gmap使用说明,通过输入经纬度查询位置由于本人对于 Gmap 的使用时间不长 有很多东西不是太熟悉 所以本人的代码有借鉴的部分 如有发现侵权 还请及时联系本人 我目前已经基本实现了 地图的放大 缩小 平移的功能 完成了鼠标单击标点 输入经纬度标点 然后通过标志点连接成轨迹的功能 还可以保存正在使用的这块地图为图片 下面是本人的代码部分 注释已经很明确了 如有不明白的地方还请及时评论 Gmap 有个需要配置的部分详情可看 https

    2026年3月17日
    2
  • lmdb数据库_Interbase数据库

    lmdb数据库_Interbase数据库LMDB全称为LightningMemory-MappedDatabase,就是非常快的内存映射型数据库,LMDB使用内存映射文件,可以提供更好的输入/输出性能,对于用于神经网络的大型数据集(比如ImageNet),可以将其存储在LMDB中…

    2026年4月18日
    7
  • 谈谈怎么实现Oracle数据库分区表「建议收藏」

    谈谈怎么实现Oracle数据库分区表「建议收藏」Oracle数据库分区是作为Oracle数据库性能优化的一种重要的手段和方法,做手头的项目以前,只聆听过分区的大名,感觉特神秘,看见某某高手在讨论会上夸夸其谈时,真是骂自己学艺不精,最近作GPS方面的项目,处理的数据量达到了几十GB,为了满足系统的实时性要求,必须提高数据的查询效率,这样就必须通过分区,以解燃眉之急!先说说分区的好处吧!1) 增强可用性:如果表的某个分区出现故障,表在其他分

    2022年5月9日
    62
  • Nginx 配置中nginx和alias的区别分析

    Nginx 配置中nginx和alias的区别分析root和alias都可以定义在location模块中,都是用来指定请求资源的真实路径,比如:?123location/i/{root/data/w3;}请求http://foofish.net/i/top.gif这个地址时,那么在服务器里面对应的真正的资源是/data/w3/i/top.gif文件注意:真实的路径是root指定的值加上location指定的值。而alias正…

    2022年7月14日
    52
  • openclaw喂饭教程!在 Linux 环境下快速完成安装、初始化与 Web UI 配置

    openclaw喂饭教程!在 Linux 环境下快速完成安装、初始化与 Web UI 配置

    2026年3月13日
    1
  • ipmitool命令总结

    ipmitool命令总结Name 名字 nbsp Ipmitool nbsp nbsp 对于控制支持 IPMI 的设备有效 Synopsis 概要 ipmitool c h v V Iopen command ipmitool c h v V Ilan H hostname nbsp nbsp nbsp amp nb hostname command

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号