欲学习基本的Python编程。
思编程语言学习与人类语言的学习类似,人类语言终究是要说的,编程语言终究也是要说的。人类语言说给人听,编程语言却是说给计算机听的。
人类学习说话,从牙牙学语,到流利交流,靠的是整天模仿与练习。编程语言也一样。
我觉得学习编程语言不是去死抠语法。就像汉语学习中除了语文考试要考病句外,我们平时说话不在乎语法一样。
所以这次学Python--一门新的编程语言,我决定尝试直接学着用,而不是去从头开始学语法。
花了一个小时浏览了一下Python语言的基本构成、关键字等,我决定开始写了--确切地说是开始抄。
抄程序的过程就像学汉语时跟着大人学学说话一样。
或抄或拷,我尝试运行了一本讲游戏的Python书。但里面的游戏多数是字符界面的,只有最后三两章用了PyGame包开发图形界面的游戏。
在大体上知道了Python和pyGame的用法后,我决定自己写个拼图游戏试试。
1.画图
- import pygame, sys, random
- from pygame.locals import *
-
-
- WINDOWWIDTH = 500
- WINDOWHEIGHT = 500
- BACKGROUNDCOLOR = (0, 0, 0)
- FPS = 40
-
-
- def terminate():
- pygame.quit()
- sys.exit()
-
-
- pygame.init()
- mainClock = pygame.time.Clock()
- windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
- pygame.display.set_caption('拼图')
-
-
- gameImage = pygame.image.load('pic.bmp')
- gameRect = gameImage.get_rect()
-
-
- timeUsed = 0
- moveUsed = 0
- while True:
- for event in pygame.event.get():
- if event.type == QUIT:
- terminate()
- windowSurface.fill(BACKGROUNDCOLOR)
- windowSurface.blit(gameImage, gameRect)
-
- pygame.display.update()
- mainClock.tick(FPS)
发现窗口大小不太合适。
解决办法:
先加载图片,然后根据图片的大小设置窗口大小:
- import pygame, sys, random
- from pygame.locals import *
-
-
- WINDOWWIDTH = 500
- WINDOWHEIGHT = 500
- BACKGROUNDCOLOR = (0, 0, 0)
- FPS = 40
-
-
- def terminate():
- pygame.quit()
- sys.exit()
-
-
- pygame.init()
- mainClock = pygame.time.Clock()
-
-
- gameImage = pygame.image.load('pic.bmp')
- gameRect = gameImage.get_rect()
-
-
- windowSurface = pygame.display.set_mode((gameRect.width, gameRect.height))
- pygame.display.set_caption('拼图')
-
-
- while True:
- for event in pygame.event.get():
- if event.type == QUIT:
- terminate()
- windowSurface.fill(BACKGROUNDCOLOR)
- windowSurface.blit(gameImage, gameRect)
-
- pygame.display.update()
- mainClock.tick(FPS)
2.图像的分割
- import pygame, sys, random
- from pygame.locals import *
-
-
- WINDOWWIDTH = 500
- WINDOWHEIGHT = 500
- BACKGROUNDCOLOR = (0, 0, 0)
- FPS = 40
-
- VHNUMS = 3
- CELLNUMS = VHNUMS*VHNUMS
-
-
- def newGameBoard():
- board = []
- for i in range(CELLNUMS):
- board.append(i)
-
- print(board)
- random.shuffle(board)
- print(board)
- return board
-
-
-
-
- def terminate():
- pygame.quit()
- sys.exit()
-
-
- pygame.init()
- mainClock = pygame.time.Clock()
-
-
- gameImage = pygame.image.load('pic.bmp')
- gameRect = gameImage.get_rect()
-
-
-
- windowSurface = pygame.display.set_mode((gameRect.width, gameRect.height))
- pygame.display.set_caption('拼图')
-
- cellWidth = int(gameRect.width / VHNUMS)
- cellHeight = int(gameRect.height / VHNUMS)
-
-
- gameBoard = newGameBoard()
-
-
- cellImage = pygame.transform.chop(gameImage, (100, 100, 200, 200))
-
-
-
- while True:
- for event in pygame.event.get():
- if event.type == QUIT:
- terminate()
- windowSurface.fill(BACKGROUNDCOLOR)
- windowSurface.blit(gameImage, pygame.Rect(0, 0, cellWidth, cellHeight), pygame.Rect(100, 100, cellWidth, cellHeight))
- for i in range(CELLNUMS):
- rowDst = int(i / VHNUMS)
- colDst = int(i % VHNUMS)
- rectDst = pygame.Rect(colDst*cellWidth, rowDst*cellHeight, cellWidth, cellHeight)
-
- rowArea = int(gameBoard[i] / VHNUMS)
- colArea = int(gameBoard[i] % VHNUMS)
- rectArea = pygame.Rect(colArea*cellWidth, rowArea*cellHeight, cellWidth, cellHeight)
- windowSurface.blit(gameImage, rectDst, rectArea)
-
- pygame.display.update()
- mainClock.tick(FPS)
然后实现空白图像块,及保证能拼起来的随机打乱图像块算法。
随机打乱算法为实现左、右、上、下移动的算法后,随机移动若干步,则可以保证用这若干步的逆步骤使图像重新拼起来:
-
- def newGameBoard():
- board = []
- for i in range(CELLNUMS):
- board.append(i)
- blackCell = CELLNUMS-1
- board[blackCell] = -1
-
- for i in range(MAXRANDTIME):
- direction = random.randint(0, 3)
- if (direction == 0):
- blackCell = moveLeft(board, blackCell)
- elif (direction == 1):
- blackCell = moveRight(board, blackCell)
- elif (direction == 2):
- blackCell = moveUp(board, blackCell)
- elif (direction == 3):
- blackCell = moveDown(board, blackCell)
- return board, blackCell
-
-
- def moveRight(board, blackCell):
- if blackCell % VHNUMS == 0:
- return blackCell
- board[blackCell-1], board[blackCell] = board[blackCell], board[blackCell-1]
- return blackCell-1
-
-
- def moveLeft(board, blackCell):
- if blackCell % VHNUMS == VHNUMS-1:
- return blackCell
- board[blackCell+1], board[blackCell] = board[blackCell], board[blackCell+1]
- return blackCell+1
-
-
- def moveDown(board, blackCell):
- if blackCell < VHNUMS:
- return blackCell
- board[blackCell-VHNUMS], board[blackCell] = board[blackCell], board[blackCell-VHNUMS]
- return blackCell-VHNUMS
-
-
- def moveUp(board, blackCell):
- if blackCell >= CELLNUMS-VHNUMS:
- return blackCell
- board[blackCell+VHNUMS], board[blackCell] = board[blackCell], board[blackCell+VHNUMS]
- return blackCell+VHNUMS
绘制分割线:
- for i in range(VHNUMS+1):
- pygame.draw.line(windowSurface, BLACK, (i*cellWidth, 0), (i*cellWidth, gameRect.height))
- for i in range(VHNUMS+1):
- pygame.draw.line(windowSurface, BLACK, (0, i*cellHeight), (gameRect.width, i*cellHeight))
3.实现鼠标键盘事件
- if event.type == KEYDOWN:
- if event.key == K_LEFT or event.key == ord('a'):
- blackCell = moveLeft(gameBoard, blackCell)
- if event.key == K_RIGHT or event.key == ord('d'):
- blackCell = moveRight(gameBoard, blackCell)
- if event.key == K_UP or event.key == ord('w'):
- blackCell = moveUp(gameBoard, blackCell)
- if event.key == K_DOWN or event.key == ord('s'):
- blackCell = moveDown(gameBoard, blackCell)
- if event.type == MOUSEBUTTONDOWN and event.button == 1:
- x, y = pygame.mouse.get_pos()
- col = int(x / cellWidth)
- row = int(y / cellHeight)
- index = col + row*VHNUMS
- if (index == blackCell-1 or index == blackCell+1 or index == blackCell-VHNUMS or index == blackCell+VHNUMS):
- gameBoard[blackCell], gameBoard[index] = gameBoard[index], gameBoard[blackCell]
- blackCell = index
4.判断胜利
-
- def isFinished(board, blackCell):
- for i in range(CELLNUMS-1):
- if board[i] != i:
- return False
- return True
5.完整代码
- import pygame, sys, random
- from pygame.locals import *
-
-
- WINDOWWIDTH = 500
- WINDOWHEIGHT = 500
- BACKGROUNDCOLOR = (255, 255, 255)
- BLUE = (0, 0, 255)
- BLACK = (0, 0, 0)
- FPS = 40
-
- VHNUMS = 3
- CELLNUMS = VHNUMS*VHNUMS
- MAXRANDTIME = 100
-
-
- def terminate():
- pygame.quit()
- sys.exit()
-
-
- def newGameBoard():
- board = []
- for i in range(CELLNUMS):
- board.append(i)
- blackCell = CELLNUMS-1
- board[blackCell] = -1
-
- for i in range(MAXRANDTIME):
- direction = random.randint(0, 3)
- if (direction == 0):
- blackCell = moveLeft(board, blackCell)
- elif (direction == 1):
- blackCell = moveRight(board, blackCell)
- elif (direction == 2):
- blackCell = moveUp(board, blackCell)
- elif (direction == 3):
- blackCell = moveDown(board, blackCell)
- return board, blackCell
-
-
- def moveRight(board, blackCell):
- if blackCell % VHNUMS == 0:
- return blackCell
- board[blackCell-1], board[blackCell] = board[blackCell], board[blackCell-1]
- return blackCell-1
-
-
- def moveLeft(board, blackCell):
- if blackCell % VHNUMS == VHNUMS-1:
- return blackCell
- board[blackCell+1], board[blackCell] = board[blackCell], board[blackCell+1]
- return blackCell+1
-
-
- def moveDown(board, blackCell):
- if blackCell < VHNUMS:
- return blackCell
- board[blackCell-VHNUMS], board[blackCell] = board[blackCell], board[blackCell-VHNUMS]
- return blackCell-VHNUMS
-
-
- def moveUp(board, blackCell):
- if blackCell >= CELLNUMS-VHNUMS:
- return blackCell
- board[blackCell+VHNUMS], board[blackCell] = board[blackCell], board[blackCell+VHNUMS]
- return blackCell+VHNUMS
-
-
- def isFinished(board, blackCell):
- for i in range(CELLNUMS-1):
- if board[i] != i:
- return False
- return True
-
-
- pygame.init()
- mainClock = pygame.time.Clock()
-
-
- gameImage = pygame.image.load('pic.bmp')
- gameRect = gameImage.get_rect()
-
-
-
- windowSurface = pygame.display.set_mode((gameRect.width, gameRect.height))
- pygame.display.set_caption('拼图')
-
- cellWidth = int(gameRect.width / VHNUMS)
- cellHeight = int(gameRect.height / VHNUMS)
-
- finish = False
-
- gameBoard, blackCell = newGameBoard()
-
-
-
- while True:
- for event in pygame.event.get():
- if event.type == QUIT:
- terminate()
- if finish:
- continue
- if event.type == KEYDOWN:
- if event.key == K_LEFT or event.key == ord('a'):
- blackCell = moveLeft(gameBoard, blackCell)
- if event.key == K_RIGHT or event.key == ord('d'):
- blackCell = moveRight(gameBoard, blackCell)
- if event.key == K_UP or event.key == ord('w'):
- blackCell = moveUp(gameBoard, blackCell)
- if event.key == K_DOWN or event.key == ord('s'):
- blackCell = moveDown(gameBoard, blackCell)
- if event.type == MOUSEBUTTONDOWN and event.button == 1:
- x, y = pygame.mouse.get_pos()
- col = int(x / cellWidth)
- row = int(y / cellHeight)
- index = col + row*VHNUMS
- if (index == blackCell-1 or index == blackCell+1 or index == blackCell-VHNUMS or index == blackCell+VHNUMS):
- gameBoard[blackCell], gameBoard[index] = gameBoard[index], gameBoard[blackCell]
- blackCell = index
-
- if (isFinished(gameBoard, blackCell)):
- gameBoard[blackCell] = CELLNUMS-1
- finish = True
-
- windowSurface.fill(BACKGROUNDCOLOR)
-
- for i in range(CELLNUMS):
- rowDst = int(i / VHNUMS)
- colDst = int(i % VHNUMS)
- rectDst = pygame.Rect(colDst*cellWidth, rowDst*cellHeight, cellWidth, cellHeight)
-
- if gameBoard[i] == -1:
- continue
-
- rowArea = int(gameBoard[i] / VHNUMS)
- colArea = int(gameBoard[i] % VHNUMS)
- rectArea = pygame.Rect(colArea*cellWidth, rowArea*cellHeight, cellWidth, cellHeight)
- windowSurface.blit(gameImage, rectDst, rectArea)
-
- for i in range(VHNUMS+1):
- pygame.draw.line(windowSurface, BLACK, (i*cellWidth, 0), (i*cellWidth, gameRect.height))
- for i in range(VHNUMS+1):
- pygame.draw.line(windowSurface, BLACK, (0, i*cellHeight), (gameRect.width, i*cellHeight))
-
- pygame.display.update()
- mainClock.tick(FPS)