Python遊戲開發,pgzrun模塊,Python實現阿肯色克隆人遊戲 前言 開發工具 環境搭建 遊戲實現

前言

利用Python實現Python和PyGameZero編寫阿卡尼類(Outout)的克隆,廢話不多說。

讓我們愉快地開始吧~

開發工具

Python版本:3.6.4

相關模塊:

pgzrun模塊;

以及一些Python自帶的模塊。

環境搭建

安裝Python並添加到環境變量,pip安裝需要的相關模塊即可。

遊戲實現

安裝遊戲零:

pip install pgzero

我們要做的第一件事是打開一個空窗口:

import pgzrun

TITLE = "Arkanoid clone"
WIDTH = 800
HEIGHT = 500

pgzrun.go()

我們進口遊戲零。標題顯示在窗口上的標題,其他兩個變量定義寬度和高度。

Go()運行程序。

您將看到一個空白窗口

接下來,讓我們展示一些街區。

在高度和寬度下面添加以下代碼:

WIDTH = 800
HEIGHT = 500

paddle = Actor("paddleblue.png")
paddle.x = 120
paddle.y = 420

ball = Actor("ballblue.png")
ball.x = 30
ball.y = 300

演員是PyGames 0顯示圖像的方式。圖像總是存儲在影象文件夾位於與遊戲腳本相同的位置。

➜ tree
.
├── game.py
└── images
    ├── ballblue.png
    └── paddleblue.png

1 directory, 3 files

我們還設置了正在加載的圖像的起始x和y位置:

paddle.x = 120
paddle.y = 420

這些值可以是任意的,我通過反覆試驗得到了上面的結果。

因此,我們將圖像加載到內存中,但我們還沒有顯示它們。我們現在就解決這個問題。PgZero有一個內置的抽籤() 函數,該函數在啓動遊戲時自動調用。還有一個更新函數,每秒調用60次,並在移動時更新屏幕。

更新VS繪圖功能

更新和繪製函數是相似的--除非更新每秒調用60次,而只有在某些事情發生變化時才調用繪圖。

沒有硬和快速的規則,但我會使用更新的東西,很多變化,如鍵盤運動,球運動等,而背景圖像可以在繪製。

畫槳和球

現在,我們將只在屏幕上繪圖,並將UPDATE保留爲空

def draw():
    paddle.draw()
    ball.draw()
    
def update():
    pass

更換背景

讓我們更新繪圖功能:

def draw():
    screen.blit("background.png", (0,0))
    paddle.draw()
    ball.draw()

背景是一個文件Background.png在……裏面影象。這個布利特() 函數將我們的圖像繪製到屏幕上。(0,0)表示從x=0y=0開始。我們將在下面討論更多關於PyameZero座標系的內容。

佈置欄杆

接下來,我們要列出我們的球將擊中的所有頂部的欄杆。

在我們的目錄中有一些條形圖,我們將使用它們。首先,佈局1欄:

bar = Actor("element_blue_rectangle_glossy.png")
bar.x=120
bar.y=100

def draw():
    bar.draw()

很明顯,一次只放一個酒吧是很痛苦的。讓我們使用一個for循環來放置多個。

def draw():
    bar_x = 120
    bar_y = 100
    for i in range(8):
        bar = Actor("element_blue_rectangle_glossy.png")
        bar.x = bar_x
        bar.y = bar_y
        bar.draw()
        
        bar_x += 70

我們創建了開始的x和y變量-棒x初始化爲120和棒Y初始化爲100

我們繞8圈。爲什麼是8?因爲這就是我們能舒服地坐在屏幕上的酒吧。

對於每個循環,我們創建一個Actor並初始化它的x和y,並將其繪製到屏幕上。然後我們會:

bar_x += 70

使下一個條形圖向左移動70個像素。再一次,我通過反覆試驗找到了70個。嘗試更改值,然後看到條形圖重疊或相距太遠。

運行代碼

好的。現在我們也要把其他的酒吧都佈置好。我計劃有三排不同顏色的。

我要做的第一件事是將上面的代碼解壓縮到一個函數中:

def draw():
    screen.blit("background.png", (0,0))
    paddle.draw()
    ball.draw()
    place_blue_bars()

