当前位置:   article > 正文

Python 用3D引擎写一个Pong游戏_python3d游戏引擎

python3d游戏引擎

之前,我们用pygame做了一个2D的Pong游戏,今天我们做一个3D的,游戏画面如下:

 用ad和←→操作,双人对战


实现该效果我们使用Python强大的3D引擎Ursina,基础的使用方法见下方这篇文章:

手把手教你用Python编一个《我的世界》 1. 认识Ursina并学会绘制立体图形_Leleprogrammer的博客-CSDN博客_ursinaPython有一个不错的3D引擎——UrsinaUrsina官网:www.ursinaengine.org打开cmd,控制台输入pip install ursina以安装ursina编写第一个程序首先导入ursinafrom ursina import *然后创建appapp=Ursina()运行appapp.run()最终代码:from ursina import *app=Ursina()app.run()如果出现了一个灰色的窗口,https://blog.csdn.net/leleprogrammer/article/details/124780527?spm=1001.2014.3001.5502接下来开始写代码吧!

首先,导入ursina和随机库

  1. from ursina import *
  2. 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的属性即可,设置它的倾斜度和位置

  1. camera.position=(0,15,-26)
  2. camera.rotation_x=30

绘制两个玩家的名字

  1. Text(text="Player A",scale=2,position=(-0.1,0.32),color=color.orange)
  2. Text(text="Player B",scale=2,position=(-0.1,-0.4),color=color.orange)

接下来,绘制桌子中间的分割线和球

  1. line=Entity(parent=table,model="quad",scale=(0.88,0.2,0.1),position=(0,3.5,-0.2))
  2. ball=Entity(parent=table,model="sphere",color=color.gold,scale=.05,position=(0,3.7,-0.2),collider="box")

设置初始x和z的速度

  1. dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
  2. 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自动调用

创建函数并引入全局变量

  1. def update():
  2. global dx,dz,scorea,scoreb
'
运行

然后判断按下了按键就对板子进行移动操作,按下按键的信息存储于held_keys中,并限制板子的移动范围

  1. paddle_B.x-=held_keys["left arrow"]*time.dt
  2. paddle_B.x+=held_keys["right arrow"]*time.dt
  3. paddle_A.x-=held_keys["a"]*time.dt
  4. paddle_A.x+=held_keys["d"]*time.dt
  5. if paddle_A.x>0.35:
  6. paddle_A.x=0.35
  7. elif paddle_A.x<-0.35:
  8. paddle_A.x=-0.35
  9. if paddle_B.x>0.35:
  10. paddle_B.x=0.35
  11. elif paddle_B.x<-0.35:
  12. paddle_B.x=-0.35

移动小球

  1. ball.x+=dx*time.dt
  2. ball.z+=dz*time.dt

更新比分显示

    t.text=f"Player A : Player B  {scorea} : {scoreb}"

进行板子和球的碰撞检测,先用intersects获取触碰到的实体列表,然后对碰到实体为两个板子的时候进行反弹、加速或减速的操作

  1. hit_info=ball.intersects()
  2. if hit_info.hit:
  3. if hit_info.entity==paddle_A:
  4. dz=-dz
  5. if dz>-0.05:
  6. dz-=rd.uniform(0.1,0.3)
  7. else:
  8. dz-=rd.uniform(-0.05,0.2)
  9. if hit_info.entity==paddle_B:
  10. dz=-dz
  11. if dz<0.05:
  12. dz+=rd.uniform(0.1,0.3)
  13. else:
  14. dz+=rd.uniform(-0.05,0.2)

限制球在桌子中间移动,如果一方没有接到球,就对另一方进行加分的操作

  1. if abs(ball.x)>0.4:
  2. dx=-dx
  3. if ball.z>0.25:
  4. scoreb+=1
  5. ball.x=0
  6. ball.z=-0.2
  7. dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
  8. dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
  9. if ball.z<-0.65:
  10. scorea+=1
  11. ball.x=0
  12. ball.z=-0.2
  13. dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
  14. dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)

我们用了不到100行代码,就实现了以下效果~

这里附上最终代码:

  1. from ursina import *
  2. import random as rd
  3. scorea=scoreb=0
  4. def update():
  5. global dx,dz,scorea,scoreb
  6. paddle_B.x-=held_keys["left arrow"]*time.dt
  7. paddle_B.x+=held_keys["right arrow"]*time.dt
  8. paddle_A.x-=held_keys["a"]*time.dt
  9. paddle_A.x+=held_keys["d"]*time.dt
  10. if paddle_A.x>0.35:
  11. paddle_A.x=0.35
  12. elif paddle_A.x<-0.35:
  13. paddle_A.x=-0.35
  14. if paddle_B.x>0.35:
  15. paddle_B.x=0.35
  16. elif paddle_B.x<-0.35:
  17. paddle_B.x=-0.35
  18. ball.x+=dx*time.dt
  19. ball.z+=dz*time.dt
  20. t.text=f"Player A : Player B {scorea} : {scoreb}"
  21. hit_info=ball.intersects()
  22. if hit_info.hit:
  23. if hit_info.entity==paddle_A:
  24. dz=-dz
  25. if dz>-0.05:
  26. dz-=rd.uniform(0.1,0.3)
  27. else:
  28. dz-=rd.uniform(-0.05,0.2)
  29. if hit_info.entity==paddle_B:
  30. dz=-dz
  31. if dz<0.05:
  32. dz+=rd.uniform(0.1,0.3)
  33. else:
  34. dz+=rd.uniform(-0.05,0.2)
  35. if abs(ball.x)>0.4:
  36. dx=-dx
  37. if ball.z>0.25:
  38. scoreb+=1
  39. ball.x=0
  40. ball.z=-0.2
  41. dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
  42. dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
  43. if ball.z<-0.65:
  44. scorea+=1
  45. ball.x=0
  46. ball.z=-0.2
  47. dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
  48. dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
  49. app=Ursina()
  50. window.color=color.cyan
  51. table=Entity(model="cube",color=color.orange,scale=(10,0.5,14),position=(0,0,0),texture="white_cube")
  52. 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")
  53. paddle_B=duplicate(paddle_A,z=-0.62)
  54. t=Text(text=f"Player A : Player B {scorea} : {scoreb}", position=(-0.85, 0.45), scale=2,color=color.orange)
  55. camera.position=(0,15,-26)
  56. camera.rotation_x=30
  57. Text(text="Player A",scale=2,position=(-0.1,0.32),color=color.orange)
  58. Text(text="Player B",scale=2,position=(-0.1,-0.4),color=color.orange)
  59. line=Entity(parent=table,model="quad",scale=(0.88,0.2,0.1),position=(0,3.5,-0.2))
  60. ball=Entity(parent=table,model="sphere",color=color.gold,scale=.05,position=(0,3.7,-0.2),collider="box")
  61. dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
  62. dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
  63. app.run()

喜欢的话就点赞收藏+关注吧~

谢谢支持~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/790305
推荐阅读
相关标签
  

闽ICP备14008679号