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ù)分布情況,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07Python任務(wù)調(diào)度利器之APScheduler詳解
所謂的任務(wù)調(diào)度是指安排任務(wù)的執(zhí)行計劃,即何時執(zhí)行,怎么執(zhí)行等。這篇文章主要介紹了Python任務(wù)調(diào)度利器之APScheduler詳解,需要的朋友可以參考下2020-04-04Python實現(xiàn)矩陣相乘的三種方法小結(jié)
今天小編就為大家分享一篇Python實現(xiàn)矩陣相乘的三種方法小結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07python中websockets與主線程傳遞參數(shù)的實現(xiàn)
本文主要介紹了python中websockets與主線程傳遞參數(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-02-02如何將matlab數(shù)據(jù)導入到Python中使用
這篇文章主要介紹了如何將matlab數(shù)據(jù)導入到Python中使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12