I have this code for a tilemap:
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerQueue, CollisionRay
from panda3d.core import CollisionBox, BitMask32, LineSegs
class TileMap():
# -----------------------------------------------------
def __init__(self):
self.width = 8
self.height = 8
self.tile_width = 8
self.tile_height = 8
self.full_width = self.width * self.tile_width
self.full_height = self.height * self.tile_height
self.half_width = self.full_width / 2
self.half_height = self.full_height / 2
self.picker = CollisionTraverser()
self.pq = CollisionHandlerQueue()
self.pickerNode = CollisionNode('mouseRay')
self.pickerNP = render.attachNewNode(self.pickerNode)
self.pickerNode.setFromCollideMask(BitMask32.bit(1))
self.pickerRay = CollisionRay()
self.pickerNode.addSolid(self.pickerRay)
self.picker.addCollider(self.pickerNP, self.pq)
self.tile_dict = {
"0": ["grass", "assets/tiles/grass1.obj", "0"],
"1": ["water", "assets/tiles/water1.obj", "0"],
"2": ["hill", "assets/tiles/hill1.obj", "0"]
}
self.tiles = [
["1", "0", "0", "1", "1", "0", "0", "1"],
["0", "0", "0", "0", "0", "0", "0", "0"],
["0", "1", "1", "0", "0", "2", "0", "0"],
["1", "0", "0", "0", "0", "2", "0", "1"],
["0", "0", "0", "2", "2", "2", "0", "1"],
["0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "1", "0", "1", "1", "0", "0"]
]
# the dimensions for the collisionbox
dx = self.tile_width / 2
dy = 1
dz = self.tile_height / 2
# node for the tiles
self.tilesRoot = render.attachNewNode("tilesRoot")
for i in range(self.width - 1, -1, -1):
for j in range(self.height - 1, -1, -1):
x = i * self.tile_width
z = j * self.tile_height
t = self.tiles[j][i]
m = loader.loadModel(self.tile_dict[t][1])
m.setPos(x, 0, z)
m.reparentTo(self.tilesRoot)
# set the collisionbox
box = CollisionBox((0, 0, 0), dx, dy, dz)
mPath = m.attachNewNode(CollisionNode('cnode'))
mPath.node().addSolid(box)
mPath.node().setIntoCollideMask(BitMask32.bit(1))
mPath.node().setTag("monu_i", str(i))
mPath.node().setTag("monu_j", str(j))
# mPath.show()
# -----------------------------------------------------
def getTile(self, x, y):
# check ray collsion with mouse
self.pickerRay.setFromLens(base.camNode, x, y)
print(base.cam.getPos())
# draw the ray
seg = LineSegs("lines")
seg.setColor(1, 1, 0, 1)
seg.drawTo(self.pickerRay.getOrigin())
seg.drawTo(self.pickerRay.getDirection())
segnode = seg.create(False)
render.attachNewNode(segnode)
self.picker.traverse(self.tilesRoot)
if self.pq.getNumEntries() > 0:
self.pq.sortEntries()
i = int(self.pq.getEntry(0).getIntoNode().getTag('monu_i'))
j = int(self.pq.getEntry(0).getIntoNode().getTag('monu_j'))
If I click on the tiles, you can see that the ray is wrong, he shows always to the first tile at 0, 0, 0:
Can someone check, what’s my mistake is?