小朋友們好,大朋友們好!
我是貓妹,一名愛(ài)上Python編程的小學(xué)生。
歡迎和貓妹一起,趣味學(xué)Python。
今日主題
你玩過(guò)游戲嗎?
你喜歡玩游戲嗎?
手機(jī)游戲,電腦游戲,還是游戲機(jī)游戲?
pygame是一個(gè)跨平臺(tái)Python庫(kù),pygame 作者是 Pete Shinners, 協(xié)議為 GNU Lesser General Public License。
pygame官網(wǎng)上有許多游戲,如下圖:

咱們今天簡(jiǎn)單學(xué)習(xí)下pygame,了解用它做游戲的簡(jiǎn)單流程。
使用前,需要用pip安裝下pygame庫(kù)。
一、繪制窗口

import sys
import pygame
from pygame.locals import *
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED? = (255, 0, 0)
pygame.init()
clock = pygame.time.Clock()
clock.tick(60)
pygame.display.set_caption("瘋狂賽車(chē)")
screen = pygame.display.set_mode((500, 800))
screen.fill(WHITE)
pygame.display.update()
while True:
? ? for event in pygame.event.get():
? ? ? ? if event.type == QUIT:
? ? ? ? ? ? pygame.quit()
? ? ? ? ? ? sys.exit()
? ? pygame.display.update()
2行:導(dǎo)入pygame庫(kù)
3行:導(dǎo)入pygame庫(kù)中的局部變量
5~7行:定義單個(gè)顏色RGB變量
9行:該函數(shù)在使用pygame時(shí)進(jìn)行初始化,只有引用了該函數(shù)才能使用pygame提供的所用功能。
10行:實(shí)例化Clock對(duì)象
11行:設(shè)置每秒60幀,每秒更新不超過(guò)60次。
幀速率是指程序每秒在屏幕上繪制圖像的數(shù)目,我們可以用FPS來(lái)表示它。
一般的計(jì)算機(jī)都能達(dá)到每秒60幀的速度。如果我們把幀速率講得比較低,游戲會(huì)看上去較為卡頓。
pygame.time.Clock對(duì)象幫助我們確定程序要以多少最大的幀速率運(yùn)行。
13行:設(shè)置窗口的名稱(chēng)
14行:設(shè)置游戲窗口大小
15行:設(shè)置窗口填充顏色
16行:刷新屏幕內(nèi)容顯示
18~23行:當(dāng)玩家點(diǎn)擊退出時(shí)才會(huì)退出,所以是一個(gè)循環(huán)結(jié)構(gòu)。
19行:獲取事件,比如鼠標(biāo)、鍵盤(pán)等
20行:當(dāng)用戶點(diǎn)擊了窗口的關(guān)閉,產(chǎn)生事件QUIT
21~22行:退出程序,pygame.quit()是pygame.init()函數(shù)的一種相反的函數(shù),它運(yùn)行的代碼會(huì)使得Pygame庫(kù)停止工作。在調(diào)用sys.exit()終止程序之前,總是應(yīng)該先調(diào)用pygame.quit()。
23行:刷新屏幕
二、加載游戲界面

