Panda3D Manual: Event Example

Here is a short example of using the Collision Handler Events:

from direct.showbase.ShowBase import ShowBase
from direct.showbase.DirectObject import DirectObject
from direct.interval.IntervalGlobal import Sequence, Func, Wait
from panda3d.core import CollisionTraverser, CollisionHandlerEvent
from panda3d.core import CollisionNode, CollisionSphere
from panda3d.core import VBase4
 
 
class World(DirectObject):
 
def __init__( self ):
# Initialize the traverser.
base.cTrav = CollisionTraverser()
 
# Initialize the handler.
self.collHandEvent = CollisionHandlerEvent()
self.collHandEvent.addInPattern('into-%in')
self.collHandEvent.addOutPattern('outof-%in')
 
# Make a variable to store the unique collision string count.
self.collCount = 0
 
# Load a model. Reparent it to the camera so we can move it.
s = loader.loadModel('smiley')
s.reparentTo(camera)
s.setPos(0, 25, 0)
 
# Setup a collision solid for this model.
sColl = self.initCollisionSphere(s, True)
 
# Add this object to the traverser.
base.cTrav.addCollider(sColl[0], self.collHandEvent)
 
# Accept the events sent by the collisions.
self.accept('into-' + sColl[1], self.collide3)
self.accept('outof-' + sColl[1], self.collide4)
print(sColl[1])
 
# Load another model.
t = loader.loadModel('smiley')
t.reparentTo(render)
t.setPos(5, 25, 0)
 
# Setup a collision solid for this model.
tColl = self.initCollisionSphere(t, True)
 
# Add this object to the traverser.
base.cTrav.addCollider(tColl[0], self.collHandEvent)
 
# Accept the events sent by the collisions.
self.accept('into-' + tColl[1], self.collide)
self.accept('outof-' + tColl[1], self.collide2)
print(tColl[1])
 
print("WERT")
 
def collide(self, collEntry):
print("WERT: object has collided into another object")
Sequence(Func(collEntry.getFromNodePath().getParent().setColor,
VBase4(1, 0, 0, 1)),
Wait(0.2),
Func(collEntry.getFromNodePath().getParent().setColor,
VBase4(0, 1, 0, 1)),
Wait(0.2),
Func(collEntry.getFromNodePath().getParent().setColor,
VBase4(1, 1, 1, 1))).start()
 
 
def collide2(self, collEntry):
print("WERT.: object is no longer colliding with another object")
 
def collide3(self, collEntry):
print("WERT2: object has collided into another object")
 
def collide4(self, collEntry):
print("WERT2: object is no longer colliding with another object")
 
def initCollisionSphere(self, obj, show=False):
# Get the size of the object for the collision sphere.
bounds = obj.getChild(0).getBounds()
center = bounds.getCenter()
radius = bounds.getRadius() * 1.1
 
# Create a collision sphere and name it something understandable.
collSphereStr = 'CollisionHull' + str(self.collCount) + "_" + obj.getName()
self.collCount += 1
cNode = CollisionNode(collSphereStr)
cNode.addSolid(CollisionSphere(center, radius))
 
cNodepath = obj.attachNewNode(cNode)
if show:
cNodepath.show()
 
# Return a tuple with the collision node and its corrsponding string so
# that the bitmask can be set.
return (cNodepath, collSphereStr)
 
ShowBase()
# Run the world. Move around with the mouse to create collisions.
w = World()
run()