multiple CollisionHandlerEvent()

Hi,

I am developping a server, which has several zones. Each zone has asteroids, and ships. For each zone, I want to use a different collider and a different collisionhandlerevent.

It seems, when I do self.hdlCollider=CollisionHandlerEvent(), I grab always the same collisionHandlerEvent. The consequence, is that it has events of each collision between each zone, my bullet fired in zone1, collides with asteroid in zone1, zone2, zone3…

I don’t wish that, you can understand. So is it possible to instantiate several CollisionHandlerEvent, or must I use an unique handler, and so play with pattern and so on, to identify the right collision (which is at my mind the best solution…).

Thank you

I don’t understand what you mean. The line:

self.hdlCollider=CollisionHandlerEvent()

constructs a new, unique instance of the CollisionHandlerEvent class, and stores it in self.hdlCollider. Each time you execute this line, you will replace self.hdlCollider with a new and different instance.

You can certainly store each CollisionHandlerEvent instance in a different member and then you will have multiple CollisionHandlerEvent objects, which you can then set to generate different event messages.

But the CollisionHandlerEvent is the handler, so I don’t know what you mean when you say “is it possible to instantiate several CollisionHandlerEvent, or must I use an unique handler,” since those two phrases are the same thing. Or maybe you meant to say “must I use a unique traverser,” in which case the answer is no, you do not need to have a unique traverser, just a unique handler.

Actually, you don’t really need a unique handler either, if your goal is to trigger unique events for each collision, because the event names are based on the node names of the things you’re colliding into and from. So a single CollisionHandlerEvent can generate all sorts of unique event names, if you name your objects appropriately. This is the way most people set up their collision systems.

But it sounds like you’re talking about a completely different problem altogether. A bullet in zone1 won’t collide with an asteroid in zone2 unless they’re actually in the same space. If they are in the same space, but you don’t want them to test for intersections, then you should use collision bitmasks to avoid this.

David

I got something wrong in this case … what I do:

self.collider=CollisionTraverser("TraverserZone" + self.name)  
			self.hdlCollider=CollisionHandlerEvent()
			self.hdlCollider.addInPattern('into-%in')
			self.hdlCollider.addOutPattern('outof-%in')

objToCollide=shimCollider.getInstance(self.name).getListObjCollide()
for objColl in objToCollide.keys():
   self.collider.addCollider(objToCollide[objColl] , self.hdlCollider)
   if objToCollide[objColl] .getTag("classname")=="bullet":
       self.accept( 'into-' +  objToCollide[objColl] .getName(), self.testcollide)



def testcollide(self,collEntry):
		target=collEntry.getFromNodePath()
		source=collEntry.getIntoNodePath()
		print "Zone::testcollide#############"
		#~ self.collider.removeCollider(source)
		print source
		print source.getParent().getName()
		print source.getTag("objname")
		print "Zone::plop @@@@@@"
		print target.getParent().getName()
		print target.getTag("objname")
		print "Zone::testcollide#############"
		if target.getTag("classname")=="bullet":
			self.collider.removeCollider(source)
			self.ignore( 'into-' + source.getName())
		

What I got in my logs:
Starting the zones (zone1 and zone2)

Zone::runCollisionManagement addObjToCollide asteroid###render/ast114/asteroidin zone : zone2
Zone::runCollisionManagement addObjToCollide asteroid###render/ast115/asteroidin zone : zone2
Zone::runCollisionManagement addObjToCollide asteroid###render/ast116/asteroidin zone : zone2
Zone::runCollisionManagement addObjToCollide asteroid###render/ast111/asteroidin zone : zone2
Zone::runCollisionManagement addObjToCollide asteroid###render/ast112/asteroidin zone : zone2
Zone::runCollisionManagement addObjToCollide asteroid###render/ast113/asteroidin zone : zone2
Zone::runCollisionManagement addObjToCollide asteroid###render/ast1/asteroidin zone : zone1
Zone::runCollisionManagement addObjToCollide asteroid###render/ast2/asteroidin zone : zone1
Zone::runCollisionManagement addObjToCollide asteroid###render/ast3/asteroidin zone : zone1
Zone::runCollisionManagement addObjToCollide asteroid###render/ast4/asteroidin zone : zone1

Shooting a bullet in zone1

Zone::runCollisionManagement addObjToCollide bullet###render/bullet1/bulletin zone : zone1

and it collides with asteroids:

Zone::testcollide #############
render/bullet1/bullet
bullet1
bullet1
Zone::plop @@@@@@
ship0
ship0
Zone::testcollide #############
Zone::testcollide #############
render/bullet1/bullet
bullet1
bullet1
Zone::plop @@@@@@
ast111
ast111
Zone::testcollide #############
Zone::testcollide #############
render/bullet1/bullet
bullet1
bullet1
Zone::plop @@@@@@
ast1
ast1
Zone::testcollide #############

To differenciate easyly the asteroid, in zone2 asteroids have name > 100 like ast111.
As you can see, it detects a collision in zone2, and in zone1 (ast1, ast1111, ship0), with my bullet zone1.

what’s wrong on what I’ve done?

Thanks for your help

I don’t know what you mean by “zone”, exactly, but I can only surmise that you have several zones that are meant to be different spaces, but they all use the same 3-d coordinate space? Like different levels of a building, for instance?

Why don’t you create a different traverser for each zone, and call trav.traverse(zoneRoot) for each traverser. That way the traverser will only detect collisions at zoneRoot and below, and there’s no ambiguity.

David

Yesn a zone, is what you guess :stuck_out_tongue: They effectively uses the same space coordinates.

One traverser per zone. Yes it is why I tried to do.

self.collider=CollisionTraverser("TraverserZone" + self.name)  

But I am not sure of what I have to pass as argument to the constructor? I just give a name I choose…

I am wondering. I have only one render today, and all my models are reparent to this one. Isn’t that my error?

The string you pass to the CollisionTraverser constructor is only a name, which is meaningful only to you. The important part is when you call collider.traverse(root), at that point, you pass in the root node that you want to traverse from.

Well, yes, you will need a different root node for each zone, something other than render. Any node you create for this purpose is fine.

Note that if you assign your traverser to base.cTrav, then Panda will automatically call base.cTrav.traverse(render) for you every frame. But you don’t want this, because you don’t want to traverse from render, you want to traverse from each of your zone roots instead. So don’t assign anything to base.cTrav(), and call traverse() yourself.

David

ok, as argument to traverse you pass the root node?

So I just create a node, and reparent all nodes I create in this zone, to this “rootzoneX” node?
And next I pass this “rootzonXe” to traverse() as argument?

Is it that?

Yes.

It may take little time to refactor my code for this, But I will answer.

Thank you anyway for your help, and patience!

OK it is solved.

Thank you a lot for your help…