Python游戲利器pygame,瘋狂賽車(chē)(34)

小朋友們好,大朋友們好!

我是貓妹,一名愛(à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)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容