欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中pygame游戲模塊的用法詳解

 更新時間:2024年01月19日 09:22:18   作者:軟件技術(shù)愛好者  
Pygame是一組用來開發(fā)游戲軟件的 Python 程序模塊,Pygame 在 SDL(Simple DirectMedia Layer) 的基礎(chǔ)上開發(fā)而成,它提供了諸多操作模塊,本文給大家介紹了Python中pygame游戲模塊的用法,需要的朋友可以參考下

Python中的pygame游戲模塊的使用

Pygame 是一組用來開發(fā)游戲軟件的 Python 程序模塊,Pygame 在 SDL(Simple DirectMedia Layer) 的基礎(chǔ)上開發(fā)而成。它提供了諸多操作模塊,比如圖像模塊(image)、聲音模塊(mixer)、輸入/輸出(鼠標、鍵盤、顯示屏)模塊,擅長開發(fā) 2D 游戲,Python 也提供了開發(fā) 3D 游戲的軟件包,比如 Pyglet、Panda3D、PyOgre 等。Pygame 是一個高可移植性的模塊可以支持多個操作系統(tǒng)。用它來開發(fā)小游戲非常適合。官網(wǎng)https://www.pygame.org/news

pygame模塊的安裝

若使用pygame模塊(python的2D游戲開發(fā)庫),這是第三方(擴展)模塊,若未預先裝,需要在CMD中,使用 pip install pygame 先裝入,可能需要花點時間。

查看是否電腦上是否有pygame,在CMD中,使用pip list命令,參見下圖

若沒有 pygame,需要在CMD中,使用 pip install pygame 命令安裝,參見下圖:

驗證是否成功安裝

法一、在CMD中,使用python -m pygame.examples.aliens命令驗證,參見下圖:

法二、進入Python的交互界面,輸入以下命令驗證是否成功安裝,參見下圖:

不報錯,則說明安裝成功。

pygame快速入門

Pygame的坐標原點(0,0)點位于左上角,X軸自左向右,Y軸自上向下,單位為像素,參見下圖:

在游戲中,所有可見的元素都是以矩形區(qū)域來描述位置的;

pygame專門提供了一個類Rect 用于 描述矩形區(qū)域,格式:

Rect(x,y,width,height)

Pygame的Rect對象,表示的區(qū)域必須位于一個 Surface 對象之上,比如游戲的主窗口(screen)。上述方法由四個關(guān)鍵參數(shù)值構(gòu)成,分別是 left、top、width、height

pygame. Rect(left, top, width, height)

display 用于創(chuàng)建、管理游戲窗口

pygame.display.set_mode()    #初始化游戲顯示窗口

pygame.dispaly.update()      #刷新屏幕內(nèi)容顯示,稍后使用

為了做到游戲程序啟動后,不會立即退出,通常會在游戲程序中使用一個游戲循環(huán)。

pygame開發(fā)游戲的大體框架結(jié)構(gòu)如下:

import pygame
 
# 初始化pygame
pygame.init()
 
# 創(chuàng)建游戲的窗口  350 * 573(寬,高);注意:此窗口的大小是依據(jù)游戲的背景圖片而設(shè)定的
screen=pygame.display.set_mode((350,600))
 
# 游戲循環(huán)
while True:
    pass
 

示例代碼如下:

# 導入所需的模塊
import pygame
import sys
# 導入所有pygame.locals里的變量(比如下面大寫的QUIT變量)
from pygame.locals import *
 
# 初始化pygame
pygame.init()
 
# 設(shè)置窗口的大小,單位為像素
screen = pygame.display.set_mode((450, 300))
 
# 設(shè)置窗口標題
pygame.display.set_caption('Hello World')
 
# 程序主循環(huán)
while True:
 
  # 獲取事件
  for event in pygame.event.get():
    # 判斷事件是否為退出事件
    if event.type == QUIT:
      # 退出pygame
      pygame.quit()
      # 退出系統(tǒng)
      sys.exit()
 
  # 繪制屏幕內(nèi)容
  pygame.display.update()
 

運行之,顯示如下:

Pygame設(shè)置窗口圖標和設(shè)置窗口背景圖片

#設(shè)置窗口圖標,下面兩句
icon = pygame.image.load("./images/xyicon.png") # 加載圖像數(shù)據(jù)
pygame.display.set_icon(icon)  #設(shè)置圖標  

#設(shè)置窗口背景圖片,下面三兩句
bg = pygame.image.load("./images/background.png") # 加載圖像數(shù)據(jù)
screen.blit(bg,(0,0)) #繪制圖像 blit(圖像,位置);
pygame.display.update() #更新屏幕顯示

在前面示例代碼,設(shè)置窗口標題之后,添加設(shè)置窗口圖標和設(shè)置窗口背景圖片:

運行之,如下圖所示:

Pygame播放音頻

有兩個方法:

☆播放特效聲音:

pygame.mixer.Sound(filename)

