Moving Gold

Have made great progress on my program so far however I am stuck. I have a gold crystal that I want to move to a random position when the panda collides with it.

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
                 pd= CollisionSphere(1,-500,355,195)
                 pnodePath = self.player.attachNewNode(CollisionNode('pnode'))
                 pnodePath.node().addSolid(pd)
                 pnodePath.show()


        
        #Collision Sphere for Objective
                 cs = CollisionSphere(1, 1, 55, 53)
                 cnodePath = self.objective.attachNewNode(CollisionNode('cnode'))
                 cnodePath.node().addSolid(cs)
                 cnodePath.show()#uncomment to show the collision sphere
                 
                 self.cTrav = CollisionTraverser()

                self.objectiveHandlerone = CollisionHandlerQueue()
                self.cTrav.addCollider(cnodePath, self.objectiveHandlerone)

                self.objectiveHandler = CollisionHandlerEvent()
                self.cTrav.addCollider(cnodePath, self.objectiveHandler)
                
            def setKey(self, key, value):
                self.keyMap[key] = value
            def move(self, task):
                self.cTrav.traverse(self.render)
                r= random.randint(-60, -25)#randomly generates X for crystal 
                e= random.randint(-60, 30)#randomly generates Y for crystal
            if self.objectiveHandler.addOutPattern('%fn-out-%in'):
                self.objective.setPos(r,e,3)
                self.objective.getPos()
     

If you need more code than this to help please tell me

It looks to me as though you’ve misunderstood how CollisionHandlerEvent works.

First of all, if I’m not much mistaken, “addOutPattern” simply indicates to the system that you want events for the given pattern, rather than detecting a collision; specifically, it sets up an event for one object leaving the other (moving out of the other).

Second, you shouldn’t have to manually call traverse for base.cTrav: if I’m not much mistaken, it’s a special variable that should be automatically traversed for you every update, as I recall. If you were to create another traverser – if, for example, you wanted traversal to only happen when the mouse is pressed, rather than repeatedly in the background – you wouldn’t assign it to base.cTrav but to your own variable, and call traverse from that variable.

The basic pattern of usage should be something along these lines, I believe:

  • Set up your collision handler – this would be your CollisionHandlerEvent object, which at a glance you seem to have set up, I believe.
  • Add a pattern to your handler; since you want to detect a collision, I imagine that you’ll likely want an “in” pattern. This should cause the system to register an event in the pattern that you provide. Something like this, if we were detecting a cat bumping into a ball: myTraverser.addInPattern(“cat-into-ball”)
  • Link the event to a method, along these lines: self.accept(“cat-into-ball”, myEventMethod)
  • Define the method mentioned in the previous step: def myEventMethod(self, collisionEntry):

All that done, the method “myEventMethod” should be called whenever the cat hits a ball. Note that I haven’t used a task in any of this – I don’t think that one is called for in this case.

For more information, see this manual page.

I keep getting the error EventMethod() takes exactly 2 arguements (1 given) any idea why?

        self.objectiveHandler.addInPattern("player-into-objective")

        r= random.randint(-60, -25)#randomly generates X for crystal 
        e= random.randint(-60, 30)#randomly generates Y for crystal
        
        def EM(self,CollisionEntry):
            self.objective.setPos(r,e,3)

        self.accept("player-into-objective",EM)

It might be because you capitalised “CollisionEntry”, which is the name of a class. If you use a lower-case ‘c’ it might work.