예제 #1
0
파일: fountain.py 프로젝트: codedragon/play
    def create_ball_coll(self, ball_actor):
        # Build a collisionNode for this smiley which is a sphere of the same diameter as the model
        ball_coll_node = ball_actor.attachNewNode(CollisionNode('ball_cnode'))
        ball_coll_sphere = CollisionSphere(0, 0, 0, 1)
        ball_coll_node.node().addSolid(ball_coll_sphere)
        # Watch for collisions with our brothers, so we'll push out of each other
        ball_coll_node.node().setIntoCollideMask(BitMask32().bit(self.ball_bit))
        # we're only interested in colliding with the ground and other smileys
        cMask = BitMask32()
        cMask.setBit(self.ground_bit)
        cMask.setBit(self.ball_bit)
        ball_coll_node.node().setFromCollideMask(cMask)

        # Now, to keep the spheres out of the ground plane and each other, let's attach a physics handler to them
        ball_handler = PhysicsCollisionHandler()

        # Set the physics handler to manipulate the smiley actor's transform.
        ball_handler.addCollider(ball_coll_node, ball_actor)

        # This call adds the physics handler to the traverser list
        # (not related to last call to addCollider!)
        self.base.cTrav.addCollider(ball_coll_node, ball_handler)

        # Now, let's set the collision handler so that it will also do a CollisionHandlerEvent callback
        # But...wait?  Aren't we using a PhysicsCollisionHandler?
        # The reason why we can get away with this is that all CollisionHandlerXs are inherited from
        # CollisionHandlerEvent,
        # so all the pattern-matching event handling works, too
        ball_handler.addInPattern('%fn-into-%in')

        return ball_coll_node
예제 #2
0
 def __init__(self, debug=False):
     self._debug = debug
     
     self.handler = PhysicsCollisionHandler()
     self.handler.setStaticFrictionCoef(0.1)
     self.handler.setDynamicFrictionCoef(0.05)
     self.handler.addInPattern('into-%in')
     self.handler.addAgainPattern('again-%in')
     self.handler.addOutPattern('out-%in')
     self.handler.addInPattern('%fn-into-%in')
예제 #3
0
 def __init__(self, mouse):
     ShowBase.__init__(self)
     self.mouse = mouse
     self.joy_x = None
     self.joy_y = None
     props = WindowProperties()
     props.setMouseMode(WindowProperties.MRelative)  # keep mouse in screen
     self.disableMouse()
     self.win.requestProperties(props)
     self.setBackgroundColor(0, 0, 0)
     # Make missiles glow
     self.filters = CommonFilters(self.win, self.cam)
     self.filters.setBloom(blend=(0, 0, 0, 1), desat=-0.5, intensity=3.0, size="large")
     self.screen_width = self.win.getXSize()
     self.screen_height = self.win.getYSize()
     self.center_x = self.screen_width/2
     self.center_y = self.screen_height/2
     # self.win.movePointer(0, self.center_x, self.center_y)
     self.enableParticles()
     self.cTrav = CollisionTraverser()
     # self.cTrav.setRespectPrevTransform(True)
     self.pusher = PhysicsCollisionHandler()
     self.pusher.addInPattern('%fn-into-%in')
     self.target = None
     self.maxvel = 50
     self.roll_time = 0
     self.fuel = 1000
     self.ship()
     self.sounds()
     self.hud()
     self.part = Spacedust(self)
     self.events()
     self.camLens.setFov(70)
     self.camLens.setNear(1)
     self.camLens.setFar(500)
     self.get_key = {
         "ACCEL": False,
         "DECEL": False,
         "FORWARD_THRUST": False,
         "REVERSE_THRUST": False,
         "ROLL_LEFT": False,
         "ROLL_RIGHT": False,
         "ROLL_LEFT_BEG": False,
         "ROLL_RIGHT_BEG": False,
         "FIRE": False,
         "FIRING": False,
         "LOCK": False,
         "LOCKING": False,
     }
     self.AIworld = AIWorld(self.render)
     self.taskMgr.add(self.update, "task-update")
     self.taskMgr.doMethodLater(1, self.fuel_usage, "task-fuel-usage")
     self.taskMgr.add(self.AI_update, "AI-update")
     self.gen_enemy()
 def setupPhysics(self, name):
     an = ActorNode('%s-%s' % (name, self.doId))
     anp = NodePath(an)
     if not self.isEmpty():
         self.reparentTo(anp)
     NodePath.assign(self, anp)
     self.physicsObject = an.getPhysicsObject()
     self.setTag('object', str(self.doId))
     self.collisionNodePath.reparentTo(self)
     self.handler = PhysicsCollisionHandler()
     self.handler.addCollider(self.collisionNodePath, self)
     self.collideName = self.uniqueName('collide')
     self.handler.addInPattern(self.collideName + '-%in')
     self.handler.addAgainPattern(self.collideName + '-%in')
     self.watchDriftName = self.uniqueName('watchDrift')
예제 #5
0
 def make_traverser_handler(self):
     base.cTrav = CollisionTraverser()
     #base.mchandler = CollisionHandlerEvent()
     #base.mchandler = CollisionHandlerPusher()
     base.mchandler = PhysicsCollisionHandler()
     base.mchandler.addInPattern('into-%in')
     base.mchandler.addAgainPattern('%fn-again-%in')
     base.mchandler.addOutPattern('out-%in')
     base.mchandler.setStaticFrictionCoef(0.91)
     base.mchandler.setDynamicFrictionCoef(0.91)
예제 #6
0
    def create_ball_coll(self, ball_actor):
        # Build a collisionNode for this smiley which is a sphere of the same diameter as the model
        ball_coll_node = ball_actor.attachNewNode(CollisionNode('ball_cnode'))
        ball_coll_sphere = CollisionSphere(0, 0, 0, 1)
        ball_coll_node.node().addSolid(ball_coll_sphere)
        # Watch for collisions with our brothers, so we'll push out of each other
        ball_coll_node.node().setIntoCollideMask(BitMask32().bit(
            self.ball_bit))
        # we're only interested in colliding with the ground and other smileys
        cMask = BitMask32()
        cMask.setBit(self.ground_bit)
        cMask.setBit(self.ball_bit)
        ball_coll_node.node().setFromCollideMask(cMask)

        # Now, to keep the spheres out of the ground plane and each other, let's attach a physics handler to them
        ball_handler = PhysicsCollisionHandler()

        # Set the physics handler to manipulate the smiley actor's transform.
        ball_handler.addCollider(ball_coll_node, ball_actor)

        # This call adds the physics handler to the traverser list
        # (not related to last call to addCollider!)
        self.base.cTrav.addCollider(ball_coll_node, ball_handler)

        # Now, let's set the collision handler so that it will also do a CollisionHandlerEvent callback
        # But...wait?  Aren't we using a PhysicsCollisionHandler?
        # The reason why we can get away with this is that all CollisionHandlerXs are inherited from
        # CollisionHandlerEvent,
        # so all the pattern-matching event handling works, too
        ball_handler.addInPattern('%fn-into-%in')

        return ball_coll_node
예제 #7
0
    def addActor(self, name, position=(0,0,0), orientation=(0,0,0), 
                 scale=(1,1,1), collisionSphere=None):
        # Create the scene node path.
        actor_np = NodePath(ActorNode(name))
        actor_np.setPosHpr(position, orientation)
        actor_np.reparentTo(self.render)

        # Attach model to the node path.
        base_path  = os.path.dirname(__file__)
        model_path = os.path.join(base_path, 'models', name)
        model_path = Filename.fromOsSpecific(model_path)
        model_np   = self.loader.loadModel(model_path)
        model_np.setScale(scale)
        model_np.reparentTo(actor_np)

        #=======================================================================
        # Make actor physics collidible.
        #=======================================================================
        # Attach collision solid to the node path. 
        cn = CollisionNode(name+'PhysicsCollisionNode')
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.setFromCollideMask(BitMask32.bit(0))
        cs = CollisionSphere(collisionSphere[0:3], collisionSphere[3])
        cn.addSolid(cs)
        actor_cnp = actor_np.attachNewNode(cn)
        
        # Add actor to the physics collision detection system.
        handler = PhysicsCollisionHandler()
        handler.addCollider(actor_cnp, actor_np)
        # self.cTrav.addCollider(actor_cnp, handler)

        #=======================================================================
        # Make actor AI compatible.
        #=======================================================================
        ai_character = AICharacter(name, actor_np, mass=50, movt_force=10, 
                                   max_force=30)
        self.AICharacter[name] = ai_character
        self.AIWorld.addAiChar(ai_character)
        
        #=======================================================================
        # Make actor events collidible.
        #=======================================================================
        # Attach collision solid to the node path. 
        cn = CollisionNode(name+'EventCollisionNode')
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.setFromCollideMask(BitMask32.bit(1))
        cs = CollisionSphere(collisionSphere[0:3], collisionSphere[3])
        cn.addSolid(cs)
        actor_cnp = actor_np.attachNewNode(cn)
        actor_cnp.show()
        
        # Add actor to the collision event detection system.
        handler = CollisionHandlerEvent()
        handler.addInPattern('%fn-enters')
        handler.addOutPattern('%fn-exits')
        self.cTrav.addCollider(actor_cnp, handler)
        self.accept(name+'EventCollisionNode'+'-enters', self.onActorEnterEventFunc)
        self.accept(name+'EventCollisionNode'+'-exits', self.onActorExitEventFunc)

        self.actorNP[name] = actor_np
        
        # The most recently added actor becomes actor of interest.
        self.setActorOfInterest(name)

        self.taskMgr.add(self.actorOIStateUpdateTask,'actorStateUpdate',sort=50)