該方法返回一個Sound對象,調(diào)用它的.play( )方法,即可播放較短的音頻文件(如游戲中的槍炮聲等);

☆播放背景音樂:

pygame.mixer.music.load(filename)

該方法用來加載背景音樂,之后調(diào)用pygame.mixer.music.play( )方法就可以播放背景音樂(在同一個時刻只允許加載一個背景音樂)

# 加載并播放一個特效音頻文件)

sound = pygame.mixer.Sound('./music/alter.mp3')

sound.play()

# 加載背景音樂文件

pygame.mixer.music.load('./music/bgmusic.mp3')

# 播放背景音樂,第一個參數(shù)為播放的次數(shù)(-1表示無限循環(huán)),第二個參數(shù)是設(shè)置播放的起點(單位為秒)

pygame.mixer.music.play(-1, 0.0)

可以在適當?shù)牡胤?,作為測試在背景圖片之后插入播放音頻代碼段,當然音頻文件需要準備好。

Pygame繪制圖形

Pygame繪制圖形的常用的方法:

☆ pygame.draw.line(Surface, color, start_pos, end_pos, width)此方法用于繪制一條線段

☆ pygame.draw.aaline(Surface, color, start_pos, end_pos, blend)此方法用于繪制一條抗鋸齒的線

☆ pygame.draw.lines(Surface, color, closed, pointlist, width)此方法用于繪制一條折線

☆ pygame.draw.rect(Surface, color, Rect)此方法用于繪制一個矩形

☆ pygame.draw.rect(Surface, color, Rect, width)此方法用于繪制一個矩形框

☆ pygame.draw.ellipse(Surface, color, Rect)此方法用于繪制一個橢圓

☆ pygame.draw.ellipse(Surface, color, Rect, width)此方法用于繪制一個橢圓框

☆ pygame.draw.polygon(Surface, color, pointlist, width)此方法用于繪制一個多邊形

☆ pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width)此方法用于繪制一條弧線

☆ pygame.draw.circle(Surface, color, Rect, radius)此方法用于繪制一個圓

示例代碼

# 導入需要的模塊
import pygame, sys
from pygame.locals import *
from math import pi
 
# 初始化pygame
pygame.init()
 
# 設(shè)置窗口的大小,單位為像素
screen = pygame.display.set_mode((400,300))
 
# 設(shè)置窗口標題
pygame.display.set_caption('Drawing')
 
# 定義顏色
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
 
# 設(shè)置背景顏色
screen.fill(WHITE)
 
# 繪制一條線
pygame.draw.line(screen, GREEN, [10, 10], [50,30], 5)
 
# 繪制一條抗鋸齒的線
pygame.draw.aaline(screen, GREEN, [10, 50],[50, 80],True)
 
# 繪制一條折線
pygame.draw.lines(screen, BLACK, False,[[10, 80], [50, 90], [200, 80], [220, 30]], 5)
 
# 繪制一個空心矩形
pygame.draw.rect(screen, BLACK, [75, 10, 50, 20], 2)
 
# 繪制一個矩形
pygame.draw.rect(screen, BLACK, [150, 10, 50, 20])
 
# 繪制一個空心橢圓
pygame.draw.ellipse(screen, RED, [225, 10, 50, 20], 2)
 
# 繪制一個橢圓
pygame.draw.ellipse(screen, RED, [300, 10, 50, 20])
 
# 繪制多邊形
pygame.draw.polygon(screen, BLACK, [[100, 100], [0, 200], [200, 200]], 5)
 
# 繪制多條弧線
pygame.draw.arc(screen, BLACK,[210, 75, 150, 125], 0, pi/2, 2)
pygame.draw.arc(screen, GREEN,[210, 75, 150, 125], pi/2, pi, 2)
pygame.draw.arc(screen, BLUE, [210, 75, 150, 125], pi,3*pi/2, 2)
pygame.draw.arc(screen, RED, [210, 75, 150, 125], 3*pi/2, 2*pi, 2)
 
# 繪制一個圓
pygame.draw.circle(screen, BLUE, [60, 250], 40)
 
# 程序主循環(huán)
while True:
 
  # 獲取事件
  for event in pygame.event.get():
    # 判斷事件是否為退出事件
    if event.type == QUIT:
      # 退出pygame
      pygame.quit()
      # 退出系統(tǒng)
      sys.exit()
 
  # 繪制屏幕內(nèi)容
  pygame.display.update()
 

運行之,顯示如下:

Pygame繪制文字

Pygame不僅可以在屏幕上繪制形狀,還可以將文本繪制到屏幕上。Pygame 提供了一些非常簡單易用的函數(shù),可以創(chuàng)建字體和文本。字體(font)是字體類型的一種描述,表示按照統(tǒng)一風格繪制的一整套的字母、數(shù)字、符號和字符,例如 宋體 和 Times New Roman 都是字體。

