Panda3D学习 (8):棋盘操作 碰撞检测

对这个例程的介绍有点深意,说是通过碰撞检测机制来操作鼠标控制棋盘,但是又说Plane类可以更快的实现。不知道这个Plane类是啥,但是先研究下这个例程本身好了。

self.disableMouse()先说一下这个方法在之前每个例程里都有提到,之前觉得没什么,今天把这个注释掉后发现问题很大。

它的作用不是禁用鼠标,而是禁用默认的鼠标控制camera的功能。 

1. 碰撞检测机制

from panda3d.core import CollisionHandlerQueue, CollisionRay

首先导入这两个包

Examples:

nodePath.setCollideMask(BitMask32(0x10))

This sets the into collide mask of nodePath, and all children of nodePath, to the value 0x10, regardless of the value each node had before.

nodePath.node().setFromCollideMask(BitMask32(0x10))

You can only set the from collide mask on a collision node, and you must set it directly on the node itself, not on the NodePath.

这两句的区别就在于一个是作为into对象,一个作为from对象。但看了例程之后 发现如果是into对象,是这样的语句:

self.squares[i].find(“**/polygon”).node().setIntoCollideMask(BitMask32.bit(1))

我觉得还是按例程来做即可了。

This control is provided with the collide masks. Every CollisionNode has two collide masks: a “from” mask, which is used when the CollisionNode is acting as a “from” object (i.e. it has been added to a CollisionTraverser), and an “into” mask, which is used when the node is acting as an “into” object (i.e. it is in the scene graph, and a from object is considering it for collisions).

这一段解释了两者的区别,大致是from主动,into被动。

碰撞掩码: 在碰撞节点的“from”中的实体与另一个CollisionNode或GeomNode进行碰撞测试之前,比较碰撞掩码。具体来说,from对象的“from”掩码和into对象的“into”掩码被“与”在一起。如果结果不为零 – 意味着两个掩码至少有一个相同的位 – 则尝试进行碰撞测试; 否则,这两个对象将被忽略。

nodePath.node().setFromCollideMask(BitMask32(0x10))

BitMask32指的就是32位的碰撞掩码(32个二进制位)

nodePath.setCollideMask(BitMask32(0x04), BitMask32(0xff))

This replaces the lower 8 bits of nodePath and all of its children with the value 0x04, leaving the upper 24 bits of each node unchanged.

这一段我是这么理解的,0x代表16进制,16进制的1位代表2进制4位,所以0x04共8个bit,也就是说最低位的8个bit被设置了,剩余的32-8=24个bit没有用到。

2. 棋盘布局

self.squares[i].find(“**/polygon”).node().setTag(‘square’, str(i))

这一步用于保存棋盘标签

nearPoint = render.getRelativePoint(
    camera, self.pickerRay.getOrigin())
# Same thing with the direction of the ray
nearVec = render.getRelativeVector(
    camera, self.pickerRay.getDirection())
self.pieces[self.dragging].obj.setPos(

    PointAtZ(.5, nearPoint, nearVec))

这里实在不知道这代码的运行原理,不过应该是用来模拟了棋子的运动。应该是通过点和方向确定了移动的线。

3. 整个碰撞检测过程:

self.picker = CollisionTraverser()  定义一个碰撞移动器,

self.pq = CollisionHandlerQueue() 建立一个handler

self.pickerNode = CollisionNode(‘mouseRay12’)
# Attach that node to the camera since the ray will need to be positioned
# relative to it
self.pickerNP = camera.attachNewNode(self.pickerNode)
# Everything to be picked will use bit 1. This way if we were doing other
# collision we could separate it
self.pickerNode.setFromCollideMask(BitMask32.bit(1))
self.pickerRay = CollisionRay()  # Make our ray
# Add it to the collision node
self.pickerNode.addSolid(self.pickerRay)
# Register the ray as something that can cause collisions

self.picker.addCollider(self.pickerNP, self.pq)

建立了一个collision node

self.picker.traverse(self.squareRoot)

使用traverse方法,只在squareRoot上检测碰撞(定义好的棋盘,可以就不用检测别的了)

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/zanbaixi2128/article/details/80858749
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