예제 #8
0
    def setupCollision(self):
        base.cTrav = CollisionTraverser()
        self.collisionHandlerEvent = CollisionHandlerEvent()
        self.physicsCollisionPusher = PhysicsCollisionHandler()

        self.collisionHandlerEvent.addInPattern('into-%in')
        self.collisionHandlerEvent.addOutPattern('outof-%in')

        # create masks
        defaultCollisionMask = BitMask32(0b0001)  #0x1
        segmentCollisionMask = BitMask32(0b1000)  #0x8
        stairsCollisionMask = BitMask32(0b0010)  #0x2
        marioBodyCollisionMask = BitMask32(0b0011)  #0x3
        collisionWallsForBarrels = BitMask32(0b0100)  #0x4

        # mario segment collider
        ray = CollisionSegment(7, 0, -4.5, 7, 0, -5.1)
        cnodePath = self.mario.attachNewNode(CollisionNode('marioRay'))
        cnodePath.node().addSolid(ray)
        cnodePath.node().setFromCollideMask(segmentCollisionMask)
        cnodePath.node().setIntoCollideMask(0)
        cnodePath.show()
        base.cTrav.addCollider(cnodePath, self.collisionHandlerEvent)

        self.setupBoxCollider(self.mario, 7, 0, -4.5, 0.5, 5, 0.5,
                              'marioHitBox', self.collisionHandlerEvent,
                              marioBodyCollisionMask, marioBodyCollisionMask)

        stairs1 = self.scene.find("bottomstair")
        self.setupBoxCollider(stairs1, -6.8, 0, -3.0, 0.5, 5, 2.5,
                              'stairs1HitBox', self.collisionHandlerEvent,
                              stairsCollisionMask, stairsCollisionMask)

        stairs2 = self.scene.find("middlestair")
        self.setupBoxCollider(stairs2, -0.86, 0, .1, 0.5, 5, 2.1,
                              'stairs2HitBox', self.collisionHandlerEvent,
                              stairsCollisionMask, stairsCollisionMask)

        stairs3 = self.scene.find("topstair")
        self.setupBoxCollider(stairs3, -6.8, 0, 3.1, 0.5, 5, 2.2,
                              'stairs3HitBox', self.collisionHandlerEvent,
                              stairsCollisionMask, stairsCollisionMask)

        hammer = self.scene.find("MainGroup")  # hammer
        self.setupBoxCollider(hammer, 5.5, 0, -1.5, 0.5, 5, 0.5,
                              'hammer1HitBox', self.collisionHandlerEvent,
                              stairsCollisionMask, stairsCollisionMask)

        dk = self.scene.find("hammer1")
        self.setupBoxCollider(dk, 8.7, 0, 5, 1, 5, 1, 'dkHitBox',
                              self.collisionHandlerEvent, stairsCollisionMask,
                              stairsCollisionMask)

        floor0 = self.scene.find("floor0")
        self.setupBoxCollider(floor0,
                              -2.5,
                              0,
                              -5.5,
                              10,
                              5,
                              0.5,
                              'floor0HitBox',
                              self.collisionHandlerEvent,
                              intoCollisionMask=segmentCollisionMask)

        floor1 = self.scene.find("floor1")
        self.setupBoxCollider(floor1,
                              2,
                              0,
                              -2.5,
                              8.4,
                              5,
                              0.5,
                              'floor1HitBox',
                              self.collisionHandlerEvent,
                              intoCollisionMask=segmentCollisionMask)
        floor2_1 = self.scene.find("floor2")
        self.setupBoxCollider(floor2_1,
                              3.6,
                              0,
                              0.5,
                              3.8,
                              5,
                              0.5,
                              'floor21HitBox',
                              self.collisionHandlerEvent,
                              intoCollisionMask=segmentCollisionMask)
        floor2_2 = self.scene.find("pCube4")
        self.setupBoxCollider(floor2_2,
                              -6.3,
                              0,
                              0.5,
                              5.0,
                              5,
                              0.5,
                              'floor22HitBox',
                              self.collisionHandlerEvent,
                              intoCollisionMask=segmentCollisionMask)
        floor3 = self.scene.find("floors")
        self.setupBoxCollider(floor3,
                              1.8,
                              0,
                              3.5,
                              8,
                              5,
                              0.5,
                              'floor3HitBox',
                              self.collisionHandlerEvent,
                              intoCollisionMask=segmentCollisionMask)

        rightWall = self.scene.find("rightWall")
        self.setupBoxCollider(rightWall,
                              -12,
                              0,
                              0,
                              1,
                              5,
                              10,
                              'rightWallHitBox',
                              self.collisionHandlerEvent,
                              fromCollisionMask=collisionWallsForBarrels,
                              intoCollisionMask=collisionWallsForBarrels)

        leftWall = self.scene.find("walls")
        self.setupBoxCollider(leftWall,
                              11.5,
                              0,
                              0,
                              1,
                              5,
                              10,
                              'leftWallHitBox',
                              self.collisionHandlerEvent,
                              fromCollisionMask=collisionWallsForBarrels,
                              intoCollisionMask=collisionWallsForBarrels)

        barrelFixer = self.scene.attachNewNode("barrelFixer")
        self.setupBoxCollider(barrelFixer,
                              -3,
                              0,
                              0.505,
                              10,
                              5,
                              0.5,
                              'barrelFixerHitBox',
                              self.collisionHandlerEvent,
                              fromCollisionMask=collisionWallsForBarrels,
                              intoCollisionMask=collisionWallsForBarrels)

        barrelDestroyer = self.scene.attachNewNode("barrelDestroyer")
        self.setupBoxCollider(barrelDestroyer,
                              0,
                              0,
                              -8,
                              15,
                              5,
                              0.5,
                              'barrelDestroyerHitBox',
                              self.collisionHandlerEvent,
                              fromCollisionMask=collisionWallsForBarrels,
                              intoCollisionMask=collisionWallsForBarrels)

        self.accept('into-stairs1HitBox', self.enableStair)
        self.accept('outof-stairs1HitBox', self.disableStair)
        self.accept('into-stairs2HitBox', self.enableStair)
        self.accept('outof-stairs2HitBox', self.disableStair)
        self.accept('into-stairs3HitBox', self.enableStair)
        self.accept('outof-stairs3HitBox', self.disableStair)
        self.accept('into-hammer1HitBox', self.enableHammer)
        self.accept('into-dkHitBox', self.dkArrived)

        self.accept('into-floor0HitBox', self.enableJump)
        self.accept('outof-floor0HitBox', self.disableJump)
        self.accept('into-floor1HitBox', self.enableJump)
        self.accept('outof-floor1HitBox', self.disableJump)
        self.accept('into-floor21HitBox', self.enableJump)
        self.accept('outof-floor21HitBox', self.disableJump)
        self.accept('into-floor22HitBox', self.enableJump)
        self.accept('outof-floor22HitBox', self.disableJump)
        self.accept('into-floor3HitBox', self.enableJump)
        self.accept('outof-floor3HitBox', self.disableJump)

        self.accept("into-barrelCollider", self.barrelCrash)

        base.cTrav.showCollisions(self.render)