☆font.SysFont()函數(shù)來創(chuàng)建一個 Font 對象,這個函數(shù)有兩個參數(shù),第 1 個參數(shù)是字體名稱,第 2 個參數(shù)是字體大?。ㄒ韵袼攸c為單位)

☆font.render()函數(shù)的參數(shù):第 1 個參數(shù)是要繪制的文本的字符串;第 2 個參數(shù)指定是否想要抗鋸齒的一個 Boolean 值,如果是 True,文本看上去更加平滑一些;第 3 個參數(shù)是用來渲染文本的顏色,這個例子中使用的是白色。

☆blit() 函數(shù),將像素從一個 Surface 復制到另一個 Surface 之上。常用兩個參數(shù):第一個參數(shù)是某矩形圖像(Surface實例),第二個參數(shù)用于指定繪制的位置。

示例代碼

import pygame
import sys
from pygame.locals import *
 
pygame.init()
wS=pygame.display.set_mode((400,300)) #創(chuàng)建畫布名稱wS
WHITE=(255,255,255)
myString="Hello World!"
font = pygame.font.SysFont("Times New Roman", 48) #來創(chuàng)建 Font對象
text = font.render(myString, True, WHITE)
wS.blit(text, (100,150))  #將text復制到指定位置(100,150)
 
# 程序主循環(huán)
while True:
 
  # 獲取事件
  for event in pygame.event.get():
    # 判斷事件是否為退出事件
    if event.type == QUIT:
      # 退出pygame
      pygame.quit()
      # 退出系統(tǒng)
      sys.exit()
 
  # 繪制屏幕內(nèi)容
  pygame.display.update()
 

運行之,顯示如下:

Pygame實現(xiàn)動畫

Pygame實現(xiàn)動畫

由于人類眼睛的特殊生理結(jié)構(gòu),當所看畫面的幀率高于24的時候,就會認為是連貫的。

幀率(Frame rate)是用于測量顯示幀數(shù)的量度,所謂的測量單位為每秒顯示幀數(shù)(Frames per Second,簡稱:FPS)。

在原有坐標系的基礎(chǔ)上添加偏移量,再重新繪制,依次一張一張的循環(huán)繪制下去,就會得到我們想要的物體移動的效果。

Pygame實現(xiàn)動畫主要用到的方法:

☆ pygame.image.load(filename) 加載一張圖片

☆pygame.Surface.blit(source, dest, area=None, special_flags = 0) 將圖片繪制到屏幕相應坐標上(后面兩個參數(shù)默認,可以不傳)

☆pygame.time.Clock() 獲得pygame的時鐘

☆pygame.time.Clock.tick(FPS) 設(shè)置pygame時鐘的間隔時間

示例代碼如下:

# 導入需要的模塊
import pygame, sys
from pygame.locals import *
 
# 初始化pygame
pygame.init()
 
# 設(shè)置幀率(屏幕每秒刷新的次數(shù))
FPS = 30
 
# 獲得pygame的時鐘
fpsClock = pygame.time.Clock()
 
# 設(shè)置窗口大小
screen = pygame.display.set_mode((500, 400), 0, 32)
 
# 設(shè)置標題
pygame.display.set_caption('Animation')
 
# 定義顏色
WHITE = (255, 255, 255)
 
# 加載一張圖片
img = pygame.image.load('./images/bird.png')
 
# 初始化圖片的位置
imgx = 10
imgy = 10
 
# 初始化圖片的移動方向
direction = 'right'
 
# 程序主循環(huán)
while True:
 
  # 每次都要重新繪制背景白色
  screen.fill(WHITE)
 
  # 判斷移動的方向,并對相應的坐標做加減
  if direction == 'right':
    imgx += 5
    if imgx == 380:
      direction = 'down'
  elif direction == 'down':
    imgy += 5
    if imgy == 300:
      direction = 'left'
  elif direction == 'left':
    imgx -= 5
    if imgx == 10:
      direction = 'up'
  elif direction == 'up':
    imgy -= 5
    if imgy == 10:
      direction = 'right'
 
  # 該方法將用于圖片繪制到相應的坐標中
  screen.blit(img, (imgx, imgy))
 
  for event in pygame.event.get():
    if event.type == QUIT:
      pygame.quit()
      sys.exit()
 
  # 刷新屏幕
  pygame.display.update()
 
  # 設(shè)置pygame時鐘的間隔時間
  fpsClock.tick(FPS)

Pygame事件簡介

pygame事件可以處理游戲中的各種事情,事件是一個概念,比如點擊鼠標左鍵,按下一個鍵盤的按鍵,關(guān)閉窗口等等都是一個事件,pygame提供了一個函數(shù)來獲取游戲的事件,并把他們存放在一個隊列中,程序通過讀取整個事件隊列,來獲取當前發(fā)生的時間,并作出響應。

Pygame常用的事件如下表:

事件

產(chǎn)生途徑

參數(shù)

QUIT

