目录
前言实现方法完整代码前言
之前,我们用pygame做了一个2D的Pong游戏,今天我们做一个3D的,游戏画面如下:
(资料图片)
用ad和←→操作,双人对战
实现该效果我们使用Python强大的3D引擎Ursina,基础的使用方法见这篇文章:详解Python3D引擎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游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?