예제 #9
0
class Engine(ShowBase):

    def __init__(self, mouse):
        ShowBase.__init__(self)
        self.mouse = mouse
        self.joy_x = None
        self.joy_y = None
        props = WindowProperties()
        props.setMouseMode(WindowProperties.MRelative)  # keep mouse in screen
        self.disableMouse()
        self.win.requestProperties(props)
        self.setBackgroundColor(0, 0, 0)
        # Make missiles glow
        self.filters = CommonFilters(self.win, self.cam)
        self.filters.setBloom(blend=(0, 0, 0, 1), desat=-0.5, intensity=3.0, size="large")
        self.screen_width = self.win.getXSize()
        self.screen_height = self.win.getYSize()
        self.center_x = self.screen_width/2
        self.center_y = self.screen_height/2
        # self.win.movePointer(0, self.center_x, self.center_y)
        self.enableParticles()
        self.cTrav = CollisionTraverser()
        # self.cTrav.setRespectPrevTransform(True)
        self.pusher = PhysicsCollisionHandler()
        self.pusher.addInPattern('%fn-into-%in')
        self.target = None
        self.maxvel = 50
        self.roll_time = 0
        self.fuel = 1000
        self.ship()
        self.sounds()
        self.hud()
        self.part = Spacedust(self)
        self.events()
        self.camLens.setFov(70)
        self.camLens.setNear(1)
        self.camLens.setFar(500)
        self.get_key = {
            "ACCEL": False,
            "DECEL": False,
            "FORWARD_THRUST": False,
            "REVERSE_THRUST": False,
            "ROLL_LEFT": False,
            "ROLL_RIGHT": False,
            "ROLL_LEFT_BEG": False,
            "ROLL_RIGHT_BEG": False,
            "FIRE": False,
            "FIRING": False,
            "LOCK": False,
            "LOCKING": False,
        }
        self.AIworld = AIWorld(self.render)
        self.taskMgr.add(self.update, "task-update")
        self.taskMgr.doMethodLater(1, self.fuel_usage, "task-fuel-usage")
        self.taskMgr.add(self.AI_update, "AI-update")
        self.gen_enemy()

    def gen_enemy(self):
        x = randint(-1000, 1000)
        y = randint(-1000, 1000)
        z = randint(-1000, 1000)
        Enemy(self, 0, x, y, z)

    def AI_update(self, task):
        self.AIworld.update()
        return task.cont

    def hud(self):
        self.font = self.loader.loadFont("./fnt/subatomic.tsoonami.ttf")
        self.aim = OnscreenImage(image="./png/ring.png", pos=Vec3(0), scale=0.02)
        self.aim.setTransparency(TransparencyAttrib.MAlpha)
        self.locker = OnscreenImage(image="./png/ring.png", pos=Vec3(0), scale=0.12)
        self.locker.setTransparency(TransparencyAttrib.MAlpha)
        self.locker.hide()

        self.txtFuel = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.8), text='FUEL', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True)
        self.txtSpeed = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.7), text='SPEED', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True)
        self.txtDist = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.6), text='DIST', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True)
        self.txtCoord = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.5), text='COORD', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True)
        self.taskMgr.doMethodLater(1, self.instruments, "task-instruments")

    def instruments(self, task):
        self.txtSpeed.setText("SPEED: %s" % str(int(self.mvel)))
        self.txtFuel.setText("FUEL: %s" % str(self.fuel))
        if self.target is not None:
            self.txtDist.setText("DISTANCE: %s" % str(round(self.dist, 1)))
        else:
            self.txtDist.setText("DISTANCE: ---")
        self.txtCoord.setText("COORD: %s %s %s" % (str(round(self.fighter.getX(), 1)), str(round(self.fighter.getY(), 1)), str(round(self.fighter.getZ(), 1))))
        return task.again

    def set_key(self, key, value):
        self.get_key[key] = value

    def toggle_key(self, key):
        self.set_key(key, not self.get_key[key])

    def init_roll(self, a, task):
        if task.time <= 2:
            if self.roll_time <= task.time:
                self.roll_time = task.time
            else:
                self.roll_time += task.time
                if self.roll_time > 2:
                    self.roll_time = 2
            self.fighter.setR(self.fighter.getR() + a * self.roll_time)
        else:
            self.fighter.setR(self.fighter.getR() + a * 2)
        return task.cont

    def end_roll(self, a, b, task):
        if task.time < b:
            self.roll_time -= task.time
            if self.roll_time < 0:
                self.roll_time = 0
            self.fighter.setR(self.fighter.getR() + a * (b - task.time))
            return task.cont
        else:
            return task.done

    def roll(self, a):
        if a > 0:
            self.set_key("ROLL_RIGHT_BEG", True)
        else:
            self.set_key("ROLL_LEFT_BEG", True)
        self.taskMgr.add(self.init_roll, "task-init-roll", extraArgs=[a], appendTask=True)

    def unroll(self, a):
        if a > 0:
            self.set_key("ROLL_RIGHT_BEG", False)
        else:
            self.set_key("ROLL_LEFT_BEG", False)
        self.taskMgr.remove("task-init-roll")
        self.taskMgr.add(self.end_roll, "task-end-roll", extraArgs=[a, self.roll_time], appendTask=True)

    def to_roll(self):
        if self.get_key["ROLL_LEFT"]:
            if not self.get_key["ROLL_LEFT_BEG"]:
                if self.fuel > 5:
                    self.roll(-1)
                    self.snd_roller.play()
        else:
            if self.get_key["ROLL_LEFT_BEG"]:
                self.unroll(-1)
                self.snd_roller.stop()
        if self.get_key["ROLL_RIGHT"]:
            if not self.get_key["ROLL_RIGHT_BEG"]:
                if self.fuel > 5:
                    self.roll(+1)
                    self.snd_roller.play()
        else:
            if self.get_key["ROLL_RIGHT_BEG"]:
                self.unroll(+1)
                self.snd_roller.stop()

    def fuel_usage(self, task):
        if self.get_key["FORWARD_THRUST"] or self.get_key["REVERSE_THRUST"]:
            self.fuel -= 9
        if self.get_key["ROLL_LEFT_BEG"] or self.get_key["ROLL_RIGHT_BEG"]:
            self.fuel -= 4
        self.fuel -= 1
        if self.fuel < 0:
            self.fuel = 0
        return task.again

    def chk_speed(self, mvel):
        if mvel < 0.01:
            # stop fighter dead
            if self.prt.getActive():
                self.set_key("DECEL", False)
            mvel = 0
        if mvel > self.maxvel:
            # stop fighter accelerating
            if self.pft.getActive():
                self.set_key("ACCEL", False)
            mvel = self.maxvel
        self.part.p.renderer.setLineScaleFactor(mvel*2)
        self.part.pn.setPos(self.fighter, 0, 10, 0)
        return mvel

    def thrust_shake(self, task):
        x = uniform(-1000, 1000)
        y = uniform(-1000, 1000)
        self.repos(x, y, 0.001)
        return task.cont

    def thrust_end(self, task):
        if task.time < 5:
            f = (5. - task.time) / 5.
            s = 1000.*f
            x = uniform(-s, s)
            y = uniform(-s, s)
            self.repos(x, y, 0.001)
            self.snd_thrust.setVolume(f)
            return task.cont
        self.snd_thrust.stop()
        return task.done

    def thrust(self, a):
        if a > 0:
            self.set_key("FORWARD_THRUST", True)
        else:
            self.set_key("REVERSE_THRUST", True)
        self.taskMgr.remove("task-thrust-end")
        self.snd_thrust.setVolume(1)
        self.snd_thrust.play()
        self.taskMgr.add(self.thrust_shake, "task-thrust-shake")

    def unthrust(self, a):
        if a > 0:
            self.set_key("FORWARD_THRUST", False)
        else:
            self.set_key("REVERSE_THRUST", False)
        self.taskMgr.remove("task-thrust-shake")
        self.taskMgr.add(self.thrust_end, "task-thrust-end")

    def to_thrust(self):
        if self.get_key["ACCEL"]:
            if self.mvel < self.maxvel - 1:
                if not self.get_key["FORWARD_THRUST"]:
                    if self.fuel > 10:
                        self.pft.setActive(True)
                        self.thrust(+1)
        else:
            if self.get_key["FORWARD_THRUST"]:
                self.pft.setActive(False)
                self.unthrust(+1)
        if self.get_key["DECEL"]:
            if self.mvel > 0:
                if not self.get_key["REVERSE_THRUST"]:
                    if self.fuel > 10:
                        self.prt.setActive(True)
                        self.thrust(-1)
        else:
            if self.get_key["REVERSE_THRUST"]:
                self.prt.setActive(False)
                self.unthrust(-1)

    def events(self):
        self.accept("escape", self.quit)
        self.accept('mouse1', self.set_key, ["FIRE", True])
        self.accept('mouse1-up', self.set_key, ["FIRE", False])
        self.accept('mouse3', self.set_key, ["LOCK", True])
        self.accept('mouse3-up', self.set_key, ["LOCK", False])
        self.accept("w", self.set_key, ["ACCEL", True])
        self.accept("w-up", self.set_key, ["ACCEL", False])
        self.accept("s", self.set_key, ["DECEL", True])
        self.accept("s-up", self.set_key, ["DECEL", False])
        self.accept("a", self.set_key, ["ROLL_LEFT", True])
        self.accept("a-up", self.set_key, ["ROLL_LEFT", False])
        self.accept("d", self.set_key, ["ROLL_RIGHT", True])
        self.accept("d-up", self.set_key, ["ROLL_RIGHT", False])

    def update(self, task):
        self.pos()
        self.speed()
        if self.fuel > 0:
            self.to_roll()
            self.to_thrust()
            self.to_fire()
            self.to_lock()
        self.rehud()
        return task.cont

    def rehud(self):
        if self.target is not None:
            c = self.target.np.getPos(self.fighter)
            self.dist = c.length()
            c.normalize()
            self.d2 = c - Vec3(0, 1, 0)*c.dot(Vec3(0, 1, 0))
            self.target.radar.setPos(self.d2.getX(), 1, self.d2.getZ())

    def sounds(self):
        self.audio3d = Audio3DManager.Audio3DManager(self.sfxManagerList[0], self.camera)
        self.audio3d.setListenerVelocityAuto()
        self.snd_space = self.loader.loadSfx("./snd/space.flac")
        self.snd_space.setLoop(True)
        self.snd_thrust = self.loader.loadSfx("./snd/thrust.flac")
        self.snd_thrust.setLoop(True)
        self.snd_roller = self.loader.loadSfx("./snd/roller.flac")
        self.snd_roller.setLoop(True)
        self.snd_launch = self.loader.loadSfx("./snd/launch.flac")
        self.snd_lock = self.loader.loadSfx("./snd/lock.flac")
        self.snd_space.play()

    def quit(self):
        self.taskMgr.running = False

    def repos(self, x, y, d):
        player_q = self.fighter.getQuat()
        up = player_q.getUp()
        right = player_q.getRight()
        up.normalize()
        right.normalize()
        up_q = copy(player_q)
        right_q = copy(player_q)
        up_q.setFromAxisAngle(-(x * d), up)
        right_q.setFromAxisAngle(y * d, right)
        self.fighter.setQuat(player_q.multiply(up_q.multiply(right_q)))

    def move_end(self, x, y, task):
        if task.time <= 1:
            d = 0.002*(1 - task.time)
            self.repos(x, y, d)
            return task.cont
        return task.done

    def pos(self):
        if self.mouse:
            md = self.win.getPointer(0)
            x = md.getX()
            y = md.getY()
        else:
            x = self.joy_x
            y = self.joy_y
        if self.win.movePointer(0, self.center_x, self.center_y):
            x -= self.center_x
            y -= self.center_y
            if x != 0 or y != 0:
                self.taskMgr.add(self.move_end, 'task-move-end', extraArgs=[x, y], appendTask=True)

    def speed(self):
        fwd = self.fighter.getQuat().getForward()
        fwd.normalize()
        self.mvel = self.anpo.getVelocity().length()
        # speed control
        self.mvel = self.chk_speed(self.mvel)
        self.anpo.setVelocity(fwd * self.mvel)

    def ship(self):
        an = ActorNode()
        an.getPhysicsObject().setMass(100)
        self.fighter = self.render.attachNewNode(an)
        self.physicsMgr.attachPhysicalNode(an)
        self.anpo = an.getPhysicsObject()
        fn = ForceNode("force-node-fighter")
        self.fighter.attachNewNode(fn)
        self.pft = LinearVectorForce(Vec3(0, +1, 0) * 500)  # forward thrust
        self.prt = LinearVectorForce(Vec3(0, -1, 0) * 500)  # reverse thrust
        self.pft.setMassDependent(1)
        self.prt.setMassDependent(1)
        self.pft.setActive(False)
        self.prt.setActive(False)
        fn.addForce(self.pft)
        fn.addForce(self.prt)
        an.getPhysical(0).addLinearForce(self.pft)
        an.getPhysical(0).addLinearForce(self.prt)
        self.camera.reparentTo(self.fighter)
        from_obj = self.fighter.attachNewNode(CollisionNode('fighter'))
        from_obj.node().setFromCollideMask(BitMask32(0x1))
        from_obj.setCollideMask(BitMask32(0x1))
        from_obj.node().addSolid(CollisionSphere(0, 0, 0, 1))
        # from_obj.show()
        self.pusher.addCollider(from_obj, self.fighter)
        self.cTrav.addCollider(from_obj, self.pusher)

    def launch_bullet(self):
        speed = 500.
        scale = Vec3(0.05)
        color = Vec4(0, 1, 0, 1)
        mask = BitMask32(0x2)
        lookat = Vec3(0, 100, 0)
        Missile(self, "bullet", speed, scale, color, mask, self.fighter, Vec3(-0.5, 0, 0), self.fighter, lookat, 0.5)
        Missile(self, "bullet", speed, scale, color, mask, self.fighter, Vec3(+0.5, 0, 0), self.fighter, lookat, 0.5)
        self.snd_launch.play()

    def to_fire(self):
        if self.get_key["FIRE"]:
            if not self.get_key["FIRING"]:
                self.set_key("FIRING", True)
                self.taskMgr.doMethodLater(0.16, self.fire_bullet, "task-fire-bullet")
        else:
            if self.get_key["FIRING"]:
                self.set_key("FIRING", False)
                self.taskMgr.remove("task-fire-bullet")

    def fire_bullet(self, task):
        if self.fuel >= 5:
            self.fuel -= 5
            self.launch_bullet()
        return task.again

    def launch_missile(self):
        speed = 100
        scale = Vec3(0.2)
        color = Vec4(1, 0, 0, 1)
        mask = BitMask32(0x2)
        lookat = Vec3(0, 0, 0)
        self.missile = Missile(self, "missile", speed, scale, color, mask, self.fighter, Vec3(0, 0, -2), self.target.np, lookat, 3)
        self.snd_launch.play()
        self.taskMgr.add(self.guide_missile, "task-guide-missile")

    def guide_missile(self, task):
        try:
            quat = Quat()
            lookAt(quat, self.target.np.getPos() - self.missile.anp.getPos(), Vec3.up())
            self.missile.anp.setQuat(quat)
            fwd = quat.getForward()
            fwd.normalize()
            mvel = self.missile.anpo.getVelocity().length()
            self.missile.anpo.setVelocity(fwd*mvel)
        except:
            return task.done
        return task.cont

    def can_lock(self):
        if self.dist >= 30 and self.dist <= 300 and abs(self.d2.getX()) <= 0.1 and abs(self.d2.getZ()) <= 0.1:
            return True
        else:
            return False

    def remove_lock(self):
        if self.get_key["LOCKING"]:
            self.set_key("LOCKING", False)
            self.locker.hide()
            self.snd_lock.stop()
            self.taskMgr.remove("task-fire-missile")

    def to_lock(self):
        if self.get_key["LOCK"]:
            if self.can_lock():
                if self.fuel >= 100:
                    if not self.get_key["LOCKING"]:
                        self.set_key("LOCKING", True)
                        self.locker.setScale(0.12)
                        self.locker.setColor(1, 0, 0, 0.5)
                        self.locker.show()
                        self.snd_lock.play()
                        self.taskMgr.add(self.fire_missile, "task-fire-missile")
                else:
                    self.remove_lock()
            else:
                self.remove_lock()
        else:
            self.remove_lock()

    def fire_missile(self, task):
        if self.fuel >= 100:
            if task.time < 3.6:
                e = (3.6 - task.time)/3.6
                f = 0.02 + e*0.1
                self.locker.setScale(f)
                self.locker.setColor(e, 1-e, 0, 0.5)
                return task.cont
            else:
                self.fuel -= 100
                self.launch_missile()
                return task.done
예제 #10
0
class CollisionManager(Manager, DirectObject):
    """Handles the collision between objects on the scene."""
    
    def __init__(self, debug=False):
        self._debug = debug
        
        self.handler = PhysicsCollisionHandler()
        self.handler.setStaticFrictionCoef(0.1)
        self.handler.setDynamicFrictionCoef(0.05)
        self.handler.addInPattern('into-%in')
        self.handler.addAgainPattern('again-%in')
        self.handler.addOutPattern('out-%in')
        self.handler.addInPattern('%fn-into-%in')
    
    @debug(['managers'])
    def setup(self):
        self._old_cTrav = base.cTrav
        base.cTrav = CollisionTraverser()
        base.cTrav.setRespectPrevTransform(True)
        if self._debug:
            base.cTrav.showCollisions(base.gameState.currentState.objectsNode)
        
        self.addCollider(base.gameState.currentState.objects['equismo'])
    
    @debug(['managers'])
    def clear(self):
        base.cTrav.clearColliders()
        base.cTrav = self._old_cTrav
        self.ignoreAll()
    
    def addCollider(self, physicalNode):
        """Add a node to the collision system.
        
        The parameter 'physicalNode' must be an instance of PhysicalNode.
        """
        self.handler.addCollider(physicalNode.collider, physicalNode.actor)
        base.cTrav.addCollider(physicalNode.collider, self.handler)
        
        if self._debug:
            physicalNode.collider.show()
    
    def addCollisionHandling(self, intoNode, type, *handlers):
        """Notify that a collision event should be handled.
        
        The given 'type' should be "into", "again" or "out".
        The given handlers must inherit from the CollisionEventHandler 
        class. Its 'handleCollisionEvent' method will be called whenever
        a collision with the node given by 'intoNode' occurs.
        """
        pattern = "%s-%s" % (type, intoNode.getName())
        self.accept(pattern, self._callHandlers, [handlers, type])
        
    def addMutualCollisionHandling(self, fromNode, intoNode):
        """Notify that a 'into' collision event between two specific 
        nodes should be handled by them.

        The given nodes must inherit from the CollisionEventHandler 
        class. Its 'handleCollisionEvent' method will be called whenever
        a collision with the node given by 'intoNode' occurs.
        """
        pattern = "%s-into-%s" % (fromNode.collider.getName(), 
                                  intoNode.collider.getName())
        
        handlers = [fromNode, intoNode]
        self.accept(pattern, self._callHandlers, [handlers, "into"])
        
    def _callHandlers(self, handlers, type, entry):
        for handler in handlers:
            handler.handleCollisionEvent(entry, type)
예제 #11
0
 def __init__(self):
     #Game variables
     self.health = 100
     self.panda_kill_count = 0
     self.level = 0
     
     #Implementation variables
     #self.color = [Vec4((204.0/255), (255.0/255), (204/255), 0.1),Vec4((0/255), (255.0/255), (255.0/255), 0.1),Vec4((255.0/255), (51.0/255), (255.0/255), 0.1),Vec4((153.0/255), (255.0/255), (153.0/255), 0.1),Vec4((255.0/255), (178.0/255), (102.0/255), 0.1),Vec4((229.0/255), (204.0/255), (255.0/255), 0.1)]
     self.color = [Vec4(0.4,0.4,0.4,0.1)]
     self.mirror=False
     self.paused=False
     self.displayed=False
     self.game_started=False
     self.randomthings_ = randomthings.RandomThings(self)
     self.shifted_cam=False
     self.is_firstP=False
     self.old_anim2 = None
     self.old_anim=None
     self.timeout=False
     (self.r,self.f,self.b,self.l)=(0,0,0,0)
     self.inside_level=False
     self.move_anim_queue=[]
     self.anim_queue=[]
     self.prev_time=0.0
     self.bullets = []
     self.rightspeed=0
     self.forwardspeed=0
     ShowBase.__init__(self)
     self.makeDefaultPipe()
     bb=self.pipe.getDisplayHeight()
     aa=self.pipe.getDisplayWidth()
     
     self.openDefaultWindow(size=(aa, bb))
     import layer2d
     self.layer2d = layer2d
     self.layer2d.update_info('Loading...')
     self.keyreader= ReadKeys(self,layer2d)
     
     #Sounds
     self.gunshot = self.loader.loadSfx("sounds/gunshot_se.ogg")
     self.gunshot.setLoop(False)
     
     self.music = self.loader.loadSfx("sounds/music.ogg")
     self.music.setLoop(True)
     
     
     self.zombie_die = self.loader.loadSfx('sounds/zombie_die.ogg')
     self.zombie_die.setLoop(False)
     
     self.kicked = self.loader.loadSfx('sounds/kicked.ogg')
     self.kicked.setLoop(False)
     
     self.hurt_sound = self.loader.loadSfx('sounds/hurt.ogg')
     self.hurt_sound.setLoop(False)
     
     self.dead_sound = self.loader.loadSfx('sounds/dead.ogg')
     self.dead_sound.setLoop(False)
     
     self.intro_sound = self.loader.loadSfx('sounds/intro.ogg')
     self.intro_sound.setLoop(False)
     self.intro_sound.play()
     
     
     self.enableParticles()
     self.center_mouse()
     #self.disableMouse()
     self.prev_pos = None
     if base.mouseWatcherNode.hasMouse():
         x=base.mouseWatcherNode.getMouseX()
         y=base.mouseWatcherNode.getMouseY()
         self.prev_pos = (x,y)
     #Hide cursor
     props = WindowProperties()
     props.setCursorHidden(True) 
     self.win.requestProperties(props)
     
     
     self.environ = self.loader.loadModel('models/ourworld')
     self.environ.setPos(0,0,0)
     self.environ.reparentTo(self.render)
     
     
     self.pandaActor = Actor("models/hero_anim", {'kick':'models/hero_anim-kick','unready_to_shoot':'models/hero_anim-unready_to_shoot','jump':'models/hero_anim-jump',"shooting":"models/hero_anim-shooting","ready_to_shoot":"models/hero_anim-ready_to_shoot","ready_to_walk":"models/hero_anim-ready_to_run","ready_to_run":"models/hero_anim-ready_to_run","walk4":"models/hero_anim-walk1", "breathe": "models/hero_anim-breathe", "run": "models/hero_anim-walk"})
     self.pandaActor.setPlayRate(3,'ready_to_shoot')
     self.pandaActor.setPlayRate(-1.0,"ready_to_walk")
     self.pandaActor.setPlayRate(1.5,'run')
     self.pandaActor.setPlayRate(1.5,'ready_to_run')
     self.pandaActor.reparentTo(self.render)
     self.pandaActor.setPos(self.environ,0,0,100)
     self.pandaActor.loop("breathe")
     
     self.phy = NodePath("PhysicsNode")
     self.phy.reparentTo(self.render)
     
     self.pandaAN = ActorNode("PandaActor")
     self.pandaActorPhysicsP = self.phy.attachNewNode(self.pandaAN)
     
     self.physicsMgr.attachPhysicalNode(self.pandaAN)
     self.pandaActor.reparentTo(self.pandaActorPhysicsP)
     
     
     #set mass of panda
     self.pandaAN.getPhysicsObject().setMass(100)
     
     #apply gravity
     self.gravityFN=ForceNode('world-forces')
     self.gravityFNP=self.environ.attachNewNode(self.gravityFN)
     self.gravityForce=LinearVectorForce(0,0,-30.81) #gravity acceleration
     self.gravityFN.addForce(self.gravityForce)
     self.physicsMgr.addLinearForce(self.gravityForce)
     
     
     #camera stuff
     self.camera.reparentTo(self.pandaActor)
     self.camera.lookAt(self.pandaActor)
     self.taskMgr.add(self.spinCameraTask, "zombieTask_SpinCameraTask")
     self.taskMgr.doMethodLater(0.01,self.movePandaTask,"zombieTask_movePandaTask")
     
     
     #Collision Handling
     self.cTrav = CollisionTraverser()
     self.collisionHandler = CollisionHandlerEvent()
     
     #Add collider for terrain
     self.groundCollider = self.environ.find("**/terrain")
     
     #Add walker for panda
     self.collision_sphere = CollisionSphere(0,0,1,1)
     self.collNode = CollisionNode('pandaWalker')
     self.cnodePath = self.pandaActor.attachNewNode(self.collNode)
     self.cnodePath.node().addSolid(self.collision_sphere)
     
     #AddZombieDetector for panda
     self.zombie_sphere = CollisionSphere(0,0,3,1)
     self.zomb_detector_node = CollisionNode('zombieDetector')
     self.zomb_detector_NP = self.pandaActor.attachNewNode(self.zomb_detector_node)
     self.zomb_detector_NP.node().addSolid(self.zombie_sphere)
     #self.zomb_detector_NP.show()
     
     #Add pusher against gravity
     self.pusher = PhysicsCollisionHandler()
     self.pusher.addCollider(self.cnodePath, self.pandaActorPhysicsP)
     self.pusher.addCollider(self.zomb_detector_NP,self.pandaActorPhysicsP)
     self.cTrav.addCollider(self.cnodePath,self.pusher)
     self.cTrav.addCollider(self.zomb_detector_NP,self.pusher)
     
     self.pusher.addInPattern('%fn-into-%in')
     self.pusher.addAgainPattern('%fn-again-%in')
     
     #Add collision handler patterns
     self.collisionHandler.addInPattern('%fn-into-%in')
     self.collisionHandler.addAgainPattern('%fn-again-%in')
     
     self.abientLight = AmbientLight("ambientLight")
     self.abientLight.setColor(Vec4(0.1, 0.1, 0.1, 1))
     self.directionalLight = DirectionalLight("directionalLight")
     self.directionalLight.setDirection(Vec3(-5, -5, -5))
     self.directionalLight.setColor(Vec4((229.0/255), (204.0/255), (255.0/255), 0.7))
     self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1))
     self.directionalLight.setShadowCaster(True,512,512)
     self.render.setLight(self.render.attachNewNode(self.abientLight))
     self.render.setLight(self.render.attachNewNode(self.directionalLight))
     self.render.setShaderAuto()
     
     #create zombie land
     self.zombieland = zombie.Zombies(self)
     self.taskMgr.doMethodLater(0.01,self.zombieland.moveZombie, "zombieTask_ZombieMover")
     layer2d.incBar(self.health)
     self.taskMgr.add(self.game_monitor,"zombieTask_gameMonitor")
     self.taskMgr.doMethodLater(2.7,self.music_play, "zombieTask_music")
     
     #Add random useless things:
     self.randomthings_.add_random_things()
예제 #12
0
class MyApp(ShowBase):
    def center_mouse(self):
        self.win.movePointer(0,self.win.getXSize()/2,self.win.getYSize()/2)
    def __init__(self):
        #Game variables
        self.health = 100
        self.panda_kill_count = 0
        self.level = 0
        
        #Implementation variables
        #self.color = [Vec4((204.0/255), (255.0/255), (204/255), 0.1),Vec4((0/255), (255.0/255), (255.0/255), 0.1),Vec4((255.0/255), (51.0/255), (255.0/255), 0.1),Vec4((153.0/255), (255.0/255), (153.0/255), 0.1),Vec4((255.0/255), (178.0/255), (102.0/255), 0.1),Vec4((229.0/255), (204.0/255), (255.0/255), 0.1)]
        self.color = [Vec4(0.4,0.4,0.4,0.1)]
        self.mirror=False
        self.paused=False
        self.displayed=False
        self.game_started=False
        self.randomthings_ = randomthings.RandomThings(self)
        self.shifted_cam=False
        self.is_firstP=False
        self.old_anim2 = None
        self.old_anim=None
        self.timeout=False
        (self.r,self.f,self.b,self.l)=(0,0,0,0)
        self.inside_level=False
        self.move_anim_queue=[]
        self.anim_queue=[]
        self.prev_time=0.0
        self.bullets = []
        self.rightspeed=0
        self.forwardspeed=0
        ShowBase.__init__(self)
        self.makeDefaultPipe()
        bb=self.pipe.getDisplayHeight()
        aa=self.pipe.getDisplayWidth()
        
        self.openDefaultWindow(size=(aa, bb))
        import layer2d
        self.layer2d = layer2d
        self.layer2d.update_info('Loading...')
        self.keyreader= ReadKeys(self,layer2d)
        
        #Sounds
        self.gunshot = self.loader.loadSfx("sounds/gunshot_se.ogg")
        self.gunshot.setLoop(False)
        
        self.music = self.loader.loadSfx("sounds/music.ogg")
        self.music.setLoop(True)
        
        
        self.zombie_die = self.loader.loadSfx('sounds/zombie_die.ogg')
        self.zombie_die.setLoop(False)
        
        self.kicked = self.loader.loadSfx('sounds/kicked.ogg')
        self.kicked.setLoop(False)
        
        self.hurt_sound = self.loader.loadSfx('sounds/hurt.ogg')
        self.hurt_sound.setLoop(False)
        
        self.dead_sound = self.loader.loadSfx('sounds/dead.ogg')
        self.dead_sound.setLoop(False)
        
        self.intro_sound = self.loader.loadSfx('sounds/intro.ogg')
        self.intro_sound.setLoop(False)
        self.intro_sound.play()
        
        
        self.enableParticles()
        self.center_mouse()
        #self.disableMouse()
        self.prev_pos = None
        if base.mouseWatcherNode.hasMouse():
            x=base.mouseWatcherNode.getMouseX()
            y=base.mouseWatcherNode.getMouseY()
            self.prev_pos = (x,y)
        #Hide cursor
        props = WindowProperties()
        props.setCursorHidden(True) 
        self.win.requestProperties(props)
        
        
        self.environ = self.loader.loadModel('models/ourworld')
        self.environ.setPos(0,0,0)
        self.environ.reparentTo(self.render)
        
        
        self.pandaActor = Actor("models/hero_anim", {'kick':'models/hero_anim-kick','unready_to_shoot':'models/hero_anim-unready_to_shoot','jump':'models/hero_anim-jump',"shooting":"models/hero_anim-shooting","ready_to_shoot":"models/hero_anim-ready_to_shoot","ready_to_walk":"models/hero_anim-ready_to_run","ready_to_run":"models/hero_anim-ready_to_run","walk4":"models/hero_anim-walk1", "breathe": "models/hero_anim-breathe", "run": "models/hero_anim-walk"})
        self.pandaActor.setPlayRate(3,'ready_to_shoot')
        self.pandaActor.setPlayRate(-1.0,"ready_to_walk")
        self.pandaActor.setPlayRate(1.5,'run')
        self.pandaActor.setPlayRate(1.5,'ready_to_run')
        self.pandaActor.reparentTo(self.render)
        self.pandaActor.setPos(self.environ,0,0,100)
        self.pandaActor.loop("breathe")
        
        self.phy = NodePath("PhysicsNode")
        self.phy.reparentTo(self.render)
        
        self.pandaAN = ActorNode("PandaActor")
        self.pandaActorPhysicsP = self.phy.attachNewNode(self.pandaAN)
        
        self.physicsMgr.attachPhysicalNode(self.pandaAN)
        self.pandaActor.reparentTo(self.pandaActorPhysicsP)
        
        
        #set mass of panda
        self.pandaAN.getPhysicsObject().setMass(100)
        
        #apply gravity
        self.gravityFN=ForceNode('world-forces')
        self.gravityFNP=self.environ.attachNewNode(self.gravityFN)
        self.gravityForce=LinearVectorForce(0,0,-30.81) #gravity acceleration
        self.gravityFN.addForce(self.gravityForce)
        self.physicsMgr.addLinearForce(self.gravityForce)
        
        
        #camera stuff
        self.camera.reparentTo(self.pandaActor)
        self.camera.lookAt(self.pandaActor)
        self.taskMgr.add(self.spinCameraTask, "zombieTask_SpinCameraTask")
        self.taskMgr.doMethodLater(0.01,self.movePandaTask,"zombieTask_movePandaTask")
        
        
        #Collision Handling
        self.cTrav = CollisionTraverser()
        self.collisionHandler = CollisionHandlerEvent()
        
        #Add collider for terrain
        self.groundCollider = self.environ.find("**/terrain")
        
        #Add walker for panda
        self.collision_sphere = CollisionSphere(0,0,1,1)
        self.collNode = CollisionNode('pandaWalker')
        self.cnodePath = self.pandaActor.attachNewNode(self.collNode)
        self.cnodePath.node().addSolid(self.collision_sphere)
        
        #AddZombieDetector for panda
        self.zombie_sphere = CollisionSphere(0,0,3,1)
        self.zomb_detector_node = CollisionNode('zombieDetector')
        self.zomb_detector_NP = self.pandaActor.attachNewNode(self.zomb_detector_node)
        self.zomb_detector_NP.node().addSolid(self.zombie_sphere)
        #self.zomb_detector_NP.show()
        
        #Add pusher against gravity
        self.pusher = PhysicsCollisionHandler()
        self.pusher.addCollider(self.cnodePath, self.pandaActorPhysicsP)
        self.pusher.addCollider(self.zomb_detector_NP,self.pandaActorPhysicsP)
        self.cTrav.addCollider(self.cnodePath,self.pusher)
        self.cTrav.addCollider(self.zomb_detector_NP,self.pusher)
        
        self.pusher.addInPattern('%fn-into-%in')
        self.pusher.addAgainPattern('%fn-again-%in')
        
        #Add collision handler patterns
        self.collisionHandler.addInPattern('%fn-into-%in')
        self.collisionHandler.addAgainPattern('%fn-again-%in')
        
        self.abientLight = AmbientLight("ambientLight")
        self.abientLight.setColor(Vec4(0.1, 0.1, 0.1, 1))
        self.directionalLight = DirectionalLight("directionalLight")
        self.directionalLight.setDirection(Vec3(-5, -5, -5))
        self.directionalLight.setColor(Vec4((229.0/255), (204.0/255), (255.0/255), 0.7))
        self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1))
        self.directionalLight.setShadowCaster(True,512,512)
        self.render.setLight(self.render.attachNewNode(self.abientLight))
        self.render.setLight(self.render.attachNewNode(self.directionalLight))
        self.render.setShaderAuto()
        
        #create zombie land
        self.zombieland = zombie.Zombies(self)
        self.taskMgr.doMethodLater(0.01,self.zombieland.moveZombie, "zombieTask_ZombieMover")
        layer2d.incBar(self.health)
        self.taskMgr.add(self.game_monitor,"zombieTask_gameMonitor")
        self.taskMgr.doMethodLater(2.7,self.music_play, "zombieTask_music")
        
        #Add random useless things:
        self.randomthings_.add_random_things()
    def music_play(self,task):
        self.music.play()
        return Task.done
    #def get_color(self):
     #   return self.color[min(len(self.color)-1,self.level)]
    
    #GameMonitor
    def game_monitor(self,task):
        if self.paused:
            return Task.cont
        #Update Score
        self.layer2d.update_score(self.panda_kill_count)
        #Check for health of actor
        if self.health <= 0:
            self.dead_sound.play()
            self.pandaActor.detachNode()
            print "LOL u ded"
            self.info = """Game Over..
    Score: """ + str(self.panda_kill_count) + """
    Press alt+f4 to quit the game.
    
    """
            self.layer2d.update_info(self.info)
            self.taskMgr.removeTasksMatching('zombieTask_*')
        
        if self.game_started<>True:
            if not self.displayed:
                self.display_information()
            self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100)))
            return Task.cont
        
        #Check if user is inside some level. if yes, pass.
        if self.inside_level or self.timeout:
            return Task.cont
        self.inside_level = True
        #self.health=100
        self.timeout=True
        print ".."
        #The next lines will be executed only when the user is in between two levels (or at the beginning of the game)
        #Display information based on game level
        self.display_information()
        print "HUEHUEHUEHUE"    
        #Schedule wave of zombies
        self.taskMgr.doMethodLater(10,self.addWave, "zombieTask_ZombieAdder")
        
        return Task.cont
        
            
    
    def addWave(self,task):
        ##add a wave of 5 zombies, depending on the level.
        ##speed of zombie increases with each level
        ##durability of zombie increases with each level.
        ##Wave ends when all zombies die.
        self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1))
        self.layer2d.update_info("level"+str(self.level))
        self.timeout=False
        self.zombieland.add(5)
        return Task.done
        
    
    #information displayer
    def display_information(self):
        #display information based on levels.
        print self.game_started
        self.displayed=True
        if self.game_started==False:
            info = """
    Welcome to PandaLand. Once upon a time, there used to be these cute

    little creatures called Pandas. They were lazy, funny, and

    adorable. But that is what we humans thought. Pandas are

    actually an evil alien race that spread from planet to planet,

    spreading destruction and terror everywhere. They ruled earth

    several billion years ago. But our super ancestors (Dinosaurs)

    fought agaisnt them with great valour and selflessness; and managed

    to save planet Earth from doom. But the pandas went into hiding

    (and became cute); until few days back! Now they seek to kill all.

    You, the Joker, are our only hope,since Batman has retired.

    Go Kill Pandas.For Mother Earth!
    
    

    """
            self.layer2d.information['bg'] = (0,0,0,0.8)
        else:
            self.layer2d.update_info('')
            if self.level==0:
                info="""
    Your game will start in a few seconds.
    This is the first level. Pandas will spawn
    and follow you. Shoot to kill.

    Test out your controls while
    they are still cute and harmless :)
    
    Jump: Space
    Shoot: LeftClick
    Kick: RightClick
    Walk: A/W/S/D
    
    For more information, press P.

"""
                
                self.layer2d.information['bg'] = (0,0,0,0.6)
            elif self.level==1:
                info="""
    Level 0 Completed!
    Starting Level 1.
    
    Pandas have turned evil
    and stronger. They will try
    to eat you up.

    To run:
    Press Shift + A/S/W/D

"""
            elif self.level==2:
                info="""
    Level 1 Completed!
    Starting Level 2.
    
    Pandas are even stronger now.
    They will get stronger by
    each level.

    Your automatic shooting speed has
    also improved due to experience
    gained.

"""
            elif self.level==3:
                info="""
    Level 2 Completed!
    Starting Level 3.
    
    Pandas also move faster
    by each level. They really
    want to eat you.

    But don't worry, you also 
    run faster as the levels
    proceed.
    
"""
            else:
                info = """
    Level """ + str(self.level-1) + """ Completed!
    Starting """ + str(self.level) + """ .
    
    Well done!
    Keep fighting, our fate lies
    in your hands.
    
"""
        self.layer2d.update_info(info)
    #self.create_bullet()
    def create_bullet(self):
        self.bullet = self.loader.loadModel('models/gun/bullet')
        self.gunshot.play()
        self.bulletAN = ActorNode("BulletNode")
        self.bulletActorPhysicsP = self.phy.attachNewNode(self.bulletAN)
        
        self.physicsMgr.attachPhysicalNode(self.bulletAN)
        self.bullet.reparentTo(self.bulletActorPhysicsP)
        self.bulletAN.getPhysicsObject().setMass(1)
        self.bullet.setPos(self.pandaActor,0,-3,3.5)
        self.bullet.setScale(0.1,0.1,0.1)
        self.bullet.setHpr(self.pandaActor,0,90,0)
        self.bullet.setP(self.camera.getP()+90)
        self.bullet_sphere = CollisionSphere(0,0,0,0.2)
        self.bullet_collNode = CollisionNode('bullet')
        self.bullet_cnodePath = self.bullet.attachNewNode(self.bullet_collNode)
        self.bullet_cnodePath.node().addSolid(self.bullet_sphere)
        
        #self.pusher.addCollider(self.bullet_cnodePath,self.bulletActorPhysicsP)
        self.cTrav.addCollider(self.bullet_cnodePath,self.collisionHandler)
        
        #self.bullet_cnodePath.show()
        self.bullets += [self.bullet]
    def bulletKiller(self,task):
        if self.paused:
            return Task.cont
        self.bullets[0].remove_node()
        self.bullets = self.bullets[1:]
        return Task.done
    
    
    def bulletThrower(self,task):
        if self.paused:
            return Task.cont
        #make bullet move
        if self.pandaActor.getCurrentAnim()<>'shooting' and self.pandaActor.getCurrentAnim()<>'ready_to_shoot':
            self.pandaActor.play('shooting')
        print "loL"
        self.create_bullet()
        
        self.bulletAN.getPhysicsObject().setVelocity(self.render.getRelativeVector(self.camera,Vec3(0,200,0)))
        
        self.taskMgr.doMethodLater(max(0.05,0.1*(5-self.level)),self.bulletThrower, "zombieTask_bulletThrower")
        self.taskMgr.doMethodLater(0.5,self.bulletKiller, "zombieTask_bulletKiller")
        
        self.prev=True
        
        if self.old_anim2==None:
            self.old_anim2='breathe'
        if self.old_anim2 not in ['run','walk4']:
            self.old_anim2='breathe'
        self.anim_queue = [(self.pandaActor,True,'unready_to_shoot'),(self.pandaActor,False,self.old_anim2)]
        return Task.done
        
    def movePandaTask(self,task):
        
        if self.paused:
            return Task.cont
        tempos = self.pandaActor.getPos()
        speed = 0.1
        if self.run_:
            speed+=0.3*self.level
        self.rightspeed = -(self.r-self.l)*speed
        self.forwardspeed = -(self.f-self.b)*speed
        if (self.r-self.l)<>0 and (self.f-self.b)<>0:
            #print self.forwardspeed
            #print self.rightspeed
            #sys.exit(0)
            self.rightspeed *= 0.7
            self.forwardspeed *= 0.7
        self.pandaActor.setPos(self.pandaActor,self.rightspeed, self.forwardspeed,0)
        return Task.again
    def spinCameraTask(self, task):
        if self.paused:
           
            return Task.cont
        if self.render.getRelativePoint(self.pandaActorPhysicsP,self.pandaActor.getPos())[2] < -10:
            self.pandaAN.getPhysicsObject().setVelocity(0,0,30)
            #self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100)))
        self.prev_time=task.time
        
            
            
        #play queued animations:
        for x in self.move_anim_queue+self.anim_queue:
            if x[0].getCurrentAnim()==None:
                if x[1]:
                    x[0].play(x[2])
                else:
                    x[0].loop(x[2])
                if x in self.move_anim_queue:
                    self.move_anim_queue.remove(x)
                elif x in self.anim_queue:
                    self.anim_queue.remove(x)
                    
        
        #Do other stuff
        if self.mouseWatcherNode.hasMouse():
            x=base.mouseWatcherNode.getMouseX()
            y=base.mouseWatcherNode.getMouseY()
            if self.prev_pos==None:
                self.prev_pos = (x,y)
            xx = self.prev_pos[0] - x
            yy = self.prev_pos[1] + y
            self.prev_pos = (xx,yy)
            
            self.pandaActor.setHpr(self.pandaActor,-20*(pi/2.0)*x,0,0)
            
            #self.camera.setHpr(self.pandaActor, 20*(pi/2.0)*x, 20*(pi/2.0)*yy, 0)
            if self.is_firstP:
                self.camera.lookAt(self.pandaActor)
                self.camera.setPos(self.pandaActor,0,0,4)
                self.camera.setHpr(self.camera,180,0,0)
                
            else:
                self.camera.setPos(self.pandaActor,0,8,5)
                self.camera.lookAt(self.pandaActor)
                if self.mirror:
                    self.camera.setY(-self.camera.getY())
                    self.camera.lookAt(self.pandaActor)
            self.camera.setHpr(self.camera,0,20*(pi/2.0)*yy,0)
        self.center_mouse()
        
        #zombie collisions
        return Task.cont
    
    #User Actions:
    def meelee(self):
        #Make actor stomp here. or something
        #Load animation
        self.zombieland.meelee()
        self.anim_queue += [(self.pandaActor,True,self.pandaActor.getCurrentAnim())]
        self.pandaActor.play('kick')
        #pass
    def ranged_start(self):
        #put animation here
        self.old_anim = self.pandaActor.getCurrentAnim()
        if self.old_anim not in  ['shooting','unready_to_shoot','ready_to_shoot'] :
            self.old_anim2 = self.old_anim
        if self.old_anim not in ['ready_to_shoot','shooting','unready_to_shoot']:
            self.pandaActor.play('ready_to_shoot')
        
        self.taskMgr.add(self.bulletThrower, "zombieTask_bulletThrower")
    def ranged_stop(self,task=None):
        if self.paused:
            return Task.cont
        #stop animation here
        if self.pandaActor.getCurrentAnim()<>'shooting' and task==None:
            self.pandaActor.play('shooting')
            self.taskMgr.remove("zombieTask_bulletThrower")
            self.taskMgr.doMethodLater(0.5,self.ranged_stop,'zombieTask_rangedStop')
            return Task.done
        self.taskMgr.remove("zombieTask_bulletThrower")
        return Task.done