用戶按下關(guān)閉按鈕

none

ACTIVEEVENT

Pygame被激活或者隱藏

gain, state

KEYDOWN

鍵盤被按下

unicode, key, mod

KEYUP

鍵盤被放開

key, mod

MOUSEMOTION

鼠標移動

pos, rel, buttons

MOUSEBUTTONDOWN

鼠標按下

pos, button

MOUSEBUTTONUP

鼠標放開

pos, button

VIDEORESIZE

Pygame窗口縮放

size, w, h

示例代碼:

# 導入需要的模塊
import pygame, sys
from pygame.locals import *
 
# 定義顏色
WHITE = (255, 255, 255)
 
# 初始化pygame
pygame.init()
 
# 設(shè)置窗口的大小,單位為像素
screen = pygame.display.set_mode((500,400), 0, 32)
 
# 設(shè)置窗口的標題
pygame.display.set_caption('Event')
 
# 設(shè)置背景
screen.fill(WHITE)
 
# 程序主循環(huán)
while True:
 
  # 獲取事件
  for event in pygame.event.get():
    # 判斷事件是否為退出事件
    if event.type == QUIT:
      # 退出pygame
      pygame.quit()
      # 退出系統(tǒng)
      sys.exit()
 
     
    # 獲得鼠標按下的位置
    if event.type ==MOUSEBUTTONDOWN:
      print("鼠標按下:",event.pos)
 
    # 獲得鼠標抬起的位置
    if event.type ==MOUSEBUTTONUP:
      print("鼠標抬起:",event.pos) 
 
    # 獲得鍵盤方向鍵按下的事件  
    if event.type == KEYDOWN:
      if(event.key==K_UP or event.key==K_w):
        print("上")
      if(event.key==K_DOWN or event.key==K_s):
        print("下")
      if(event.key==K_LEFT or event.key==K_a):
        print("左")
      if(event.key==K_RIGHT or event.key==K_d):
        print("右")
      # 按下鍵盤的Esc鍵退出
      if(event.key==K_ESCAPE):
        # 退出pygame
        pygame.quit()
        # 退出系統(tǒng)
        sys.exit()
 
  # 繪制屏幕內(nèi)容
  pygame.display.update()
  

效果圖如下:

綜合例子

下面給出綜合例子

1、畫一個小房子,房前有樹,樹頂上有太陽

先給出效果圖:

源碼如下:

import pygame
import sys
 
# 初始化pygame
pygame.init()
 
# 設(shè)置窗口尺寸
width, height = 861, 594
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('畫圖')
 
# 定義顏色
WHITE = (255, 255, 255)
ORANGE = (255, 165, 0)
BROWN = (165, 42, 42)
GREEN = (0, 128, 0)
RED = (255, 0, 0)
GRAY = (128, 128, 128)
 
# 繪制背景
screen.fill(WHITE)
 
# 畫房子
pygame.draw.polygon(screen, GRAY, [(150, 300), (350, 300), (250, 200)])  # 房子的屋頂
pygame.draw.polygon(screen, ORANGE, [(150, 400), (350, 400), (350, 300), (150, 300)])  # 房子的底部
 
# 畫房子的門和窗戶
pygame.draw.rect(screen, WHITE, (180, 350, 30, 30))  # 窗戶1
pygame.draw.rect(screen, WHITE, (230, 350, 40, 50))  # 門
pygame.draw.rect(screen, WHITE, (290, 350, 30, 30))  # 窗戶2
 
# 畫樹1
pygame.draw.rect(screen, BROWN, (400, 300, 20, 100))  # 樹干
pygame.draw.circle(screen, GREEN, (410, 250), 50)  # 樹冠
 
# 畫樹2 
pygame.draw.rect(screen, BROWN, (560, 300, 40, 150)) # 繪制樹干
# 繪制樹冠
pygame.draw.circle(screen, GREEN, (550, 250), 50)
pygame.draw.circle(screen, GREEN, (620, 250), 50)
pygame.draw.circle(screen, GREEN, (590, 220), 50)
pygame.draw.circle(screen, GREEN, (560, 280), 50)
pygame.draw.circle(screen, GREEN, (610, 280), 50)
 
# 畫太陽
pygame.draw.circle(screen, RED, (650, 50), 25)  # 太陽
 
# 刷新屏幕
pygame.display.flip()
 
# 保持窗口打開
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

2、用方向鍵控制小貓移動示例

需要兩個素材文件:小貓圖片 cat.png 和背景圖片bg1.jpg,為簡便將它們 和源碼程序文件,放在同一文件夾中。

源碼如下:

import sys
import pygame
from pygame.locals import *
 
def control_ball(event):
    speed = [x,y] =[0,0]# 設(shè)置相對位移
    speed_offset = 1 #小球的速度
 
