CollisionTraverser issues

Currently in the process of developing a game in which objects are classified as Pushable, Immovable, and Collectable. However, we’re having some trouble dealing with allowing the CollisionTraverser to deal with all three of these object types. The Wiki states that you should avoid multiple traversers except in special cases for performance reasons, so we don’t want to have to resort to that.

We currently have things set up so that there are three CollisionHandlers.
The first is “pusher”, a CollisionHandlerPusher, which is used to handle
when the player runs into an object that cannot be moved. It does as its name implies and pushes the player away when he/she hits an immovable object.

The seconder is “pushback”, another CollisionHandlerPusher, which allows the player to push pushable objects.

The last is a CollisionEventHandler, which fires events when the player runs over a collectable.

The problem that occurs seems to be some kind of conflict between the pusher and the event handler. If you add the event handler first, the player won’t be able to go through immovable objects. If you add the pusher first, the player wont be able to pick up collectables. If I print the contents of the CollisionTraverser it confirms that the handler added second overwrites the original. Why is this happening only two these two? The pushback is entirely unaffected.

Here are some code snippets that are pertinent to this problem:

      self.pusher = CollisionHandlerPusher()
		self.pushback = CollisionHandlerPusher()
		self.cHandler = CollisionHandlerEvent()
		self.cHandler.setInPattern("collide-%in")
		self.cTrav = CollisionTraverser()
		
		base.cTrav = self.cTrav

      cNode = CollisionNode("Plane")
		cNode.addSolid(cSphere)
		
		cNode.setIntoCollideMask(BitMask32.bit(2))
		cNode.setFromCollideMask( BitMask32.bit(1))
		cNodePath = self.plane.attachNewNode(cNode)
		######
		#Comment out to remove visiblecollision sphere 
		#cNodePath.show()
		######
		self.cTrav.addCollider(cNodePath, self.cHandler)
		
		"Set up the pushers"
		for i in range(7):
			self.cTrav.addCollider(self.movables[i].cNodePath, self.pushback)
			self.pushback.addCollider(self.movables[i].cNodePath, self.movables[i].model)
		#for i in range(2):
			#self.cTrav.addCollider(self.immovables[i].cNodePath, self.cHandler)
		
		self.cTrav.addCollider(cNodePath, self.pusher)
		self.cTrav.addCollider(cNodePath, self.cHandler)
		print self.cTrav
		self.pusher.addCollider(cNodePath,self.plane)


		
		self.fishSchool.setupCollision(self.plane)

I know it isn’t a bitmask problem, but we are completely at a loss here. Any help is greatly appreciated. If you need any more info let me know as well.

Thanks!

Just make 2 coll solids to be assigned to pusher and event handler. Make sure to assign different bitmask.

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject
from direct.task import Task
import sys

class World(DirectObject):
  def __init__(self):
      render.setTransparency(1)
      render.setAlphaScale(.5)

      self.keys = {}
      self.KEY_UP='up'
      self.KEY_DOWN='down'
      self.KEY_RIGHT='right'
      self.KEY_LEFT='left'
      self.acceptMultiKey('arrow_up',self.KEY_UP)
      self.acceptMultiKey('arrow_down',self.KEY_DOWN)
      self.acceptMultiKey('arrow_left',self.KEY_LEFT)
      self.acceptMultiKey('arrow_right',self.KEY_RIGHT)
      self.accept('escape',sys.exit)

      #initialize traverser
      base.cTrav = CollisionTraverser()
      base.cTrav.showCollisions(render)
      #initialize collision handlers
      self.pusher = CollisionHandlerPusher()
      self.cHandler = CollisionHandlerEvent()
      self.cHandler.setInPattern("collide-%in")
      self.accept('collide-jack', self.collectJack)

      #########
      #load smiley
      smiley = loader.loadModel('smiley')
      smiley.reparentTo(render)
      smiley.setPos(0, 25.5,0.5)
      #create a collision solid for this model
      cNode = CollisionNode('smiley')
      cNode.addSolid(CollisionSphere(0,0,0,1.1))
      smileyC = smiley.attachNewNode(cNode)
      #smileyC.show()

      #########
      #load frowney
      self.frowney = loader.loadModel('frowney')
      self.frowney.reparentTo(render)
      self.frowney.setPos(5, 25,0)
      eventMASK = BitMask32.bit(2)
      #create a collsion solid for this model
      cNode1 = CollisionNode('frowneyPusher')
      cNode1.addSolid(CollisionSphere(0,0,0,1.1))
      cNode1.setIntoCollideMask(BitMask32.allOff())
      cNode1.setFromCollideMask(BitMask32.bit(0))
      frowneyC1 = self.frowney.attachNewNode(cNode1)
      #create another collsion solid for this model
      cNode2 = CollisionNode('frowneyEvent')
      cNode2.addSolid(CollisionSphere(0,0,0,1.1))
      cNode2.setIntoCollideMask(BitMask32.allOff())
      cNode1.setFromCollideMask(eventMASK)
      frowneyC2 = self.frowney.attachNewNode(cNode2)

      # load the jacks
      for j in range(-3,4):
          jack = loader.loadModelCopy('jack')
          jack.reparentTo(render)
          jack.setPos(j*2, 20,0)
          jack.setH(180)
          #create a collision solid for this model
          cNode = CollisionNode('jack')
          cNode.addSolid(CollisionSphere(0,0,0,.25))
          cNode.setFromCollideMask(BitMask32.allOff())
          cNode.setIntoCollideMask(eventMASK)
          jackC = jack.attachNewNode(cNode)
          jackC.show()

      #########
      #add collision node to the traverser and the pusher
      self.pusher.addCollider(frowneyC1,self.frowney)
      base.cTrav.addCollider(frowneyC1,self.pusher)
      base.cTrav.addCollider(frowneyC2, self.cHandler)
      #########
      base.cam.setZ(10)
      base.cam.lookAt(smiley)
      self.mainLoop = taskMgr.add(self.gLoop, "gLoop")
      self.mainLoop.last = 0

  def gLoop(self,task):
      dt = task.time - task.last
      task.last = task.time
      self.keybControl(dt)
      return Task.cont

  def acceptMultiKey(self,key,val):
      self.keys[val]=0
      self.accept(key,self.setKey,[val, 1])
      self.accept(key+'-up',self.setKey,[val, 0])

  def setKey(self,key,val):
      self.keys[key]=val

  def keybControl(self,dt):
      move=7.*dt
      vel=Vec3(0,0,0)
      if self.keys[self.KEY_UP]:
         vel+=Vec3(0,move,0)
      if self.keys[self.KEY_DOWN]:
         vel+=Vec3(0,-move,0)
      if self.keys[self.KEY_RIGHT]:
         vel+=Vec3(move,0,0)
      if self.keys[self.KEY_LEFT]:
         vel+=Vec3(-move,0,0)
      self.frowney.setPos(self.frowney.getPos()+vel)

  def collectJack(self,entry):
      entry.getIntoNodePath().getParent().removeNode()

World()
run()

Excellent, that fixed it nicely. Thank you for the help!