class DistributedCashbotBossObject(DistributedSmoothNode.DistributedSmoothNode,
                                   FSM.FSM):
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'DistributedCashbotBossObject')
    wantsWatchDrift = 1

    def __init__(self, cr):
        DistributedSmoothNode.DistributedSmoothNode.__init__(self, cr)
        FSM.FSM.__init__(self, 'DistributedCashbotBossObject')
        self.boss = None
        self.avId = 0
        self.craneId = 0
        self.cleanedUp = 0
        self.collisionNode = CollisionNode('object')
        self.collisionNode.setIntoCollideMask(
            ToontownGlobals.PieBitmask | OTPGlobals.WallBitmask
            | ToontownGlobals.CashbotBossObjectBitmask
            | OTPGlobals.CameraBitmask)
        self.collisionNode.setFromCollideMask(ToontownGlobals.PieBitmask
                                              | OTPGlobals.FloorBitmask)
        self.collisionNodePath = NodePath(self.collisionNode)
        self.physicsActivated = 0
        self.toMagnetSoundInterval = Sequence()
        self.hitFloorSoundInterval = Sequence()
        self.hitBossSfx = loader.loadSfx(
            'phase_5/audio/sfx/AA_drop_safe_miss.ogg')
        self.hitBossSoundInterval = SoundInterval(self.hitBossSfx)
        self.touchedBossSfx = loader.loadSfx(
            'phase_5/audio/sfx/AA_drop_sandbag.ogg')
        self.touchedBossSoundInterval = SoundInterval(self.touchedBossSfx,
                                                      duration=0.8)
        self.lerpInterval = None

    def disable(self):
        self.cleanup()
        self.stopSmooth()
        DistributedSmoothNode.DistributedSmoothNode.disable(self)

    def cleanup(self):
        if self.cleanedUp:
            return
        else:
            self.cleanedUp = 1

        self.demand('Off')
        self.detachNode()
        self.toMagnetSoundInterval.finish()
        self.hitFloorSoundInterval.finish()
        self.hitBossSoundInterval.finish()
        self.touchedBossSoundInterval.finish()
        del self.toMagnetSoundInterval
        del self.hitFloorSoundInterval
        del self.hitBossSoundInterval
        del self.touchedBossSoundInterval
        self.boss = None

    def setupPhysics(self, name):
        an = ActorNode('%s-%s' % (name, self.doId))
        anp = NodePath(an)
        if not self.isEmpty():
            self.reparentTo(anp)
        NodePath.assign(self, anp)
        self.physicsObject = an.getPhysicsObject()
        self.setTag('object', str(self.doId))
        self.collisionNodePath.reparentTo(self)
        self.handler = PhysicsCollisionHandler()
        self.handler.addCollider(self.collisionNodePath, self)
        self.collideName = self.uniqueName('collide')
        self.handler.addInPattern(self.collideName + '-%in')
        self.handler.addAgainPattern(self.collideName + '-%in')
        self.watchDriftName = self.uniqueName('watchDrift')

    def activatePhysics(self):
        if not self.physicsActivated:
            self.boss.physicsMgr.attachPhysicalNode(self.node())
            base.cTrav.addCollider(self.collisionNodePath, self.handler)
            self.physicsActivated = 1
            self.accept(self.collideName + '-floor', self.__hitFloor)
            self.accept(self.collideName + '-goon', self.__hitGoon)
            self.acceptOnce(self.collideName + '-headTarget', self.__hitBoss)
            self.accept(self.collideName + '-dropPlane', self.__hitDropPlane)

    def deactivatePhysics(self):
        if self.physicsActivated:
            self.boss.physicsMgr.removePhysicalNode(self.node())
            base.cTrav.removeCollider(self.collisionNodePath)
            self.physicsActivated = 0
            self.ignore(self.collideName + '-floor')
            self.ignore(self.collideName + '-goon')
            self.ignore(self.collideName + '-headTarget')
            self.ignore(self.collideName + '-dropPlane')

    def hideShadows(self):
        pass

    def showShadows(self):
        pass

    def stashCollisions(self):
        self.collisionNodePath.stash()

    def unstashCollisions(self):
        self.collisionNodePath.unstash()

    def __hitFloor(self, entry):
        if self.state == 'Dropped' or self.state == 'LocalDropped':
            self.d_hitFloor()
            self.demand('SlidingFloor', localAvatar.doId)

    def __hitGoon(self, entry):
        if self.state == 'Dropped' or self.state == 'LocalDropped':
            goonId = int(entry.getIntoNodePath().getNetTag('doId'))
            goon = self.cr.doId2do.get(goonId)
            if goon:
                self.doHitGoon(goon)

    def doHitGoon(self, goon):
        pass

    def __hitBoss(self, entry):
        if (self.state == 'Dropped' or self.state
                == 'LocalDropped') and self.craneId != self.boss.doId:
            vel = self.physicsObject.getVelocity()
            vel = self.crane.root.getRelativeVector(render, vel)
            vel.normalize()
            impact = vel[1]
            if impact >= self.getMinImpact():
                print 'hit! %s' % impact
                self.hitBossSoundInterval.start()
                self.doHitBoss(impact)
            else:
                self.touchedBossSoundInterval.start()
                print '--not hard enough: %s' % impact

    def doHitBoss(self, impact):
        self.d_hitBoss(impact)

    def __hitDropPlane(self, entry):
        self.notify.info('%s fell out of the world.' % self.doId)
        self.fellOut()

    def fellOut(self):
        raise StandardError, 'fellOut unimplented'

    def getMinImpact(self):
        return 0

    def __watchDrift(self, task):
        v = self.physicsObject.getVelocity()
        if abs(v[0]) < 0.0001 and abs(v[1]) < 0.0001:
            self.d_requestFree()
            self.demand('Free')

        return Task.cont

    def prepareGrab(self):
        pass

    def prepareRelease(self):
        pass

    def setBossCogId(self, bossCogId):
        self.bossCogId = bossCogId
        self.boss = base.cr.doId2do[bossCogId]

    def setObjectState(self, state, avId, craneId):
        if state == 'G':
            self.demand('Grabbed', avId, craneId)
        elif state == 'D':
            if self.state != 'Dropped':
                self.demand('Dropped', avId, craneId)
        elif state == 's':
            if self.state != 'SlidingFloor':
                self.demand('SlidingFloor', avId)
        elif state == 'F':
            self.demand('Free')
        else:
            self.notify.error('Invalid state from AI: %s' % state)

    def d_requestGrab(self):
        self.sendUpdate('requestGrab')

    def rejectGrab(self):
        if self.state == 'LocalGrabbed':
            self.demand('LocalDropped', self.avId, self.craneId)

    def d_requestDrop(self):
        self.sendUpdate('requestDrop')

    def d_hitFloor(self):
        self.sendUpdate('hitFloor')

    def d_requestFree(self):
        self.sendUpdate(
            'requestFree',
            [self.getX(), self.getY(),
             self.getZ(), self.getH()])

    def d_hitBoss(self, impact):
        self.sendUpdate('hitBoss', [impact])

    def defaultFilter(self, request, args):
        if self.boss == None:
            raise FSM.RequestDenied, request
        return FSM.FSM.defaultFilter(self, request, args)

    def enterOff(self):
        self.detachNode()
        if self.lerpInterval:
            self.lerpInterval.finish()
            self.lerpInterval = None

    def exitOff(self):
        self.reparentTo(render)

    def enterLocalGrabbed(self, avId, craneId):
        self.avId = avId
        self.craneId = craneId
        self.crane = self.cr.doId2do.get(craneId)
        self.hideShadows()
        self.prepareGrab()
        self.crane.grabObject(self)

    def exitLocalGrabbed(self):
        if self.newState != 'Grabbed':
            self.crane.dropObject(self)
            self.prepareRelease()
            del self.crane
            self.showShadows()

    def enterGrabbed(self, avId, craneId):
        if self.oldState == 'LocalGrabbed':
            if craneId == self.craneId:
                return
            else:
                self.crane.dropObject(self)
                self.prepareRelease()

        self.avId = avId
        self.craneId = craneId
        self.crane = self.cr.doId2do.get(craneId)
        self.hideShadows()
        self.prepareGrab()
        self.crane.grabObject(self)

    def exitGrabbed(self):
        self.crane.dropObject(self)
        self.prepareRelease()
        self.showShadows()
        del self.crane

    def enterLocalDropped(self, avId, craneId):
        self.avId = avId
        self.craneId = craneId
        self.crane = self.cr.doId2do.get(craneId)
        self.activatePhysics()
        self.startPosHprBroadcast()
        self.hideShadows()
        self.handler.setStaticFrictionCoef(0)
        self.handler.setDynamicFrictionCoef(0)

    def exitLocalDropped(self):
        if self.newState != 'SlidingFloor' and self.newState != 'Dropped':
            self.deactivatePhysics()
            self.stopPosHprBroadcast()
        del self.crane
        self.showShadows()

    def enterDropped(self, avId, craneId):
        self.avId = avId
        self.craneId = craneId
        self.crane = self.cr.doId2do.get(craneId)
        if self.avId == base.localAvatar.doId:
            self.activatePhysics()
            self.startPosHprBroadcast()
            self.handler.setStaticFrictionCoef(0)
            self.handler.setDynamicFrictionCoef(0)
        else:
            self.startSmooth()

        self.hideShadows()

    def exitDropped(self):
        if self.avId == base.localAvatar.doId:
            if self.newState != 'SlidingFloor':
                self.deactivatePhysics()
                self.stopPosHprBroadcast()
        else:
            self.stopSmooth()

        del self.crane
        self.showShadows()

    def enterSlidingFloor(self, avId):
        self.avId = avId
        if self.lerpInterval:
            self.lerpInterval.finish()
            self.lerpInterval = None
        if self.avId == base.localAvatar.doId:
            self.activatePhysics()
            self.startPosHprBroadcast()
            self.handler.setStaticFrictionCoef(0.9)
            self.handler.setDynamicFrictionCoef(0.5)
            if self.wantsWatchDrift:
                taskMgr.add(self.__watchDrift, self.watchDriftName)
        else:
            self.startSmooth()

        self.hitFloorSoundInterval.start()

    def exitSlidingFloor(self):
        if self.avId == base.localAvatar.doId:
            taskMgr.remove(self.watchDriftName)
            self.deactivatePhysics()
            self.stopPosHprBroadcast()
        else:
            self.stopSmooth()

    def enterFree(self):
        self.avId = 0
        self.craneId = 0

    def exitFree(self):
        pass