# 如果事件的類型是 鍵盤輸入,就根據(jù)方向鍵來求出速度的方向(默認是從左往右為1,從上往下為1)
    if event.type == KEYDOWN:
        if event.key == pygame.K_LEFT:
            speed[0] -= speed_offset
            event.key
 
        if event.key == pygame.K_RIGHT:
            speed[0] = speed_offset
            event.key
 
        if event.key == pygame.K_UP:
            speed[1] -= speed_offset
            event.key
 
        if event.key == pygame.K_DOWN:
            speed[1] = speed_offset
            event.key
 
    #如果沒有方向鍵的輸入,則速度為0,小球不動
    if event.type in (pygame.K_UP, pygame.K_LEFT, pygame.K_RIGHT, pygame.K_DOWN):
        speed = [0,0]
 
    return speed
    
#定義函數(shù)
def play_ball():
    pygame.init()#初始化
    window_size = Rect(0,0,600,440)#設(shè)置窗口的大小
    
    screen = pygame.display.set_mode(window_size.size)#設(shè)置窗口模式
    pygame.display.set_caption('hello  cat')#設(shè)置窗口標題
    ball_image = pygame.image.load('cat.png')#載入小球圖片
    back_image = pygame.image.load('bg1.jpg')#載入背景圖片
    ball_rect = ball_image.get_rect()# 獲取小球圖片所在的區(qū)域
 
    while True:
        #退出事件的處理
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
                
        control_speed = control_ball(event)#獲取到小球的方向
        ball_rect = ball_rect.move(control_speed).clamp(window_size)#小球按照方向移動,并且不會移出窗口。
 
        screen.blit(back_image,(0,0))#設(shè)置窗口背景,位于(0,0)處,窗口左上角。
        screen.blit(ball_image, ball_rect)#把小球繪制到背景surface上。
 
        pygame.display.flip()#更新窗口內(nèi)容       
 
#調(diào)用函數(shù)
play_ball()
 

3、拼圖游戲

兩種實現(xiàn):點擊交換式和拖動交換式

★拼圖游戲之點擊交換式

加載一張圖片分塊打亂,用戶用鼠標單擊兩塊圖片則兩塊圖片交換位置,拼圖完成后提示成功。確保圖像文件存在并與代碼中指定的路徑相匹配——我這里圖片名是player.png,和源碼文件放在同一文件夾中。

源碼如下: 

import random
from sys import exit  # 使用sys模塊的exit函數(shù)來退出游戲
import pygame
from pygame.locals import *  # 導入一些常用的函數(shù)和常量
from tkinter import messagebox #導入messagebox模塊
 
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
ROW = 0
COL = 0
CELL_WIDTH = 0 #SCREEN_WIDTH / COL
CELL_HEIGHT = 0 #SCREEN_HEIGHT / ROW
 
firstClickCell = None
 
# 標記是否游戲成功
successFlag = False
 
gamePictures='player.png' ##游戲圖片##
 
pygame.init()  # 初始化pygame
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))  # 創(chuàng)建了一個窗口 大小是(寬,高)
pygame.display.set_caption('單擊交換式拼圖')  # 設(shè)置窗口標題
 
