I am trying to figure out exactly how the collision code works when handling events. I am working on a game where I need objects in motion to collide with other objects in motion and am not completely sure I understand what events are being thrown with the collision handler. The following code will help me explain what I do not understand and is a modification of what it is the manual.
import direct.directbase.DirectStart
from direct.interval.IntervalGlobal import Sequence
from direct.showbase import DirectObject
from pandac.PandaModules import *
import random
class World( DirectObject.DirectObject ):
def __init__( self ):
#initialize traverser
base.cTrav = CollisionTraverser()
#initialize handler
self.collHandEvent=CollisionHandlerEvent()
self.collHandEvent.addInPattern('into-%in')
self.collHandEvent.addOutPattern('outof-%in')
#initialize collision count (for unique collision strings)
self.collCount=0
self.loadObj1()
self.loadObj2()
def loadObj1(self):
#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)
#set up bitmasks
#this object can only collide into things
sColl[0].node().setIntoCollideMask( BitMask32.bit(2) )
#this object will only collide with objects with this bitmask
sColl[0].node().setFromCollideMask( BitMask32.bit(1) )
#add this object to the traverser
base.cTrav .addCollider(sColl[0] , self.collHandEvent)
self.accept( 'into-' + sColl[1], self.collide3)
self.accept( 'outof-' + sColl[1], self.collide4)
self.posint1 = s.posInterval(20,Point3(random.random()*200-100,0,0))
self.AIPath = Sequence(self.posint1, name = 'AIPath')
self.AIPath.start()
def loadObj2(self):
#load a 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)
#set up bitmasks
#this object can only be collided into and will collide with the other object
tColl[0].node().setIntoCollideMask( BitMask32.bit( 1 ))
tColl[0].node().setFromCollideMask( BitMask32.bit(2) )
#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)
def collide(self, collEntry):
print "WERT: object has collided into another object"
def collide2(self, collEntry):
print "WERT: object is no longer colliding with another object"
def collide3(self, collEntry):
print "The other collision"
def collide4(self, collEntry):
print "The other leave"
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' +obj.getName()
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
# return the collison node so that the bitmask can be set
return (cNodepath,collSphereStr )
#run the world. move around with the mouse to create collisions
w = World()
run()
When I run this and there is a collision I get two collide and collide2 events instead of getting one of each of the 4 collide events. I don’t understand why this is happening and would be thrilled if someone could explain what I am missing.