def place_blue_bars():
    bar_x = 120
    bar_y = 100
    for i in range(8):
        bar = Actor("element_blue_rectangle_glossy.png")
        bar.x = bar_x
        bar.y = bar_y
        bar.draw()
        bar_x += 70

我所做的就是將代碼解壓縮成一個函數放置藍條()

現在,我可以創建更多的函數Create_red_bar(), 但我相信我們可以做得更聰明。所以我將有一個一般的函數Place_bar():

def place_bars(x,y,image):

我們還將創建另一個全局變量。條形表=[] 在頂部,我們將用這個來檢查要顯示的條子,以及球擊中後要移除的條子。

我們將傳遞第一個條形的起始x和y,加上我們想要使用的圖像。最後的職能是:

def place_bars(x,y,image):
    bar_x = x
    bar_y = y
    for i in range(8):
        bar = Actor(image)
        bar.x = bar_x
        bar.y = bar_y
        bar_x += 70
        bars_list.append(bar)

唯一的變化是我們初始化了x,y和輸入的圖像。

我們將在遊戲主代碼開始之前調用這個函數。Pgzero.run()

coloured_box_list = ["element_blue_rectangle_glossy.png", "element_green_rectangle_glossy.png","element_red_rectangle_glossy.png"]
    x = 120
    y = 100

我們有一個包含3幅圖像的列表,我們初始化了x和y值。然後我們循環遍歷我們的列表:

for coloured_box in coloured_box_list:
        place_bars(x, y, coloured_box)
        y += 50

我們需要做一個Y+=50在每個循環中,否則,條子將放置在彼此的頂部。

最後代碼:

coloured_box_list = 
 ["element_blue_rectangle_glossy.png",
 "element_green_rectangle_glossy.png",
 "element_red_rectangle_glossy.png"]
 x = 120
 y = 100
 for coloured_box in coloured_box_list:
     place_bars(x, y, coloured_box)
     y += 50

還有一件事要做。我們正在創建我們的酒吧,但沒有顯示它們。更新繪圖功能:

def draw()
    for bar in bars_list:
        bar.draw()

我們有漂亮的佈局。我們現在可以開始研究邏輯了。

添加球物理和處理用戶輸入

移動槳

讓我們從移動我們的槳開始。這是相當容易的,在遊戲零-你可以直接檢查鍵盤事件。讓我們更新我們的更新() 職能:

def update():
    if keyboard.left:
        paddle.x = paddle.x - 5
    if keyboard.right:
        paddle.x = paddle.x + 5

如果鍵盤左檢查左鍵是否按下,如果是,則將槳的x位置更改爲-5(即向左移動5個像素)。正確的鑰匙也是一樣。

爲什麼我要選擇5個像素?在移動太快/太慢之間找到平衡。嘗試將值更改爲1和10,看看會發生什麼。

按左右鍵-你現在可以移動槳了。

移動球

記住,內置的UPDATE()方法每秒調用60次。因此,任何遊戲邏輯,如移動球,檢查碰撞等都會出現在這裏。

我們將創建一個名爲更新球() 我們會從更新() .

def update():
    update_ball()

def update_ball():
    ball.x -= 1
    ball.y -= 1

我們要改變球的x和y位置。

關於PYGERO零座標系的一點看法

屏幕左上角爲0,0;即x=0,y=0。

當你往右走,x就會增加。

當你下去的時候,y會增加。

所以向左移動,減小x。向右移動,增加x。

下去,增加你。向上,減少你。

考慮到這一點:

Ball.x-=1向左移動球(as-1=左,+1=右)

Ball.y-=1將球向上移動(as-1=向上,+1=向下)

所以在開始的時候,球會向上和左邊移動。這只是一個隨機的決定-你可以很容易地選擇下來和正確的。但我會堅持下去,現在,我可以給你們看一個問題

球飛離了屏幕!哈!

我們需要增加檢查,這樣如果它撞到牆上,它就會反彈回來。這是物理部分。

現在再加上那張支票。

首先,讓我們爲x和y的速度添加一個全局變量。將這些全局VAR添加到文件的頂部:

ball_x_speed = 1
ball_y_speed = 1

左/右和上/下的速度是1像素。您可以嘗試增加這個數字,以使球跑得更快(從而增加難度),但我們將堅持1,因爲它使測試變得容易。

讓我們在函數中使用這個變量:

def update_ball():
    global ball_x_speed, ball_y_speed
    ball.x -= ball_x_speed
    ball.y -= ball_y_speed

代碼和以前一樣,只是用變量替換了‘1’。我們現在把支票加起來。

if (ball.x >= WIDTH) or (ball.x <=0):
        ball_x_speed *= -1

如果x超過我們爲遊戲定義的最大寬度(即超出屏幕的右側),或低於0(即超出屏幕的左邊),那麼:

ball_x_speed *= -1

這是什麼意思?記住,每次更新的時候我們都是按球的速度前進的。首先,我們向上移動,然後離開。

在這裏,我們把速度乘以-1。所以,如果球向左移動,它就會開始向右移動,反之亦然。

結果是,球一碰到邊界,就會改變方向。

對於y軸,我們也可以這樣做:

if (ball.y >= HEIGHT) or (ball.y <=0):
        ball_y_speed *= -1

再一次,我們檢查球是在屏幕上方還是下面。最後的職能是:

def update_ball():
    global ball_x_speed, ball_y_speed
    ball.x -= ball_x_speed
    ball.y -= ball_y_speed
    if (ball.x >= WIDTH) or (ball.x <=0):
        ball_x_speed *= -1
    if (ball.y >= HEIGHT) or (ball.y <=0):
        ball_y_speed *= -1

讓我們測試代碼

太酷了,所以球會從牆上跳下來。但它仍然穿過街區。我們來解決這個問題。

在PyameZero中實現碰撞檢測

在UPDATE函數中,我們添加此代碼以檢測衝突:

def update():
    update_ball()
    for bar in bars_list:
        if ball.colliderect(bar):
            bars_list.remove(bar)

讓我們逐行檢查代碼。

我們繞着欄杆:

for bar in bars_list:

對於每個酒吧,我們檢查球是否與之碰撞:

if ball.colliderect(bar):

對撞機()是一個內置的函數,它檢查兩個對象是否發生碰撞;在本例中,是球體和棒子。

如果它們發生碰撞,我們從列表中刪除該條:

if ball.colliderect(bar):
            bars_list.remove(bar)

記住,這些條是在抽籤() 功能?

for bar in bars_list:
        bar.draw()

如果我們從列表中刪除該條,它將不再被繪製,從而從屏幕上消失。

好的,那很好,但是球像刀子一樣穿過塊。這不是我們想要的。我們想讓球在擊中蓋子時反彈。

幸運的是,有一個簡單的解決方案:

for bar in bars_list:
        if ball.colliderect(bar):
            bars_list.remove(bar)
            ball_y_speed *= -1 # ==> this is the new code

最後一行是新代碼--我們改變了球的y方向--所以如果它上升了,它就會開始下降。

我還想做一件事。在真正的阿肯色州,當球擊中塊或槳,它可以左或右,模擬現實世界彈球樣的“物理”。是的,這並不完美,但它給比賽增添了一些樂趣,因爲你不知道球會去哪裏。

我將爲此添加代碼:

# randomly move ball left or right on hit
            rand = random.randint(0,1)
            if rand:
                ball_move_x *= -1

當球擊中一個街區,我們將隨機,大約50%的時間,改變方向。所以如果球向右,它可能會開始向左移動。

我們還有最後一件事要做。

把球從我們的槳上彈下來

我將分享代碼--你現在應該能夠理解它了:

if paddle.colliderect(ball):
        ball_y_speed *= -1
        # randomly move ball left or right on hit
        rand = random.randint(0,1)
        if rand:
            ball_x_speed *= -1

再次,我們檢查球是否與槳碰撞,如果是,改變它的y方向。隨機改變x方向。

你現在應該可以玩這個遊戲了

注意點要牢記以下幾點

1代碼中有一個很大的錯誤--如果它落在槳下,遊戲就會繼續進行。實際上,你永遠不會輸!

你需要改變邏輯,這樣如果球落在槳下,遊戲就結束了。在下一個例子中,我們將看到如何在屏幕上創建一個遊戲,現在只需將其打印到控制檯即可。

2試着增加分數--所以每次你碰到一個街區,你就能得到1分。同樣,只需將得分打印到控制檯即可。

對於加分,對於不同顏色的塊有不同的分數。提示:您需要將塊存儲在不同的列表中,這樣您就可以根據您點擊的顏色來檢查分數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章