scaled_image =pygame.transform.scale(pygame.image.load(gamePictures), (SCREEN_WIDTH//6, SCREEN_HEIGHT//6)) #加載原始圖片縮小
 
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
WHITE = (255, 255, 255)
myfont = pygame.font.SysFont('KaiTi', 60) #None系統(tǒng)默認字體,楷體:KaiTi
textImage1 = myfont.render("難度級別 1", True , GREEN)
textImage2 = myfont.render("難度級別 2", True , BLUE)
textImage3 = myfont.render("難度級別 3", True , RED)
myfont = pygame.font.SysFont('SimHei', 20) #黑體:SimHei
textImage4 = myfont.render("選取上面難度等級進入游戲;用戶用鼠標單擊", True , WHITE)
textImage5 = myfont.render("兩個已打亂順序的小圖塊則這兩塊交換位置。", True , WHITE)
 
screen.fill((0,0,0))
screen.blit(scaled_image, (0, 0))
screen.blit(textImage1, (150, 100))
screen.blit(textImage2, (150, 250))
screen.blit(textImage3, (150, 400))
screen.blit(textImage4, (100, 500))
screen.blit(textImage5, (100, 530))
pygame.display.update()
 
class PartPicture:
    # 初始化一個圖片分塊,保存圖像和圖像的位置, id代表原圖第幾塊的位置
    def __init__(self, img, x, y, id):
        self.img = img
        self.x = x
        self.y = y
        self.id = id
    # 判斷是否在圖片內(nèi)
    def isOver(self):
        w, h = self.img.get_size()
        point_x, point_y = pygame.mouse.get_pos()  # 返回鼠標當前坐標
        in_x = self.x < point_x < self.x + w
        in_y = self.y < point_y < self.y + h
        return in_x and in_y
    # 檢測移動
    def isPressed(self, pictureList):
        # print('is_pressed')
        if self.isOver():
            b1, b2, b3 = pygame.mouse.get_pressed()
            if b1 == 1:
                global firstClickCell
                global successFlag
 
                if firstClickCell is None:
                    firstClickCell = self
                    print('id為{}的塊被點擊'.format(firstClickCell.getId()))
                else:
                    print('交換{}與{}的坐標'.format(firstClickCell.getId(), self.getId()))
                    self.pictureSwitch(firstClickCell, self)
                    if self.isFinish(pictureList):
                        successFlag = True
                        print('成功!')         
                    else:
                        successFlag = False
                    firstClickCell = None
                return True
        return False
    
    # 判斷拼圖完成
    def isFinish(self, pictureList):
        for cell in  pictureList:
            nowp_x, nowp_y = cell.getXY()
            p_x = cell.getId() % COL * CELL_WIDTH
            p_y = (cell.getId() // COL) * CELL_HEIGHT
            print("id{} nowx{}與nowy{}的坐標 本來的坐標x{}y{}".format(cell.getId(), nowp_x, nowp_y, p_x, p_y))
            if nowp_x != p_x or nowp_y != p_y:
                return False
        return True
 
    def pictureSwitch(self, cell1, cell2):
        tempX = cell1.getX()
        tempY = cell1.getY()
        cell1.setXY(cell2.getX(), cell2.getY())
        cell2.setXY(tempX, tempY)
        
    def render(self, screen):
        screen.blit(self.img, (self.x, self.y))
        
    # get和set方法
    def getX(self):
        return self.x;
    def getY(self):
        return self.y
    # 獲取圖片坐標
    def getXY(self):
        return self.x, self.y
    # 修改圖片坐標
    def setXY(self,x, y):
        self.x = x
        self.y = y
    # 獲取id
    def getId(self):
        return self.id
    
# 圖片分塊
def devide(imgSrc):
    # 切割原來的圖片
    pictures = []
    ScPictures = []
    id = 0 # 給每個分塊的圖片設(shè)置下標
    for i in range(ROW):
        for j in range(COL):
            # 提取部分圖片
            partOfPicutre = imgSrc.subsurface(j * CELL_WIDTH, i * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT)
            # 保存第一組圖片
            tempPicture = PartPicture(partOfPicutre, j * CELL_WIDTH, i * CELL_HEIGHT, id)
            pictures.append(tempPicture)
            # 保存第二組圖片
            tempPicture = PartPicture(partOfPicutre, j * CELL_WIDTH, i * CELL_HEIGHT, id)
            ScPictures.append(tempPicture)
            id += 1
    random.shuffle(pictures)
    # 開始利用第二組圖片來打亂原來的圖片
    for i in range(len(pictures)):
        pictures[i].setXY(ScPictures[i].getX(), ScPictures[i].getY())
    return pictures # 把打亂的圖片返回
 
setInit = False
while True:
    if setInit:
        break
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()  # 接收到退出事件后退出程序
        elif event.type == MOUSEBUTTONDOWN:
            b1, b2, b3 = pygame.mouse.get_pressed()
            if b1 == 1:
                point_x, point_y = pygame.mouse.get_pos()  # 返回鼠標當前坐標
                if 100 < point_y < 200:
                    ROW = 3
                    COL = 3
                    setInit = True
                elif 250 < point_y < 350:
                    ROW = 4
                    COL = 4
                    setInit = True
                elif 350 < point_y < 450:
                    ROW = 5
                    COL = 5
                    setInit = True
 
CELL_WIDTH = SCREEN_WIDTH / COL
CELL_HEIGHT = SCREEN_HEIGHT / ROW
# 原圖 提高 blit 的速度 convert_alpha相對于convert,保留了圖像的Alpha 通道信息,可以認為是保留了透明的部分,實現(xiàn)了透明轉(zhuǎn)換
imgSrc = pygame.image.load(gamePictures).convert() ##加載游戲圖片
PictureList = devide(imgSrc) #圖片分塊
 
while True:  # 游戲主循環(huán)
    for event in pygame.event.get():        
        if event.type == QUIT:
            exit()  # 接收到退出事件后退出程序
        elif event.type == MOUSEBUTTONDOWN:
            for cell in PictureList:
                # 檢測按鍵按下,并且交換圖片位置
                if cell.isPressed(PictureList):
                    break
    for partPicture in PictureList:
        partPicture.render(screen)
    if not successFlag:
        # # Sta 繪制分割線
        for i in range(1, COL):
            pygame.draw.lines(screen, GREEN, 0, [(i * SCREEN_WIDTH // COL, 0), (i * SCREEN_WIDTH // COL, SCREEN_HEIGHT)], 1)
        for i in range(1, ROW):
            pygame.draw.lines(screen, GREEN, 0, [(0, i * SCREEN_HEIGHT // ROW), (SCREEN_WIDTH, i * SCREEN_HEIGHT // ROW)], 1)
        # End 繪制分割線
    pygame.display.update()  # 刷新一下畫面
 
    if successFlag:
        messagebox.showinfo("祝賀你!", "成功完成!")
        break

效果示意圖如下:

★拼圖游戲之拖動交換式

下面給出拼圖游戲的另一種實現(xiàn)

功能:窗體上有兩個按鈕,單擊"open"按鈕加載的游戲圖片,單擊"start"按鈕將加載的游戲圖片分割成9小塊打亂排列。游戲規(guī)則:將一個小塊拖動到另一小塊時,兩小塊圖片將交換位置,當恢復原樣時,提示"success!"。

源碼如下:

import pygame
import random
import sys
import tkinter as tk
from tkinter import filedialog
 
# 初始化Tkinter
root = tk.Tk()
root.withdraw()
 
# 初始化游戲
pygame.init()
 
# 設(shè)置游戲窗口尺寸
WIDTH = 600
HEIGHT = 600
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("拼圖游戲:拖動交換小塊圖")
 
# 設(shè)置顏色
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
 
# 設(shè)置字體
font = pygame.font.Font(None, 36)
 
# 設(shè)置拼圖塊的尺寸和間隙
BLOCK_SIZE = 200
BLOCK_MARGIN = 5
 
# 設(shè)置拼圖塊的初始位置
block_positions = [(j * (BLOCK_SIZE + BLOCK_MARGIN), i * (BLOCK_SIZE + BLOCK_MARGIN))
                   for i in range(3) for j in range(3)]
 
# 拼圖塊的當前位置
current_positions = block_positions.copy()
 
# 游戲狀態(tài)
game_started = False
puzzle_completed = False
 
# 選中的拼圖塊
selected_block = None
selected_block_index = None
 
# 加載游戲圖片
original_image = None
block_images = []
 
def load_image():
    global original_image, block_images
    # 選擇并加載計算機中的圖片
    file_path = filedialog.askopenfilename()
    if file_path:
        try:
            original_image = pygame.image.load(file_path)
            original_image = pygame.transform.scale(original_image, (BLOCK_SIZE * 3, BLOCK_SIZE * 3))
 
            # 分割原始圖片為拼圖塊
            block_images = []
            for i in range(3):
                for j in range(3):
                    block_images.append(original_image.subsurface(pygame.Rect(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)))
                    
            # 重置游戲狀態(tài)
            global game_started, puzzle_completed
            game_started = False
            puzzle_completed = False
        except pygame.error:
            print("加載圖片失?。?)
            sys.exit(1)
 
# 檢查拼圖是否完成
def check_puzzle_completed():
    global puzzle_completed
    puzzle_completed = all(current_positions[i] == block_positions[i] for i in range(len(current_positions)))
 
# "start"按鈕的點擊事件處理
def start_game():
    global game_started, puzzle_completed, current_positions
    if original_image is not None:
        current_positions = block_positions.copy()
        random.shuffle(current_positions)
        game_started = True
        puzzle_completed = False
 
# 交換拼圖塊位置
def swap_pieces(pos1, pos2):
    current_positions[pos1], current_positions[pos2] = current_positions[pos2], current_positions[pos1]
 
# 獲取拼圖塊索引
def get_block_index(position):
    for i, pos in enumerate(current_positions):
        if pos == position:
            return i
    return None
 
# 游戲主循環(huán)
running = True
clock = pygame.time.Clock()
 
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if 50 <= event.pos[0] <= 180 and 50 <= event.pos[1] <= 80:
                load_image()  # 當鼠標在"open"按鈕區(qū)域內(nèi)按下時,調(diào)用load_image()函數(shù)加載圖片
            elif game_started and not puzzle_completed:
                for i, position in enumerate(current_positions):
                    block_rect = pygame.Rect((position[0], position[1]), (BLOCK_SIZE, BLOCK_SIZE))
                    if block_rect.collidepoint(event.pos):
                        selected_block = position  # 記錄選中的拼圖塊的位置
                        selected_block_index = i  # 記錄選中的拼圖塊的索引
                        break
            elif 200 <= event.pos[0] <= 330 and 50 <= event.pos[1] <= 80:
                start_game()  # 當鼠標在"start"按鈕區(qū)域內(nèi)按下時,調(diào)用start_game()函數(shù)開始游戲
        elif event.type == pygame.MOUSEBUTTONUP:
            if game_started and not puzzle_completed and selected_block is not None:
                for i, position in enumerate(current_positions):
                    block_rect = pygame.Rect((position[0], position[1]), (BLOCK_SIZE, BLOCK_SIZE))
                    if block_rect.collidepoint(event.pos) and selected_block != position:
                        swap_pieces(selected_block_index, i)  # 交換選中的拼圖塊與鼠標釋放位置上的拼圖塊的位置
                        break
                selected_block = None
                selected_block_index = None
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:
                if original_image is not None:
                    random.shuffle(current_positions)  # 按下"r"鍵后,隨機洗牌拼圖塊的位置
                    game_started = True
                    puzzle_completed = False
            elif event.key == pygame.K_q:
                running = False  # 按下"q"鍵后,退出游戲循環(huán)
 
    window.fill(WHITE)  # 填充窗口背景顏色為白色
 
    if original_image is not None:
        for i in range(len(current_positions)):
            position = current_positions[i]
            pygame.draw.rect(window, BLUE, (position[0], position[1], BLOCK_SIZE, BLOCK_SIZE))  # 繪制拼圖塊的矩形邊框
            window.blit(block_images[i], position)  # 在拼圖塊的位置上繪制對應的圖像
 
    pygame.draw.rect(window, BLUE, (50, 50, 130, 30))  # 繪制"open"按鈕的矩形邊框
    open_text = font.render("open", True, WHITE)  # 創(chuàng)建渲染的"open"文本圖像
    window.blit(open_text, (90, 55))  # 在窗口上繪制"open"文本圖像
 
    pygame.draw.rect(window, BLUE, (200, 50, 130, 30))  # 繪制"start"按鈕的矩形邊框
    start_text = font.render("start", True, WHITE)  # 創(chuàng)建渲染的"start"文本圖像
    window.blit(start_text, (235, 55))  # 在窗口上繪制"start"文本圖像
 
    check_puzzle_completed()  # 檢查拼圖是否完成
 
    if puzzle_completed:
        success_text = font.render("success!", True, WHITE)  # 創(chuàng)建渲染的"success!"文本圖像
        success_text_rect = success_text.get_rect(center=(WIDTH // 2, HEIGHT // 2))  # 計算"success!"文本圖像的中心位置
        window.blit(success_text, success_text_rect)  # 在窗口上繪制"success!"文本圖像
 
    pygame.display.flip()  # 更新窗口顯示
    clock.tick(60)  # 控制游戲循環(huán)的幀率為60幀每秒
 
pygame.quit()

在此就不給出效果示意圖了,你可以試試。

總結(jié)

以上就是Python中pygame游戲模塊的用法詳解的詳細內(nèi)容,更多關(guān)于Python pygame游戲模塊的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python實現(xiàn)畫箱線圖展示數(shù)據(jù)分布情況

    Python實現(xiàn)畫箱線圖展示數(shù)據(jù)分布情況

    這篇文章主要介紹了Python實現(xiàn)畫箱線圖展示數(shù)據(jù)分布情況,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Python實現(xiàn)從概率分布中隨機采樣

    Python實現(xiàn)從概率分布中隨機采樣

    這篇文章主要介紹了通過幾個機器學習中最常用的概率分布為例,來看看如何從一個概率分布中采樣,文章中的代碼對我們的工作或?qū)W習具有一定價值,感興趣的朋友可以了解一下
    2021-12-12
  • python中的3種定義類方法

    python中的3種定義類方法

    這篇文章主要給大家分享得是 python中的3種定義類方法,分別是普通方法、類方法(@classmethod)以及類方法(@classmethod),想了解方法具體實現(xiàn)的小伙伴可以參考下面文章內(nèi)容哦,希望對你有所幫助
    2021-11-11
  • Python任務(wù)調(diào)度利器之APScheduler詳解

    Python任務(wù)調(diào)度利器之APScheduler詳解

    所謂的任務(wù)調(diào)度是指安排任務(wù)的執(zhí)行計劃,即何時執(zhí)行,怎么執(zhí)行等。這篇文章主要介紹了Python任務(wù)調(diào)度利器之APScheduler詳解,需要的朋友可以參考下
    2020-04-04
  • Python實現(xiàn)矩陣相乘的三種方法小結(jié)

    Python實現(xiàn)矩陣相乘的三種方法小結(jié)

    今天小編就為大家分享一篇Python實現(xiàn)矩陣相乘的三種方法小結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • 讓Python更加充分的使用Sqlite3

    讓Python更加充分的使用Sqlite3

    這篇文章主要為大家詳細介紹了Python更加充分的使用Sqlite3的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • python中websockets與主線程傳遞參數(shù)的實現(xiàn)

    python中websockets與主線程傳遞參數(shù)的實現(xiàn)

    本文主要介紹了python中websockets與主線程傳遞參數(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-02-02
  • 如何將matlab數(shù)據(jù)導入到Python中使用

    如何將matlab數(shù)據(jù)導入到Python中使用

    這篇文章主要介紹了如何將matlab數(shù)據(jù)導入到Python中使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • python動態(tài)文本進度條的實例代碼

    python動態(tài)文本進度條的實例代碼

    這篇文章主要介紹了python動態(tài)文本進度條的實例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • Python如何實現(xiàn)機器人聊天

    Python如何實現(xiàn)機器人聊天

    這篇文章主要介紹了Python如何實現(xiàn)機器人聊天,幫助大家更好的理解和學習python,感興趣的朋友可以了解下
    2020-09-09

最新評論