Python利用3D引擎寫一個Pong遊戲
前言
之前,我們用pygame做瞭一個2D的Pong遊戲,今天我們做一個3D的,遊戲畫面如下:
用ad和←→操作,雙人對戰
實現該效果我們使用Python強大的3D引擎Ursina,基礎的使用方法見這篇文章:詳解Python 3D引擎Ursina如何繪制立體圖形
接下來開始寫代碼吧!
實現方法
首先,導入ursina和隨機庫
from ursina import * import random as rd
定義兩個玩傢的分數
scorea=scoreb=0
然後,我們創建app
app=Ursina()
ursina自帶window參數,代表窗口,它還自帶color參數,代表各種顏色,我們直接修改窗口的顏色
window.color=color.cyan
我們創建一個桌子,它是一個長方體,所以model為cube,顏色是橙色,然後進行縮放操作,並設置位置,還有它的材質(普通材質)
table=Entity(model="cube",color=color.orange,scale=(10,0.5,14),position=(0,0,0),texture="white_cube")
照樣子,創建一個板子
paddle_A=Entity(parent=table,color=color.black,model="cube",scale=(0.2,0.03,0.05),position=(0,3.7,0.22),collider="box")
因為第二個板子和第一個板子差不多,我們隻需要用duplicate函數進行實體復制,然後修改部分參數即可
paddle_B=duplicate(paddle_A,z=-0.62)
然後,把分數顯示,顯示文字用到瞭Text類,參數差不多
t=Text(text=f"Player A : Player B {scorea} : {scoreb}", position=(-0.85, 0.45), scale=2,color=color.orange)
這樣運行程序,我們隻看到瞭桌子的側面,調整視角,改變ursina自帶的camera的屬性即可,設置它的傾斜度和位置
camera.position=(0,15,-26) camera.rotation_x=30
繪制兩個玩傢的名字
Text(text="Player A",scale=2,position=(-0.1,0.32),color=color.orange) Text(text="Player B",scale=2,position=(-0.1,-0.4),color=color.orange)
接下來,繪制桌子中間的分割線和球
line=Entity(parent=table,model="quad",scale=(0.88,0.2,0.1),position=(0,3.5,-0.2)) ball=Entity(parent=table,model="sphere",color=color.gold,scale=.05,position=(0,3.7,-0.2),collider="box")
設置初始x和z的速度
dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4) dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
然後進入主循環
app.run()
我們在創建app前添加update函數,註意,這裡名字一定要用update,然後自己無需調用,由ursina自動調用
創建函數並引入全局變量
def update(): global dx,dz,scorea,scoreb
然後判斷按下瞭按鍵就對板子進行移動操作,按下按鍵的信息存儲於held_keys中,並限制板子的移動范圍
paddle_B.x-=held_keys["left arrow"]*time.dt paddle_B.x+=held_keys["right arrow"]*time.dt paddle_A.x-=held_keys["a"]*time.dt paddle_A.x+=held_keys["d"]*time.dt if paddle_A.x>0.35: paddle_A.x=0.35 elif paddle_A.x<-0.35: paddle_A.x=-0.35 if paddle_B.x>0.35: paddle_B.x=0.35 elif paddle_B.x<-0.35: paddle_B.x=-0.35
移動小球
ball.x+=dx*time.dt ball.z+=dz*time.dt
更新比分顯示
t.text=f"Player A : Player B {scorea} : {scoreb}"
進行板子和球的碰撞檢測,先用intersects獲取觸碰到的實體列表,然後對碰到實體為兩個板子的時候進行反彈、加速或減速的操作
hit_info=ball.intersects() if hit_info.hit: if hit_info.entity==paddle_A: dz=-dz if dz>-0.05: dz-=rd.uniform(0.1,0.3) else: dz-=rd.uniform(-0.05,0.2) if hit_info.entity==paddle_B: dz=-dz if dz<0.05: dz+=rd.uniform(0.1,0.3) else: dz+=rd.uniform(-0.05,0.2)
限制球在桌子中間移動,如果一方沒有接到球,就對另一方進行加分的操作
if abs(ball.x)>0.4: dx=-dx if ball.z>0.25: scoreb+=1 ball.x=0 ball.z=-0.2 dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4) dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5) if ball.z<-0.65: scorea+=1 ball.x=0 ball.z=-0.2 dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4) dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
我們用瞭不到100行代碼,就實現瞭以下效果~
完整代碼
這裡附上最終代碼:
from ursina import * import random as rd scorea=scoreb=0 def update(): global dx,dz,scorea,scoreb paddle_B.x-=held_keys["left arrow"]*time.dt paddle_B.x+=held_keys["right arrow"]*time.dt paddle_A.x-=held_keys["a"]*time.dt paddle_A.x+=held_keys["d"]*time.dt if paddle_A.x>0.35: paddle_A.x=0.35 elif paddle_A.x<-0.35: paddle_A.x=-0.35 if paddle_B.x>0.35: paddle_B.x=0.35 elif paddle_B.x<-0.35: paddle_B.x=-0.35 ball.x+=dx*time.dt ball.z+=dz*time.dt t.text=f"Player A : Player B {scorea} : {scoreb}" hit_info=ball.intersects() if hit_info.hit: if hit_info.entity==paddle_A: dz=-dz if dz>-0.05: dz-=rd.uniform(0.1,0.3) else: dz-=rd.uniform(-0.05,0.2) if hit_info.entity==paddle_B: dz=-dz if dz<0.05: dz+=rd.uniform(0.1,0.3) else: dz+=rd.uniform(-0.05,0.2) if abs(ball.x)>0.4: dx=-dx if ball.z>0.25: scoreb+=1 ball.x=0 ball.z=-0.2 dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4) dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5) if ball.z<-0.65: scorea+=1 ball.x=0 ball.z=-0.2 dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4) dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5) app=Ursina() window.color=color.cyan table=Entity(model="cube",color=color.orange,scale=(10,0.5,14),position=(0,0,0),texture="white_cube") paddle_A=Entity(parent=table,color=color.black,model="cube",scale=(0.2,0.03,0.05),position=(0,3.7,0.22),collider="box") paddle_B=duplicate(paddle_A,z=-0.62) t=Text(text=f"Player A : Player B {scorea} : {scoreb}", position=(-0.85, 0.45), scale=2,color=color.orange) camera.position=(0,15,-26) camera.rotation_x=30 Text(text="Player A",scale=2,position=(-0.1,0.32),color=color.orange) Text(text="Player B",scale=2,position=(-0.1,-0.4),color=color.orange) line=Entity(parent=table,model="quad",scale=(0.88,0.2,0.1),position=(0,3.5,-0.2)) ball=Entity(parent=table,model="sphere",color=color.gold,scale=.05,position=(0,3.7,-0.2),collider="box") dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4) dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5) app.run()
到此這篇關於Python利用3D引擎寫一個Pong遊戲的文章就介紹到這瞭,更多相關Python Pong遊戲內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python利用3D引擎做一個太陽系行星模擬器
- 詳解Python 3D引擎Ursina如何繪制立體圖形
- Python+Pygame實現趣味足球遊戲
- pygame實現滑塊接小球遊戲
- C語言用數組實現反彈球消磚塊