<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
好久沒有寫遊戲系列教學了,今天恰好瀏覽到了 Kivy 這個開源跨平臺的Python 框架,它能用於開發多點觸控的使用者介面程式,允許快速簡單的互動設計,非常方便,於是有了製作本教學的想法。
本教學將教你如何使用 Kivy 編寫一款乒乓球遊戲。我們將從一個基本的應用程式開始,描述建立這個遊戲的每個步驟。
Kivy 是用 Python 和 Cython 編寫的,基於 OpenGL ES 2,支援各種輸入裝置並擁有豐富的部件庫。使用相同的程式碼,你可直接實現多平臺應用,包括 Windows、macOS、Linux、Android 和 iOS。所有 Kivy 部件都支援多點觸控。
開始之前,你要確保Python和pip已經成功安裝在電腦上,如果沒有,可以存取這篇文章:超詳細Python安裝指南 進行安裝。
(可選1) 如果你用Python的目的是資料分析,可以直接安裝Anaconda,它內建了Python和pip.
(可選2) 此外,推薦大家用VSCode編輯器,它有許多的優點
請選擇以下任一種方式輸入命令安裝依賴:
1. Windows 環境 開啟 Cmd (開始-執行-CMD)。
2. MacOS 環境 開啟 Terminal (command+空格輸入Terminal)。
3. 如果你用的是 VSCode編輯器 或 Pycharm,可以直接使用介面下方的Terminal.
pip install kivy[base] kivy_examples
這一節將簡單介紹Kivy的基本使用,首先為我們遊戲建立一個目錄和一個名為main.py的檔案:
# main.py from kivy.app import App from kivy.uix.widget import Widget class PongGame(Widget): pass class PongApp(App): def build(self): return PongGame() if __name__ == '__main__': PongApp().run()
在命令列中輸入 python main.py 執行該應用程式。它應該只顯示一個黑色的視窗。所以我們所做的只是建立一個非常簡單的Kivy應用程式,它建立了一個 PongGame Widget 類的範例,並將其作為應用程式使用者介面的根元素返回。
在這一點上你應該把它想象成一個 Widget 的分層樹。Kivy 將這個 Widget 放在預設的視窗中。在下一步,我們將通過定義 PongGame 小部件的外觀來繪製Pong的背景和遊戲分數。
我們將使用一個 .kv 檔案來定義 PongGame 類的外觀。由於我們的應用程式類被稱為 PongApp,我們可以簡單地在同一目錄下建立一個名為 pong.kv 的檔案,當應用程式執行時將會自動載入。
因此,為了定義遊戲的外觀,我們建立一個名為 pong.kv 的新檔案並新增以下內容:
#:kivy 1.0.9 <PongGame>: canvas: Rectangle: pos: self.center_x - 5, 0 size: 10, self.height Label: font_size: 70 center_x: root.width / 4 top: root.top - 50 text: "0" Label: font_size: 70 center_x: root.width * 3 / 4 top: root.top - 50 text: "0"
注意一個常見錯誤:kv檔案的名稱,例如 pong.kv,必須與應用程式的名稱一致,例如 PongApp(App結尾之前的部分)。
如果你現在執行這個應用程式,你應該看到中間有一個豎條,還有兩個零,那裡將顯示玩家的分數,如下所示:
可以看到,在第一行,我們有:
#:kivy 1.0.9
每個 kv 檔案都需要第一行。它應該以 #:kivy 及一個空格開頭,然後是它要使用的 Kivy 版本(因此 Kivy 可以確保您至少擁有所需的版本,或者稍後處理向後相容性)。
再往下看 kv 檔案裡定義了三個元素,一個 canvas 和兩個 label。
先說說兩個label,他們代表的是左右兩個數位,設定了 font_size(字型大小), center_x(中心位置), top(離頂部距離), text(文字),此外可以看到 root.width 和 root.top 的使用,這樣寫的好處是能跟跟隨視窗寬度和高度的變化而變化。
另一個元素 canvas,它的下面定義了 Rectangle 引數,意思是我們向畫布新增一個矩形。將矩形的 pos 設定為小部件水平中心左側 5 個畫素,y 設定為 0,這就定義了矩形的顯示位置。
矩形的大小 size 設定為寬度為 10 畫素,高度為小部件的高度。像這樣定義圖形的好處是,當值表示式中使用的任何小部件的屬性發生變化時,渲染的矩形將自動更新。
好了,我們有一個基本的乒乓球場(雖然很簡陋),但我們仍然需要球拍和一個球來打球。讓我們從球開始。我們將新增一個新的 PongBall 類來建立一個小部件,它將成為我們的球並使它彈跳起來。
PongBall 類:
class PongBall(Widget): # velocity of the ball on x and y axis velocity_x = NumericProperty(0) velocity_y = NumericProperty(0) # referencelist property so we can use ball.velocity as # a shorthand, just like e.g. w.pos for w.x and w.y velocity = ReferenceListProperty(velocity_x, velocity_y) # ``move`` function will move the ball one step. This # will be called in equal intervals to animate the ball def move(self): self.pos = Vector(*self.velocity) + self.pos
白球的 kv 設定如下:
<PongBall>: size: 50, 50 canvas: Ellipse: pos: self.pos size: self.size
為了使這一切順利進行,你還必須為球體增加所用的Property屬性類。下面是這一步更新後的python程式碼和kv檔案。
from kivy.app import App from kivy.uix.widget import Widget from kivy.properties import NumericProperty, ReferenceListProperty from kivy.vector import Vector class PongBall(Widget): velocity_x = NumericProperty(0) velocity_y = NumericProperty(0) velocity = ReferenceListProperty(velocity_x, velocity_y) def move(self): self.pos = Vector(*self.velocity) + self.pos class PongGame(Widget): pass class PongApp(App): def build(self): return PongGame() if __name__ == '__main__': PongApp().run()
kv檔案如下:
#:kivy 1.0.9 <PongBall>: size: 50, 50 canvas: Ellipse: pos: self.pos size: self.size <PongGame>: canvas: Rectangle: pos: self.center_x - 5, 0 size: 10, self.height Label: font_size: 70 center_x: root.width / 4 top: root.top - 50 text: "0" Label: font_size: 70 center_x: root.width * 3 / 4 top: root.top - 50 text: "0" PongBall: center: self.parent.center
現在我們的目的是讓這個球動起來,因此必須定期呼叫 move 函數讓他動起來。使用 Kivy 提供的 Clock 函數可以輕易地做到這一點:
Clock.schedule_interval(game.update, 1.0/60.0)
這一行將導致遊戲物件的更新函數每秒被呼叫60次。
不過我們還有一個問題。我們想確保PongBall的移動函數被定期呼叫,但是在我們的程式碼中沒有任何對球物件的參照,因為我們只是通過 kv 檔案在 PongGame 類的 kv 規則中新增了它。
由於我們要做的不僅僅是移動球(比如把球從牆上彈下來,然後再彈到球員的球拍上),我們可能需要為我們的PongGame類建立一個更新方法。
class PongGame(Widget): def update(self, dt): # call ball.move and other stuff pass class PongApp(App): def build(self): game = PongGame() Clock.schedule_interval(game.update, 1.0/60.0) return game
然而,這仍然不能改變我們沒有對kv規則所建立的 PongBall 進行操作的這一事實。為了解決這個問題,我們可以給PongGame類新增一個ObjectProperty,並將其與kv規則中建立的widget掛鉤。
一旦這樣做了,我們就可以很容易地在更新方法中參照球的屬性,甚至可以讓它從邊緣彈起。
class PongGame(Widget): ball = ObjectProperty(None) def update(self, dt): self.ball.move() # bounce off top and bottom if (self.ball.y < 0) or (self.ball.top > self.height): self.ball.velocity_y *= -1 # bounce off left and right if (self.ball.x < 0) or (self.ball.right > self.width): self.ball.velocity_x *= -1
在kv檔案中將其與程式碼中設定的 id: ball 對映起來:
<PongGame>: ball: pong_ball # ... (canvas and Labels) PongBall: id: pong_ball center: self.parent.center
現在,我們的球正在彈來彈去。唯一缺少的是可移動的球拍和對分數的跟蹤。我們不會再去討論建立類和kv規則的所有細節,因為這些概念已經在前面的步驟中涵蓋了。
相反,讓我們把重點放在如何響應使用者的輸入而移動球拍上。你可以在Python實用寶典公眾號後臺回覆:乒乓球 獲得全部程式碼和kv規則。
在Kivy中,小部件可以通過實現 on_touch_down、on_touch_move和on_touch_up 方法對輸入做出反應。預設情況下,Widget類實現這些方法時,只是在其子部件上呼叫相應的方法來傳遞事件,直到其中一個子部件返回True。
乒乓運動是非常簡單的。球拍只需要向上和向下移動。事實上,它是如此簡單,我們甚至不需要讓球員小部件自己處理事件。我們只需為PongGame類實現on_touch_move函數:
def on_touch_move(self, touch): if touch.x < self.width/3: self.player1.center_y = touch.y if touch.x > self.width - self.width/3: self.player2.center_y = touch.y
我們將在NumericProperty中保留每個球員的分數。PongGame的分數標籤通過改變 NumericProperty score來保持更新,這反過來又會更新PongGame的子標籤文字屬性。
這是如何實現的?因為Kivy屬性會自動繫結到其對應的kv檔案中的任何參照。當球從兩側逃出時,我們將通過PongGame類中的更新方法來更新分數並再次發球。
PongPaddle類也實現了一個 bounce_ball 方法,這樣球就會根據它擊中球拍的位置而產生不同方向的彈跳,非常有意思。下面是PongPaddle類的程式碼:
class PongPaddle(Widget): score = NumericProperty(0) def bounce_ball(self, ball): if self.collide_widget(ball): speedup = 1.1 offset = 0.02 * Vector(0, ball.center_y-self.center_y) ball.velocity = speedup * (offset - ball.velocity)
到這一步我們基本就完成了整個遊戲的製作,如何,你心動了嗎?
以上就是Python+Kivy編寫一個乒乓球遊戲的詳細內容,更多關於Python Kivy乒乓球遊戲的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45