首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

使用 Python 和 Pygame 實作簡單拼圖遊戲

     編輯:更多程式設計知識

前言

本文將示範如何使用 Python 搭配 Pygame 函式庫,開發一個經典的 3x3 滑塊拼圖遊戲。程式碼包含遊戲盤面初始化、方塊移動邏輯、滑鼠鍵盤事件處理以及勝利判定等核心功能。

環境準備

請確認已安裝 Python 與 Pygame:

pip install pygame

並準備一張名為 pic.bmp 的圖片置於程式同目錄,作為拼圖素材。

核心常數設定

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()

產生隨機盤面

從有序狀態出發,隨機移動空白格 MAXRANDTIME 次,確保盤面可解。

def newGameBoard():
    board = list(range(CELLNUMS))
    blackCell = CELLNUMS - 1
    board[blackCell] = -1   # -1 代表空白格
    for _ 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 = gameRect.width // VHNUMS
cellHeight = 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 in (K_LEFT, ord('a')):
                blackCell = moveLeft(gameBoard, blackCell)
            elif event.key in (K_RIGHT, ord('d')):
                blackCell = moveRight(gameBoard, blackCell)
            elif event.key in (K_UP, ord('w')):
                blackCell = moveUp(gameBoard, blackCell)
            elif event.key in (K_DOWN, ord('s')):
                blackCell = moveDown(gameBoard, blackCell)
        elif event.type == MOUSEBUTTONDOWN and event.button == 1:
            x, y = pygame.mouse.get_pos()
            col = x // cellWidth
            row = y // cellHeight
            index = col + row * VHNUMS
            # 點擊的格子若與空白格相鄰則移動
            if index in (blackCell-1, blackCell+1, blackCell-VHNUMS, 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 = i // VHNUMS
        colDst = i % VHNUMS
        rectDst = pygame.Rect(colDst*cellWidth, rowDst*cellHeight, cellWidth, cellHeight)
        if gameBoard[i] == -1:
            continue
        rowArea = gameBoard[i] // VHNUMS
        colArea = 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))
        pygame.draw.line(windowSurface, BLACK, (0, i*cellHeight), (gameRect.width, i*cellHeight))

    pygame.display.update()
    mainClock.tick(FPS)

總結

此範例展示了 Pygame 處理圖形繪製、事件迴圈與遊戲狀態管理的基本架構。您可以嘗試擴充功能,例如增加計步器、計時器、不同難度(4x4、5x5)或自訂圖片載入介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved