from direct.showbase.ShowBase import ShowBase
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerQueue, CollisionRay
from panda3d.core import Material, LRotationf, NodePath
from panda3d.core import AmbientLight, DirectionalLight
from panda3d.core import TextNode
from panda3d.core import LVector3, BitMask32
from direct.gui.OnscreenText import OnscreenText
from direct.interval.MetaInterval import Sequence, Parallel
from direct.interval.LerpInterval import LerpFunc
from direct.interval.FunctionInterval import Func, Wait
from direct.task.Task import Task
import sys
# 常量
ACCEL = 70 # 加速度
MAX_SPEED = 5 # 最大速度
MAX_SPEED_SQ = MAX_SPEED ** 2 # 平方
# Instead of length
class BallInMazeDemo(ShowBase):
def __init__(self):
# 初始化我们继承的SkyBASE类,它将创建一个窗口并设置我们所需要的渲染到其中的所有内容。
ShowBase.__init__(self)
# 将标题和指令文本置于屏幕上。
self.title = \
OnscreenText(text="Panda3D: Ball",
parent=base.a2dBottomRight, align=TextNode.ARight,
fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=.08,
shadow=(0, 0, 0, 0.5))
self.instructions = \
OnscreenText(text="shubiao",
parent=base.a2dTopLeft, align=TextNode.ALeft,
pos=(0.05, -0.08), fg=(1, 1, 1, 1), scale=.06,
shadow=(0, 0, 0, 0.5))
self.accept("escape", sys.exit) #离开程序
#禁用默认的基于鼠标的相机控制。这是我们继承的SkyBASE类的一种方法。.
self.disableMouse()
camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera
# 加载迷宫并将其放置在场景中
self.maze = loader.loadModel("models/maze")
self.maze.reparentTo(render)
# 大多数时候,你希望通过不可见的几何形状来测试碰撞,而不是测试每个多边形。
# 这是因为对场景中的每一个多边形的测试通常都太慢。固体可以简化或近似几何,仍然可以得到良好的结果。
# 查找名为Walth-CulrDE的碰撞节点
self.walls = self.maze.find("**/wall_collide")
#使用位图对冲突对象进行排序,将使我们想要的球与包含比特0碰撞
self.walls.node().setIntoCollideMask(BitMask32.bit(0))
# 碰撞节点通常是看不见的,但可以显示出来。现在会找到孔的触发器并将它们的面具设置为0。
# 我们也设置他们的名字,使他们更容易识别碰撞
self.loseTriggers = []
for i in range(6):
trigger = self.maze.find("**/hole_collide" + str(i))
trigger.node().setIntoCollideMask(BitMask32.bit(0))
trigger.node().setName("loseTrigger")
self.loseTriggers.append(trigger)
#地面碰撞是与迷宫中的地面相同的平面上的一个多边形。我们将用一个射线来与它碰撞,
# 这样我们就能准确地知道在每一个帧上放置什么高度。
# 因为这不是我们希望球本身碰撞的东西,它有一个不同的位掩码。
self.mazeGround = self.maze.find("**/ground_collide")
self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1))
# 加载球并将它附加到场景上,它是在根虚拟节点上,这样我们就可以旋转球本身而不旋转将附着在它上的光线。
self.ballRoot = render.attachNewNode("ballRoot")
self.ball = loader.loadModel("models/ball")
self.ball.reparentTo(self.ballRoot)
# 找到碰撞球,这是在egg文件中创建的,它有一个来自0位的碰撞掩码,
# 一个是无位碰撞掩码。这意味着球只能引起碰撞,不能碰撞。
self.ballSphere = self.ball.find("**/ball")
self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())
# 创建了一个光线,从球上面开始向下投射。这是为了确定球的高度和地板的角度。
self.ballGroundRay = CollisionRay() # 创建光线
self.ballGroundRay.setOrigin(0, 0, 10) # 设置原点
self.ballGroundRay.setDirection(0, 0, -1) # 设置方向
# 碰撞实体进入碰撞节点创建并命名节点
self.ballGroundCol = CollisionNode('groundRay')
self.ballGroundCol.addSolid(self.ballGroundRay) # 添加光线
self.ballGroundCol.setFromCollideMask(
BitMask32.bit(1)) # 设置口罩
self.ballGroundCol.setIntoCollideMask(BitMask32.allOff())
# 将球连接到球底部,使光线与球相对应(它总是在球上10英尺,向下点)。
self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol)
self.cTrav = CollisionTraverser()
self.cHandler = CollisionHandlerQueue()
#现在我们添加碰撞节点,这些冲突节点可以向遍历器创建冲突。
# 遍历器将将这些与场景中的所有其他节点进行比较。
self.cTrav.addCollider(self.ballSphere, self.cHandler)
self.cTrav.addCollider(self.ballGroundColNp, self.cHandler)
# 碰撞穿越器有一个内置的工具来帮助可视化碰撞
ambientLight = AmbientLight("ambientLight")
ambientLight.setColor((.55, .55, .55, 1))
directionalLight = DirectionalLight("directionalLight")
directionalLight.setDirection(LVector3(0, 0, -1))
directionalLight.setColor((0.375, 0.375, 0.375, 1))
directionalLight.setSpecularColor((1, 1, 1, 1))
self.ballRoot.setLight(render.attachNewNode(ambientLight))
self.ballRoot.setLight(render.attachNewNode(directionalLight))
# 增加一个镜面高亮度的球,使它看起来有光泽。通常,这是在.egg文件中指定的。
m = Material()
m.setSpecular((1, 1, 1, 1))
m.setShininess(96)
self.ball.setMaterial(m, 1)
#调用start以进行初始化
self.start()
def start(self):
# 迷宫模型中也有一个定位器,用于在哪里启动球来访问它,我们使用find命令。
startPos = self.maze.find("**/start").getPos()
#把球放在起始位置
self.ballRoot.setPos(startPos)
self.ballV = LVector3(0, 0, 0) # 初始速度为 0
self.accelV = LVector3(0, 0, 0) # 初始加速度为 0
# 创建移动任务,但首先确保它尚未运行
taskMgr.remove("rollTask")
self.mainLoop = taskMgr.add(self.rollTask, "rollTask")
# 处理光线与地面之间的碰撞
def groundCollideHandler(self, colEntry):
# 将球设置到适当的Z值,以使其准确地位于地面上。
newZ = colEntry.getSurfacePoint(render).getZ()
self.ballRoot.setZ(newZ + .4)
# 求加速度方向。首先将表面法线与上矢相交,得到垂直于斜率的矢量。
norm = colEntry.getSurfaceNormal(render)
accelSide = norm.cross(LVector3.up())
# 矢量与曲面法线相交,得到一个指向斜坡的矢量。
# 通过在3D中获得加速度,而不是在2D中,我们减少了每帧的误差量,减少抖动。
self.accelV = norm.cross(accelSide)
# 处理球与墙之间的碰撞。
def wallCollideHandler(self, colEntry):
# 首先我们计算一些数字,需要做一个反射。
norm = colEntry.getSurfaceNormal(render) * -1 # 墙面标准线
curSpeed = self.ballV.length() # 当前速度
inVec = self.ballV / curSpeed # 运动方向
velAngle = norm.dot(inVec) # 角度
hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
hitDir
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
写在前面 本期内容 - 基于panda3d的迷宫中的小球游戏 所需环境 - python - pycharm或anaconda - panda3d Panda3D Panda3D是一种开放源代码的游戏引擎,专门用于开发三维游戏、模拟器和其他图形应用程序。它由迪士尼开发,并于2002年发布。Panda3D提供了强大的功能,包括高性能渲染、物理模拟、动画、碰撞检测和网络通信。它使用Python作为开发语言,因此可以轻松地进行游戏逻辑和脚本编写。Panda3D还支持C++和其他编程语言。它使用先进的渲染技术,包括阴影、光照和反射,可以创建令人惊叹的视觉效果。它还提供了丰富的工具和资源,使开发者能够快速创建和部署游戏。Panda3D被广泛用于游戏开发、虚拟现实、教育和科学研究等领域。它是一个强大而灵活的引擎,使开发者能够创造出有趣、引人入胜的体验。 程序设计 ```python from direct.showbase.ShowBase import ShowBase from panda3d.core import Collis ……
资源推荐
资源详情
资源评论
收起资源包目录
31-基于panda3d的迷宫中的小球游戏.rar (5个子文件)
31-基于panda3d的迷宫中的小球游戏
迷宫中的小球
ball
main.py 11KB
models
ball.egg.pz 12KB
limba.jpg 45KB
maze.egg.pz 49KB
iron05.jpg 60KB
共 5 条
- 1
资源评论
Want595
- 粉丝: 7w+
- 资源: 71
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功