예제 #14
0
)
snipstuff.info_show()

#=========================================================================
# Main
""" As you probably know, physics in games is a cool feature that give life to the show and today it is quite impossible not to face it while developing a modern game and panda3D make no exception. Though, you got to know that panda3d physics engine is not a complete physics engine but is there to solve simple tasks, especially related to particle management, even if could be applied to 3d models as well, so you may first understand what it got to offer and what are its limitations then see if suits for your game. We're not going to dig furter this issue, cos the panda3d manual already gotta dedicated section but rather we'll see how to setup collisions to interact with physics. We got a simple scene with a roaming smiley and a shower of frowneys and watermelons where each element in the scene will be able to collide each other, floor included and everything driven by the panda3d physics engine.
Note that we don't need to set masking in this setup cos each objet collide with each other, therefore every collider, beside the floor, gotta act as from and to object therefore the default masking setup is good as is.
"""
#=========================================================================

#** Collision system ignition - even if we're going to interact with the physics routines, the usual traverser is always in charge to drive collisions
base.cTrav = CollisionTraverser()
# look here: we enable the particle system - this is the evidence of what I was saying above, because the panda physics engine is conceived mainly to manage particles.
base.enableParticles()
# here there is the handler to use this time to manage collisions.
collisionHandler = PhysicsCollisionHandler()

#** This is the first time we see this collider: it is used mainly to define a flat infinite plane surface -
# it is very reliable and stable and gives high fame rate performances so use it as much as you can.
# Note that we specify 2 corners of the plane of just 1 unit per side but this collider will collide
#  with everithing as it was an infinite plane anyhow. Note that there is no need to set anything further for it.

cp = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0)))
planeNP = base.render.attachNewNode(CollisionNode('planecnode'))
planeNP.node().addSolid(cp)
planeNP.show()

#** This is how to define the gravity force to make our stuff fall down: first off we define a ForceNode and attach to the render, so that everything below will be affected by this force
globalforcesFN = ForceNode('world-forces')
globalforcesFNP = base.render.attachNewNode(globalforcesFN)
# then we set a linear force that will act in Z axis-drag-down-force of 9.81 units per second.