import sys, os, random
import pygame
from pygame.locals import *
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED? = (255, 0, 0)
GAME_ROOT_FOLDER=os.path.dirname(__file__)
IMAGE_FOLDER=os.path.join(GAME_ROOT_FOLDER, "Images")
pygame.init()
clock = pygame.time.Clock()
clock.tick(60)
pygame.display.set_caption("瘋狂賽車(chē)")
IMG_ROAD = pygame.image.load(os.path.join(IMAGE_FOLDER, "Road.png"))
IMG_PLAYER = pygame.image.load(os.path.join(IMAGE_FOLDER, "Player.png"))
IMG_ENEMY = pygame.image.load(os.path.join(IMAGE_FOLDER, "Enemy.png"))
screen = pygame.display.set_mode(IMG_ROAD.get_size())
h=IMG_ROAD.get_width()//2
v=IMG_ROAD.get_height() - (IMG_PLAYER.get_height()//2)
player = pygame.sprite.Sprite()
player.image = IMG_PLAYER
player.surf = pygame.Surface(IMG_PLAYER.get_size())
player.rect = player.surf.get_rect(center = (h, v))
hl=IMG_ENEMY.get_width()//2
hr=IMG_ROAD.get_width()-(IMG_ENEMY.get_width()//2)
h=random.randrange(hl, hr)
v=0
enemy = pygame.sprite.Sprite()
enemy.image = IMG_ENEMY
enemy.surf = pygame.Surface(IMG_ENEMY.get_size())
enemy.rect = enemy.surf.get_rect(center = (h, v))
while True:
? ? screen.blit(IMG_ROAD, (0,0))
? ? screen.blit(player.image, player.rect)
? ? screen.blit(enemy.image, enemy.rect)
? ? for event in pygame.event.get():
? ? ? ? if event.type == QUIT:
? ? ? ? ? ? pygame.quit()
? ? ? ? ? ? sys.exit()
? ? pygame.display.update()
1行:導(dǎo)入sys、os、random
9行:獲取當(dāng)前py文件所在路徑
10行:當(dāng)前py文件夾路徑下的Images,此路徑存放一些圖片
16~18行:加載三張圖像數(shù)據(jù)
(1).使用pygame.image.load()加載圖像的數(shù)據(jù)
(2).使用游戲屏幕對(duì)象,調(diào)用blit方法將圖像繪制到指定位置
(3).調(diào)用pygame.display.update()方法更新整個(gè)屏幕的顯示
要在創(chuàng)建的窗口中按照指定要求顯示圖片,需要三個(gè)步驟:
19行:設(shè)置窗口大小

21~26行:設(shè)置player信息
精靈(sprite),一種能放在surface上的圖片對(duì)象,可以進(jìn)行移動(dòng)、旋轉(zhuǎn)、刪除等操作。
創(chuàng)建sprite對(duì)象player,分別設(shè)置圖像、大小、位置等。
31~34行:設(shè)置enemy信息
創(chuàng)建sprite對(duì)象enemy,分別設(shè)置圖像、大小、位置等。
36~38行:使用游戲屏幕對(duì)象,調(diào)用blit方法將圖像繪制到指定位置
三、動(dòng)起來(lái)

import sys, os, random
import pygame
from pygame.locals import *
from datetime import datetime
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED? = (255, 0, 0)
moveSpeed = 5
GAME_ROOT_FOLDER=os.path.dirname(__file__)
IMAGE_FOLDER=os.path.join(GAME_ROOT_FOLDER, "Images")
pygame.init()
clock = pygame.time.Clock()
clock.tick(60)
pygame.display.set_caption("瘋狂賽車(chē)")
IMG_ROAD = pygame.image.load(os.path.join(IMAGE_FOLDER, "Road.png"))
IMG_PLAYER = pygame.image.load(os.path.join(IMAGE_FOLDER, "Player.png"))
IMG_ENEMY = pygame.image.load(os.path.join(IMAGE_FOLDER, "Enemy.png"))
screen = pygame.display.set_mode(IMG_ROAD.get_size())
h=IMG_ROAD.get_width()//2
v=IMG_ROAD.get_height() - (IMG_PLAYER.get_height()//2)
player = pygame.sprite.Sprite()
player.image = IMG_PLAYER
player.surf = pygame.Surface(IMG_PLAYER.get_size())
player.rect = player.surf.get_rect(center = (h, v))
hl=IMG_ENEMY.get_width()//2
hr=IMG_ROAD.get_width()-(IMG_ENEMY.get_width()//2)
h=random.randrange(hl, hr)
v=0
enemy = pygame.sprite.Sprite()
enemy.image = IMG_ENEMY
enemy.surf = pygame.Surface(IMG_ENEMY.get_size())
enemy.rect = enemy.surf.get_rect(center = (h, v))
while True:
? ? screen.blit(IMG_ROAD, (0,0))
? ? screen.blit(player.image, player.rect)
? ? keys = pygame.key.get_pressed()
? ? if keys[K_LEFT] and player.rect.left > 0:
? ? ? ? player.rect.move_ip(-moveSpeed, 0)
? ? ? ? if player.rect.left < 0:
? ? ? ? ? ? player.rect.left = 0
? ? if keys[K_RIGHT] and player.rect.right < IMG_ROAD.get_width():
? ? ? ? player.rect.move_ip(moveSpeed, 0)
? ? ? ? if player.rect.right > IMG_ROAD.get_width():
? ? ? ? ? ? player.rect.right = IMG_ROAD.get_width()
? ? screen.blit(enemy.image, enemy.rect)
? ? enemy.rect.move_ip(0, moveSpeed)
? ? if (enemy.rect.bottom > IMG_ROAD.get_height()):
? ? ? ? hl=IMG_ENEMY.get_width()//2
? ? ? ? hr=IMG_ROAD.get_width()-(IMG_ENEMY.get_width()//2)
? ? ? ? h=random.randrange(hl, hr)
? ? ? ? v=0
? ? ? ? enemy.rect.center = (h, v)
? ? for event in pygame.event.get():
? ? ? ? if event.type == QUIT:
? ? ? ? ? ? pygame.quit()
? ? ? ? ? ? sys.exit()
? ? pygame.display.update()
? ? dt_obj = datetime.now()
? ? millisec = dt_obj.timestamp()
? ? print(millisec)
怎么讓游戲動(dòng)起來(lái)呢?
只需要修改兩張汽車(chē)的照片位置即可,可以用鍵盤(pán)上的左右鍵控制汽車(chē)player的左右移動(dòng),另一輛汽車(chē)可以自動(dòng)從上向下移動(dòng)。
10行:變量moveSpeed用于定義汽車(chē)移動(dòng)速度
41~45行:如果按下了鍵盤(pán)方向鍵左鍵,且坐標(biāo)沒(méi)有靠近最左邊,使其向左移動(dòng),否則在窗口最左邊不改變。
47~50行:如果按下了鍵盤(pán)方向鍵右鍵,且坐標(biāo)沒(méi)有靠近最右邊,使其向右移動(dòng),否則在窗口最右邊不改變。
53~59行:汽車(chē)enemy從上向下移動(dòng),如果移出窗口,則重新生成一個(gè),位置在頂部,橫坐標(biāo)隨機(jī)。
66~68行:打印時(shí)間信息,調(diào)試使用
四、碰撞檢測(cè)

import sys, os, random
import pygame
from pygame.locals import *
from datetime import datetime
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED? = (255, 0, 0)
moveSpeed = 5
maxSpeed = 10
score = 0
GAME_ROOT_FOLDER=os.path.dirname(__file__)
IMAGE_FOLDER=os.path.join(GAME_ROOT_FOLDER, "Images")
def GameOver():
? ? pygame.quit()
? ? sys.exit()
pygame.init()
clock = pygame.time.Clock()
clock.tick(60)
pygame.display.set_caption("瘋狂賽車(chē)")
IMG_ROAD = pygame.image.load(os.path.join(IMAGE_FOLDER, "Road.png"))
IMG_PLAYER = pygame.image.load(os.path.join(IMAGE_FOLDER, "Player.png"))
IMG_ENEMY = pygame.image.load(os.path.join(IMAGE_FOLDER, "Enemy.png"))
screen = pygame.display.set_mode(IMG_ROAD.get_size())
h=IMG_ROAD.get_width()//2
v=IMG_ROAD.get_height() - (IMG_PLAYER.get_height()//2)
player = pygame.sprite.Sprite()
player.image = IMG_PLAYER
player.surf = pygame.Surface(IMG_PLAYER.get_size())
player.rect = player.surf.get_rect(center = (h, v))
hl=IMG_ENEMY.get_width()//2
hr=IMG_ROAD.get_width()-(IMG_ENEMY.get_width()//2)
h=random.randrange(hl, hr)
v=0
enemy = pygame.sprite.Sprite()
enemy.image = IMG_ENEMY
enemy.surf = pygame.Surface(IMG_ENEMY.get_size())
enemy.rect = enemy.surf.get_rect(center = (h, v))
while True:
? ? pygame.display.set_caption("瘋狂賽車(chē)-得分 " + str(score))
? ? screen.blit(IMG_ROAD, (0,0))
? ? screen.blit(player.image, player.rect)
? ? keys = pygame.key.get_pressed()
? ? if keys[K_LEFT] and player.rect.left > 0:
? ? ? ? player.rect.move_ip(-moveSpeed, 0)
? ? ? ? if player.rect.left < 0:
? ? ? ? ? ? player.rect.left = 0
? ? if keys[K_RIGHT] and player.rect.right < IMG_ROAD.get_width():
? ? ? ? player.rect.move_ip(moveSpeed, 0)
? ? ? ? if player.rect.right > IMG_ROAD.get_width():
? ? ? ? ? ? player.rect.right = IMG_ROAD.get_width()
? ? screen.blit(enemy.image, enemy.rect)
? ? enemy.rect.move_ip(0, moveSpeed)
? ? if (enemy.rect.bottom > IMG_ROAD.get_height()):
? ? ? ? hl=IMG_ENEMY.get_width()//2
? ? ? ? hr=IMG_ROAD.get_width()-(IMG_ENEMY.get_width()//2)
? ? ? ? h=random.randrange(hl, hr)
? ? ? ? v=0
? ? ? ? enemy.rect.center = (h, v)
? ? ? ? score += 1
? ? ? ? if moveSpeed < maxSpeed:
? ? ? ? ? ? moveSpeed += 1
? ? if pygame.sprite.collide_rect(player, enemy):
? ? ? ? GameOver()
? ? for event in pygame.event.get():
? ? ? ? if event.type == QUIT:
? ? ? ? ? ? pygame.quit()
? ? ? ? ? ? sys.exit()
? ? pygame.display.update()
? ? # dt_obj = datetime.now()
? ? # millisec = dt_obj.timestamp()
? ? # print(millisec)
11行:對(duì)面汽車(chē)的最大速度
12行:定義變量用于保存玩家分?jǐn)?shù)
15行:定義一個(gè)函數(shù),當(dāng)玩家汽車(chē)和對(duì)面汽車(chē)接觸時(shí)退出游戲
43行:窗口標(biāo)題欄會(huì)顯示玩家當(dāng)前的分?jǐn)?shù)
66行:每躲過(guò)一個(gè)對(duì)面的小汽車(chē)時(shí),分?jǐn)?shù)加1
67~68行:每躲過(guò)一個(gè)對(duì)面的小汽車(chē)時(shí),對(duì)面小汽車(chē)速度加1,直到最大值
69~70:檢測(cè)兩個(gè)精靈對(duì)象是否接觸,如果接觸,退出游戲
五、Game Over

import sys, os, random, time
import pygame
from pygame.locals import *
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED? = (255, 0, 0)
startSpeed = 5
moveSpeed = startSpeed
maxSpeed = 10
score = 0
eNum = -1
paused = False
GAME_ROOT_FOLDER=os.path.dirname(__file__)
IMAGE_FOLDER=os.path.join(GAME_ROOT_FOLDER, "Images")
def GameOver():
? ? textFonts = ['comicsansms','arial']
? ? textSize = 48
? ? fontGameOver = pygame.font.SysFont(textFonts, textSize)
? ? textGameOver = fontGameOver.render("Game Over!", True, RED)
? ? rectGameOver = textGameOver.get_rect()
? ? rectGameOver.center = (IMG_ROAD.get_width()//2,
? ? ? ? ? ? ? ? ? ? ? ? ? IMG_ROAD.get_height()//2)
? ? screen.fill(BLACK)
? ? screen.blit(textGameOver, rectGameOver)
? ? pygame.display.update()
? ? player.kill()
? ? enemy.kill()
? ? time.sleep(5)
? ? pygame.quit()
? ? sys.exit()
pygame.init()
clock = pygame.time.Clock()
clock.tick(60)
pygame.display.set_caption("瘋狂賽車(chē)")
IMG_ROAD = pygame.image.load(os.path.join(IMAGE_FOLDER, "Road.png"))
IMG_PLAYER = pygame.image.load(os.path.join(IMAGE_FOLDER, "Player.png"))
IMG_ENEMIES = []
IMG_ENEMIES.append(pygame.image.load(os.path.join(IMAGE_FOLDER, "Enemy.png")))
IMG_ENEMIES.append(pygame.image.load(os.path.join(IMAGE_FOLDER, "Enemy2.png")))
IMG_ENEMIES.append(pygame.image.load(os.path.join(IMAGE_FOLDER, "Enemy3.png")))
IMG_ENEMIES.append(pygame.image.load(os.path.join(IMAGE_FOLDER, "IceCube.png")))
screen = pygame.display.set_mode(IMG_ROAD.get_size())
h=IMG_ROAD.get_width()//2
v=IMG_ROAD.get_height() - (IMG_PLAYER.get_height()//2)
player = pygame.sprite.Sprite()
player.image = IMG_PLAYER
player.surf = pygame.Surface(IMG_PLAYER.get_size())
player.rect = player.surf.get_rect(center = (h, v))
while True:
? ? pygame.display.set_caption("瘋狂賽車(chē)-得分 " + str(score))
? ? screen.blit(IMG_ROAD, (0,0))
? ? screen.blit(player.image, player.rect)
? ? if eNum == -1:
? ? ? ? eNum = random.randrange(0, len(IMG_ENEMIES))
? ? ? ? hl=IMG_ENEMIES[eNum].get_width()//2
? ? ? ? hr=IMG_ROAD.get_width()-(IMG_ENEMIES[eNum].get_width()//2)
? ? ? ? h=random.randrange(hl, hr)
? ? ? ? v=0
? ? ? ? enemy = pygame.sprite.Sprite()
? ? ? ? enemy.image = IMG_ENEMIES[eNum]
? ? ? ? enemy.surf = pygame.Surface(IMG_ENEMIES[eNum].get_size())
? ? ? ? enemy.rect = enemy.surf.get_rect(center = (h, v))
? ? keys = pygame.key.get_pressed()
? ? if paused:
? ? ? ? if not keys[K_SPACE]:
? ? ? ? ? ? moveSpeed=tempSpeed
? ? ? ? ? ? paused=False
? ? else:
? ? ? ? if keys[K_LEFT] and player.rect.left > 0:
? ? ? ? ? ? player.rect.move_ip(-moveSpeed, 0)
? ? ? ? ? ? if player.rect.left < 0:
? ? ? ? ? ? ? ? player.rect.left = 0
? ? ? ? if keys[K_RIGHT] and player.rect.right < IMG_ROAD.get_width():
? ? ? ? ? ? player.rect.move_ip(moveSpeed, 0)
? ? ? ? ? ? if player.rect.right > IMG_ROAD.get_width():
? ? ? ? ? ? ? ? player.rect.right = IMG_ROAD.get_width()
? ? ? ? if keys[K_SPACE]:
? ? ? ? ? ? tempSpeed=moveSpeed
? ? ? ? ? ? moveSpeed=0
? ? ? ? ? ? paused=True
? ? screen.blit(enemy.image, enemy.rect)
? ? enemy.rect.move_ip(0, moveSpeed)
? ? if (enemy.rect.bottom > IMG_ROAD.get_height()):
? ? ? ? enemy.kill()
? ? ? ? eNum = -1
? ? ? ? score += 1
? ? ? ? moveSpeed += 1
? ? ? ? if moveSpeed < maxSpeed:
? ? ? ? ? ? moveSpeed += 1
? ? if eNum >= 0 and pygame.sprite.collide_rect(player, enemy):
? ? ? ? if eNum == 3:
? ? ? ? ? ? moveSpeed = startSpeed
? ? ? ? else:
? ? ? ? ? ? GameOver()
? ? for event in pygame.event.get():
? ? ? ? if event.type == QUIT:
? ? ? ? ? ? pygame.quit()
? ? ? ? ? ? sys.exit()
? ? pygame.display.update()
5行:開(kāi)始速度
22~40行:將游戲結(jié)束時(shí),顯示Game Over
16行:對(duì)面汽車(chē)索引
17行:是否暫停
49~53行:對(duì)面障礙物,是四個(gè)圖片中的一個(gè),隨機(jī)出現(xiàn)
68~78行:隨機(jī)產(chǎn)生一個(gè)障礙物
81~84行:空格鍵松開(kāi)時(shí),恢復(fù)對(duì)面車(chē)的運(yùn)動(dòng)速度,游戲暫停結(jié)束
94~97行:空格鍵按下時(shí),保存當(dāng)前對(duì)面車(chē)的速度,游戲開(kāi)始暫停
102~108行:當(dāng)對(duì)面車(chē)移除游戲窗口時(shí),銷(xiāo)毀它
111~112行:當(dāng)遇到特殊的車(chē),速度降低到原始速度
源碼
有朋友需要圖片、源碼等資源的話,可以點(diǎn)擊閱讀原文,然后輸入6666

好了,我們今天就學(xué)到這里吧!
如果遇到什么問(wèn)題,咱們多多交流,共同解決。
我是貓妹,咱們下次見(jiàn)!