Ejemplo n.º 1
0
    def __init__(self,
                 world: BulletWorld,
                 entity: Entity,
                 radius=1,
                 height=2,
                 name='Player',
                 **opts) -> None:
        super().__init__(BulletCapsuleShape(radius / 2, height / 2, 1),
                         radius / 2, name)
        self.np = application.base.render.attachNewNode(self)

        if entity.parent:
            self.np.reparent_to(entity.parent)

        rotation = Vec3(0, 0, 0)
        if None in rotation:
            hpr = entity.getHpr()
            for x in range(len(hpr)):
                rotation[x] = hpr[x]
        self.np.setHpr(rotation)

        self.np.setPos(entity.x, entity.y, entity.z)
        entity.reparent_to(self.np)

        world.attachCharacter(self)

        self.__fall_speed = None
        self.__jump_speed = None
        self.__max_jump_height = None

        for x in opts:
            setattr(self, x, opts[x])
Ejemplo n.º 2
0
class Game(DirectObject):

  def __init__(self):
    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -20, 4)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(1, 1, -1))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.clearLight()
    render.setLight(alightNP)
    render.setLight(dlightNP)

    # Input
    self.accept('escape', self.doExit)
    self.accept('r', self.doReset)
    self.accept('f1', self.toggleWireframe)
    self.accept('f2', self.toggleTexture)
    self.accept('f3', self.toggleDebug)
    self.accept('f5', self.doScreenshot)

    self.accept('space', self.doJump)
    self.accept('c', self.doCrouch)

    inputState.watchWithModifiers('forward', 'w')
    inputState.watchWithModifiers('left', 'a')
    inputState.watchWithModifiers('reverse', 's')
    inputState.watchWithModifiers('right', 'd')
    inputState.watchWithModifiers('turnLeft', 'q')
    inputState.watchWithModifiers('turnRight', 'e')

    # Task
    taskMgr.add(self.update, 'updateWorld')

    # Physics
    self.setup()

  # _____HANDLER_____

  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def doReset(self):
    self.cleanup()
    self.setup()

  def toggleWireframe(self):
    base.toggleWireframe()

  def toggleTexture(self):
    base.toggleTexture()

  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()

  def doScreenshot(self):
    base.screenshot('Bullet')

  def doJump(self):
    self.character.setMaxJumpHeight(5.0)
    self.character.setJumpSpeed(8.0)
    self.character.doJump()

  def doCrouch(self):
    self.crouching = not self.crouching
    sz = self.crouching and 0.6 or 1.0

    self.characterNP.setScale(Vec3(1, 1, sz))

    #self.character.getShape().setLocalScale(Vec3(1, 1, sz))
    #self.characterNP.setScale(Vec3(1, 1, sz) * 0.3048)
    #self.characterNP.setPos(0, 0, -1 * sz)

  # ____TASK___

  def processInput(self, dt):
    speed = Vec3(0, 0, 0)
    omega = 0.0

    if inputState.isSet('forward'): speed.setY( 2.0)
    if inputState.isSet('reverse'): speed.setY(-2.0)
    if inputState.isSet('left'):    speed.setX(-2.0)
    if inputState.isSet('right'):   speed.setX( 2.0)
    if inputState.isSet('turnLeft'):  omega =  120.0
    if inputState.isSet('turnRight'): omega = -120.0

    self.character.setAngularMovement(omega)
    self.character.setLinearMovement(speed, True)

  def update(self, task):
    dt = globalClock.getDt()

    self.processInput(dt)
    self.world.doPhysics(dt, 4, 1./240.)

    return task.cont

  def cleanup(self):
    self.world = None
    self.worldNP.removeNode()

  def setup(self):
    self.worldNP = render.attachNewNode('World')

    # World
    self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.show()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Ground
    shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

    #img = PNMImage(Filename('models/elevation2.png'))
    #shape = BulletHeightfieldShape(img, 1.0, ZUp)

    np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
    np.node().addShape(shape)
    np.setPos(0, 0, -1)
    np.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(np.node())

    # Box
    shape = BulletBoxShape(Vec3(1.0, 3.0, 0.3))

    np = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
    np.node().setMass(10.0)
    np.node().addShape(shape)
    np.setPos(3, 0, 4)
    np.setH(20.0)
    np.setCollideMask(BitMask32.allOn())

    self.world.attachRigidBody(np.node())

    # Character
    self.crouching = False

    h = 1.75
    w = 0.4
    shape = BulletCapsuleShape(w, h - 2 * w, ZUp)

    self.character = BulletCharacterControllerNode(shape, 0.4, 'Player')
    # self.character.setMass(1.0)
    self.characterNP = self.worldNP.attachNewNode(self.character)
    self.characterNP.setPos(-2, 0, 14)
    self.characterNP.setH(45)
    self.characterNP.setCollideMask(BitMask32.allOn())
    self.world.attachCharacter(self.character)

    self.actorNP = Actor('models/ralph/ralph.egg', {
                         'run' : 'models/ralph/ralph-run.egg',
                         'walk' : 'models/ralph/ralph-walk.egg',
                         'jump' : 'models/ralph/ralph-jump.egg'})
    self.actorNP.reparentTo(self.characterNP)
    self.actorNP.setScale(0.3048) # 1ft = 0.3048m
    self.actorNP.setH(180)
    self.actorNP.setPos(0, 0, -1)
Ejemplo n.º 3
0
class App(ShowBase):
    def moveForward(self, catch):
        print('w key pressed')
        self.cy = 3.0
        print(self.current_pos)

    def moveBackward(self, catch):
        print('w key pressed')
        self.cy = -3.0
        print(self.current_pos)

    def moveLeft(self, catch):
        print('w key pressed')
        self.cx = 3.0
        print(self.current_pos)

    def moveRight(self, catch):
        print('w key pressed')
        self.cx = -3.0
        print(self.current_pos)

    def lookLeft(self, catch):
        self.current_omega = 120

    def lookRight(self, catch):
        self.current_omega = -120

    def lookUp(self, catch):
        self.current_hpr = (self.current_hpr[0], self.current_hpr[1] - 1,
                            self.current_hpr[2])

    def moveUp(self, catch):
        self.current_pos = (self.current_pos[0], self.current_pos[1],
                            self.current_pos[2] + 1)

    def lookUp(self, catch):
        self.current_hpr = (self.current_hpr[0], self.current_hpr[1] + 1,
                            self.current_hpr[2])

    def lookDown(self, catch):
        self.current_hpr = (self.current_hpr[0], self.current_hpr[1] - 1,
                            self.current_hpr[2])

    def fire(self, catch):
        print("Fire!")
        if self.pandaPos[0] == self.current_pos[0] and self.pandaPos[
                2] + 0.5 == self.current_pos[2] and not self.pandaPos[
                    1] == self.current_pos[1] and not self.pandaPos[
                        1] - 1 == self.current_pos[1] and not self.current_pos[
                            1] - 1 == self.pandaPos[1] and not self.current_pos[
                                1] > self.pandaPos[1]:
            print('Oof')

    def jump(self, catch):
        self.player.setMaxJumpHeight(5.0)
        self.player.setJumpSpeed(8.0)
        self.player.doJump()

    def __init__(self):
        ShowBase.__init__(self)
        #self.word = BulletWorld()
        self.cx = 0.0
        self.cy = 0.0
        self.current_omega = 0
        s = self.loader.loadSfx('Doom Soundtrack - Level 1 (Extended).mp3')
        s.play()
        self.current_pos = (10, 5, 1)
        self.current_hpr = (0, 0, 0)
        #self.fxboy = self.loader.loadModel("cubearm.egg")
        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -12.0))
        #self.physicsMgr.attachPhysicalNode(self.camera)
        keyboard.on_press_key('w', self.moveForward)
        keyboard.on_press_key('s', self.moveBackward)
        keyboard.on_press_key('j', self.lookLeft)
        keyboard.on_press_key('y', self.lookUp)
        keyboard.on_press_key('h', self.lookDown)
        keyboard.on_press_key('g', self.lookRight)
        keyboard.on_press_key('d', self.moveLeft)
        #self.fxboy.reparentTo(self.render)
        #self.camera.reparentTo(self.render)
        #self.camera.reparentTo(self.fxboy)
        keyboard.on_press_key('a', self.moveRight)
        keyboard.on_press_key('space', self.fire)
        keyboard.on_press_key('2', self.jump)
        #keyboard.on_press_key('y',self.lookUp)
        keyboard.on_press_key('1', self.moveUp)

        self.cam = BulletCapsuleShape(radius, height - 2 * radius, ZUp)
        self.player = BulletCharacterControllerNode(self.cam, 0.4, 'Player')
        self.playernp = self.render.attachNewNode(self.player)
        self.world.attachCharacter(self.playernp.node())
        self.camera.reparentTo(self.playernp)
        self.playernp.setPos(self.current_pos)
        self.playernp.setHpr(self.current_hpr)
        self.playernp.setH(45)
        #self.player.setMass(10.0)
        # self.playernp.setCollideMask(BitMask32.allOn())
        self.disableMouse()

        self.scenes = BulletBoxShape(Vec3(0.25, 0.25, 0.25))
        self.scenenode = BulletRigidBodyNode('Scene')
        self.scenenode.setMass(12.0)
        self.scenenode.addShape(self.scenes)
        self.scenenp = render.attachNewNode(self.scenenode)
        self.scenenp.setPos(-8, 40, 0)
        self.world.attachRigidBody(self.scenenode)
        self.scene = self.loader.loadModel("models/environment.egg.pz")
        self.scene.reparentTo(self.render)
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 40, 0)
        self.scene.reparentTo(self.scenenp)
        self.scenenode.setGravity(Vec3(0, 0, 0))

        #self.taskMgr.add(self.spinCameraTask,"SpinCameraTask")
        self.taskMgr.add(self.moveChar, "MoveChar")
        self.taskMgr.add(self.moveCBod, "MoveCBod")
        self.pandaActor = Actor("cubearm.egg",
                                {"walk": "cubearm4-ArmatureAction.egg"})
        self.pandaActor.setScale(0.12, 0.12, 0.12)
        self.pandaActor.setPos((10, 10, 0.5))
        self.pandaPos = (10, 10, 0.5)
        self.pandaActor.reparentTo(self.render)
        self.pandaActor.loop('walk')
        '''
        posInterval1 = self.pandaActor.posInterval(13,Point3(0,-10,0),startPos=Point3(0,10,0))
        posInterval2 = self.pandaActor.posInterval(13,Point3(0,10,0),startPos=Point3(0,-10,0))
        hprInterval1 = self.pandaActor.hprInterval(3,Point3(180,0,0),startHpr=Point3(0,0,0))
        hprInterval2 = self.pandaActor.hprInterval(3,Point3(0,0,0),startHpr=Point3(180,0,0))
        self.pandaPace = Sequence(posInterval1,hprInterval1,posInterval2,hprInterval2,name="pandaPace")
        self.pandaPace.loop()
        '''

    def spinCameraTask(self, task):
        print(task.time * 6.0)
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont

    def moveChar(self, task):
        speed = Vec3(0, 0, 0)
        omega = self.current_omega
        speed.setX(self.cx)
        speed.setY(self.cy)
        #self.scenenp.setPos(-8,40,0)
        print('[Scene]: ' + str(self.scenenp.getPos()))
        print('[Cam]: ' + str(self.playernp.getPos()))
        self.player.setAngularMovement(omega)
        #self.player.setLinearMovement(speed,True)
        #self.playernp.setPos(self.current_pos)
        self.playernp.setHpr(self.current_hpr)

        return task.cont

    def moveCBod(self, task):
        self.world.doPhysics(globalClock.getDt())
        return task.cont
Ejemplo n.º 4
0
class Game(DirectObject):
    def __init__(self):
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -20, 4)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight("ambientLight")
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight("directionalLight")
        dlight.setDirection(Vec3(1, 1, -1))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept("escape", self.doExit)
        self.accept("r", self.doReset)
        self.accept("f1", self.toggleWireframe)
        self.accept("f2", self.toggleTexture)
        self.accept("f3", self.toggleDebug)
        self.accept("f5", self.doScreenshot)

        # self.accept('space', self.doJump)
        # self.accept('c', self.doCrouch)

        inputState.watchWithModifiers("forward", "w")
        inputState.watchWithModifiers("left", "a")
        inputState.watchWithModifiers("reverse", "s")
        inputState.watchWithModifiers("right", "d")
        inputState.watchWithModifiers("turnLeft", "q")
        inputState.watchWithModifiers("turnRight", "e")

        # Task
        taskMgr.add(self.update, "updateWorld")

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot("Bullet")

    # def doJump(self):
    #  self.player.setMaxJumpHeight(5.0)
    #  self.player.setJumpSpeed(8.0)
    #  self.player.doJump()

    # def doCrouch(self):
    #  self.crouching = not self.crouching
    #  sz = self.crouching and 0.6 or 1.0

    #  self.playerNP2.setScale(Vec3(1, 1, sz))

    # ____TASK___

    def processInput(self, dt):
        speed = Vec3(0, 0, 0)
        omega = 0.0

        if inputState.isSet("forward"):
            speed.setY(2.0)
        if inputState.isSet("reverse"):
            speed.setY(-2.0)
        if inputState.isSet("left"):
            speed.setX(-2.0)
        if inputState.isSet("right"):
            speed.setX(2.0)
        if inputState.isSet("turnLeft"):
            omega = 120.0
        if inputState.isSet("turnRight"):
            omega = -120.0

        self.player.setAngularMovement(omega)
        self.player.setLinearMovement(speed, True)

    def update(self, task):
        dt = globalClock.getDt()

        self.processInput(dt)
        self.world.doPhysics(dt, 4, 1.0 / 240.0)

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode("World")

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode("Debug"))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

        # img = PNMImage(Filename('models/elevation2.png'))
        # shape = BulletHeightfieldShape(img, 1.0, ZUp)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode("Ground"))
        np.node().addShape(shape)
        np.setPos(0, 0, -1)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Box
        shape = BulletBoxShape(Vec3(1.0, 3.0, 0.3))

        np = self.worldNP.attachNewNode(BulletRigidBodyNode("Box"))
        np.node().setMass(50.0)
        np.node().addShape(shape)
        np.setPos(3, 0, 4)
        np.setH(0)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Character
        h = 1.75
        w = 0.4
        shape = BulletCapsuleShape(w, h - 2 * w, ZUp)

        self.player = BulletCharacterNode(shape, 0.4, "Player")
        self.player.setMass(20.0)
        self.player.setMaxSlope(45.0)
        self.player.setGravity(9.81)
        self.playerNP = self.worldNP.attachNewNode(self.player)
        self.playerNP.setPos(-2, 0, 10)
        self.playerNP.setH(-90)
        self.playerNP.setCollideMask(BitMask32.allOn())
        self.world.attachCharacter(self.player)
Ejemplo n.º 5
0
class BulletEngine(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.init_shader()
        self.init_light_camera()
        self.init_bullet_engine()
        self.setup()
        self.init_input()
        taskMgr.add(self.update,'updateWorld')


    # 灯光镜头初始化
    def init_light_camera(self):
         self.setBackgroundColor(0.1, 0.1, 0.8, 1)
         self.setFrameRateMeter(True)

         # self.cam.setPos(0, -20, 4)
         # self.cam.lookAt(0, 0, 0)

         self.cam.setPos(0, 0, 100)
         self.cam.lookAt(0, 0, -90)

         # Light
         alight = AmbientLight('ambientLight')
         alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
         alightNP = render.attachNewNode(alight)

         dlight = DirectionalLight('directionalLight')
         dlight.setDirection(Vec3(1, 1, -1))
         dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
         dlightNP = render.attachNewNode(dlight)

         render.clearLight()
         render.setLight(alightNP)
         render.setLight(dlightNP)

    # 输入初始化
    def init_input(self):
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        # 事件管理
        self.accept('space', self.doJump)
        self.accept('mouse1',self.doShoot)
        self.accept('control', self.doCrouch)
        self.accept('1',self.getCurrentPos)

        inputState.watchWithModifiers('back', 's')
        inputState.watchWithModifiers('forward', 'w')
        inputState.watchWithModifiers('turnLeft', 'a')
        inputState.watchWithModifiers('turnRight', 'd')

    # _____HANDLER_____
    def doExit(self):
        # self.cleanup()
        sys.exit(1)

    def doReset(self):
        # self.cleanup()
        # self.setup()
        pass

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        self.screenshot('Bullet')

    def doJump(self):
        self.actor_character_NP.setJumpSpeed(JUMPSPEED)
        self.actor_character_NP.setMaxJumpHeight(JUMPHEIGHT)
        self.actor_character_NP.isOnGround()
        self.actor_character_NP.doJump()

    def getCurrentPos(self):
        print "角色当前位置 %s" % self.actorNP.getPos()

    # ____TASK___

    def processInput(self, dt):
        speed = Vec3(0, 0, 0)
        omega = 0.0
        force = Vec3(0,0,0)
        torque = Vec3(0,0,0)

        if inputState.isSet('forward'): speed.setY(-SPEED)
        if inputState.isSet('forward'): force.setY(-SPEED)
        if inputState.isSet('back'): speed.setY(SPEED)
        if inputState.isSet('back'): force.setY(SPEED)
        if inputState.isSet('turnLeft'):  omega = 120.0
        if inputState.isSet('turnLeft'):  torque = 120.0
        if inputState.isSet('turnRight'): omega = -120.0
        if inputState.isSet('turnRight'): torque = -120.0

        force *= 30.0
        torque *= 10.0
        # character
        self.actor_character_NP.setAngularMovement(omega)
        self.actor_character_NP.setLinearMovement(speed,True)

    def update(self, task):
        dt = globalClock.getDt()
        self.processInput(dt)
        self.world.doPhysics(dt,4,1./240.)
        return task.cont

    def init_shader(self):
        self.backfaceCullingOn()
        self.setFrameRateMeter(True)
        self.render.flattenStrong()
        self.render.setTwoSided(True)
        self.render.setAntialias(AntialiasAttrib.MAuto)

        lod = LODNode("lod")
        lodnp  = NodePath(lod)
        lodnp.reparentTo(self.render)

    def init_bullet_engine(self):
        self.worldNP = render.attachNewNode('World')
        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()
        self.debugNP.node().showWireframe(True)
        self.debugNP.node().showConstraints(True)
        self.debugNP.node().showBoundingBoxes(False)
        self.debugNP.node().showNormals(True)
        self.world.setDebugNode(self.debugNP.node())
        # 玩家
        self.crouching = False
        self.omega = 0.0

    def create_box_rigid(self,name,size,pos,isCCD):
        shape = BulletBoxShape(size)
        body = BulletRigidBodyNode(name)
        bodyNP = self.worldNP.attachNewNode(body)
        bodyNP.node().addShape(shape)
        bodyNP.node().setMass(2.0)
        bodyNP.setPos(pos)
        bodyNP.setCollideMask(BitMask32.allOn())

        if isCCD:
            bodyNP.node().setCcdMotionThreshold(1e-7);
            bodyNP.node().setCcdSweptSphereRadius(0.50);
        return bodyNP

    def doRemove(self,bulletNP,task):
        self.world.removeRigidBody(bulletNP.node())
        return task.done


    def doShoot(self):
        pFrom = Point3(0,0,0)
        pTo = Point3()

        print "omega"
        omega = self.actorNP.getHpr().getX()
        print omega
        omega = (omega - 90)%360
        v = Point3(math.cos(omega * math.pi / 180), math.sin(omega * math.pi / 180),0)
        v.normalize()
        v *= BULLETSPEED
        print '子弹速度 %s' %v
        #create Bullet
        size = Vec3(7,7,7)
        pFrom = self.actorNP.getPos()
        print '玩家位置 %s' %pFrom
        x = self.actorNP.getPos().getX()
        y = self.actorNP.getPos().getY()
        z = self.actorNP.getPos().getZ()
        hpr = self.actorNP.getHpr()
        print '玩家位置x %s' % x
        print '玩家位置y %s' % y
        print '玩家位置z %s' % z
        print '玩家方向hpr %s' % hpr
        print '胶囊包围体r %s' % self.actor_character_NP.getShape().getRadius()
        cosOmg = 10*math.cos(omega*math.pi/180)
        sinOmg = 10*math.sin(omega*math.pi/180)
        bulletNP = self.create_box_rigid('Bullet',size,Point3(x+cosOmg,y+sinOmg,10),True)
        bulletNP.node().setLinearVelocity(v)
        self.world.attachRigidBody(bulletNP.node())
        bulletNP.setCollideMask(BitMask32.allOff())
        print '子弹方向hpr %s' % v
        print '子弹位置 %s' %bulletNP.getPos()

        # Remove the bullet again after 1 sec
        taskMgr.doMethodLater(1,self.doRemove,'doRemove',
                            extraArgs=[bulletNP],
                            appendTask=True)

    ####################### some probelm todo  #########################################
    def doCrouch(self):
        self.crouching = not self.crouching
        sz = self.crouching and 0.6 or 1.0
        # self.actor_shape.setLocalScale(Vec3(1,1,sz))
        self.actorNP.setScale(Vec3(1,1,sz) * 0.3048)


    def setup(self):
        self.sceneMgr = SceneManager()
        self.sceneMgr.build_on(self)

        # Plane (static)
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
        np.node().addShape(shape)
        np.setPos(0, 0, -1)
        np.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(np.node())

        # 测试用房子
        village = self.sceneMgr.add_model_scene(TEST_MAIN_SCENE,self.render)
        village.setTwoSided(True)
        village.setScale(5.0)

        ##测试碰撞平面(西)
        normal = Vec3(0,1,0)
        d = 0
        shape = BulletPlaneShape(normal,d)
        np = self.worldNP.attachNewNode(BulletRigidBodyNode('west_end'))
        np.node().addShape(shape)
        np.setPos(0,-430,0)
        np.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(np.node())

        ##测试碰撞平面(东)
        normal = Vec3(0, -1, 0)
        d = 0
        shape = BulletPlaneShape(normal, d)
        np = self.worldNP.attachNewNode(BulletRigidBodyNode('west_end'))
        np.node().addShape(shape)
        np.setPos(0, 400, 0)
        np.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(np.node())

        ##测试碰撞平面(北)
        normal = Vec3(1,0,0)
        d = 0
        shape = BulletPlaneShape(normal,d)
        np = self.worldNP.attachNewNode(BulletRigidBodyNode('north_end'))
        np.node().addShape(shape)
        np.setPos(-300,0,0)
        np.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(np.node())

        ##测试碰撞平面(南)
        normal = Vec3(-1,0,0)
        d = 0
        shape = BulletPlaneShape(normal,d)
        np = self.worldNP.attachNewNode(BulletRigidBodyNode('north_end'))
        np.node().addShape(shape)
        np.setPos(330,0,0)
        np.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(np.node())

        # Some boxes
        # size = 9.0
        # shape = BulletBoxShape(Vec3(size,size,size))
        # body = BulletRigidBodyNode('Big box')
        # self.boxNP = self.worldNP.attachNewNode(body)
        # self.boxNP.node().addShape(shape)
        # # self.boxNP.node().setMass(100.0)
        # self.boxNP.node().setDeactivationEnabled(False)
        # self.boxNP.setPos(0,0,10)
        # self.boxNP.setCollideMask(BitMask32.allOn())
        # self.world.attachRigidBody(self.boxNP.node())

        house1NP = self.create_box_rigid('house1',Vec3(5,5,5),Vec3(0,0,5),False)
        self.world.attachRigidBody(house1NP.node())
        house1NP.node().setDeactivationEnabled(False)

        # 猎人
        actor = self.sceneMgr.add_actor_scene(HUNTER_PATH,
                                         HUNTER_ACTION_PATH,
                                         self.render)
        actor.setPos(0,1,-10)
        actor.setScale(1.6)
        actor.setTwoSided(True)
        self.add_actor_collide(actor,3.5,15)

        # control
        self.sceneMgr.get_ActorMgr().set_clock(globalClock)
        actorId = self.sceneMgr.get_ActorMgr().get_resId(actor)
        self.sceneMgr.get_ActorMgr().add_toggle_to_actor("w", actorId, "run")
        self.sceneMgr.get_ActorMgr().add_toggle_to_actor("s", actorId, "run_back")
        self.sceneMgr.get_ActorMgr().add_toggle_to_actor("z", actorId, "rda")
        self.sceneMgr.get_ActorMgr().add_toggle_to_actor("x", actorId, "lda")
        self.sceneMgr.get_ActorMgr().add_toggle_to_actor("c", actorId, "bda")
        print "actorId : ", actorId

        camCtrlr = CameraController()
        camCtrlr.bind_camera(self.cam)
        camCtrlr.bind_ToggleHost(self)
        camCtrlr.set_clock(globalClock)
        camCtrlr.focus_on(actor, 100)
        camCtrlr.set_rotateSpeed(10)
        camCtrlr.add_toggle_to_opt("u", "rotate_around_up")
        camCtrlr.add_toggle_to_opt("j", "rotate_around_down")
        camCtrlr.add_toggle_to_opt("h", "rotate_around_cw")
        camCtrlr.add_toggle_to_opt("k", "rotate_around_ccw")

        self.sceneMgr.bind_CameraController(camCtrlr)
        self.sceneMgr.get_ActorMgr().bind_CameraController(camCtrlr)

        print self.sceneMgr.get_ActorMgr().get_eventActionRecord()
        print self.sceneMgr.get_ActorMgr().get_eventEffertRecord()

        self.roleMgr = RoleManager()
        self.sceneMgr.get_ActorMgr().bind_RoleManager(self.roleMgr)
        self.roleMgr.bind_SceneManager(self.sceneMgr)
        player = self.roleMgr.create_role(roleType="PlayerRole",
                                     modelId=actorId)
        player.print_all_attr()

        self.taskMgr.add(self.sceneMgr.update_scene, "update_scene")

    def add_actor_collide(self,actor,radius,height):
        # 猎人胶囊碰撞体
        r = radius
        h = height
        self.actor_shape = BulletCapsuleShape(r, height, ZUp)
        self.actor_character_NP = BulletCharacterControllerNode(self.actor_shape, 1.0, 'Player')
        self.actorNP = self.worldNP.attachNewNode(self.actor_character_NP)
        self.actorNP.setPos(-20, 30, 0)
        self.actorNP.setCollideMask(BitMask32.allOn())
        self.world.attachCharacter(self.actorNP.node())
        # actor.detachNode(self.world)
        actor.reparentTo(self.actorNP)


    def add_house_collide(self, house, size,pos,houseName):
        # geomNodes = loader.loadModel(TEST_HOUSE1).findAllMatches('**/+GeomNode')
        # geomNode = geomNodes.getPath(0).node()
        # geom = geomNode.getGeom(0)
        # house_shape = BulletConvexHullShape()
        # house_shape.addGeom(geom)
        # houseNP = self.worldNP.attachNewNode(BulletRigidBodyNode(houseName))
        # houseNP.node().addShape(house_shape)
        # houseNP.setPos(pos)
        # # houseNP.node().setMass(10.0)
        # houseNP.setCollideMask(BitMask32.allOn())
        # self.world.attachRigidBody(houseNP.node())
        # house.reparentTo(houseNP)
        # house.setPos(0,0,0)
        pass
Ejemplo n.º 6
0
class FriendlyFruit(ShowBase, Scene):
    def __init__(self, server_connection, player_tag):
        ShowBase.__init__(self)
        self.__server_connection = server_connection
        self.__player_tag = player_tag
        self.__rotations = {}

        # Panda pollutes the global namespace.  Some of the extra globals can be referred to in nicer ways
        # (for example self.render instead of render).  The globalClock object, though, is only a global!  We
        # create a reference to it here, in a way that won't upset PyFlakes.
        self.globalClock = __builtins__["globalClock"]

        # Turn off the debugging system which allows the camera to be adjusted directly by the mouse.
        self.disableMouse()

        # Set up physics: the ground plane and the capsule which represents the player.
        self.world = BulletWorld()

        # The ground first:
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
        node = BulletRigidBodyNode("Ground")
        node.addShape(shape)
        np = self.render.attachNewNode(node)
        np.setPos(0, 0, 0)
        self.world.attachRigidBody(node)

        # Enable shader generation (for more sophisticated lighting etc.)
        self.render.setShaderAuto()

        # Create lights so we can see the scene.
        dlight = DirectionalLight("dlight")
        dlight.setColor(VBase4(2, 2, 2, 0))
        dlnp = self.render.attachNewNode(dlight)
        dlnp.setHpr(0, -60, 0)
        self.render.setLight(dlnp)

        alight = AmbientLight('alight')
        alight.setColor(VBase4(0.75, 0.75, 0.75, 0))
        alnp = self.render.attachNewNode(alight)
        self.render.setLight(alnp)

        # Create a task to update the scene regularly.
        self.taskMgr.add(self.update, "UpdateTask")

    # Update the scene by turning objects if necessary, and processing physics.
    def update(self, task):
        asyncore.loop(timeout=0.01, use_poll=True, count=1)

        for node, angular_velocity in self.__rotations.iteritems():
            node.setAngularMovement(angular_velocity)

        dt = self.globalClock.getDt()
        self.world.doPhysics(dt)
        return task.cont

    def server_created_object(self, tag, height, radius):
        # This shape is used for collision detection, preventing the player falling through the ground for
        # example.
        shape = BulletCapsuleShape(radius, height - 2 * radius, ZUp)

        # A character controller is a physical body which responds instantly to keyboard controls.  (Bodies
        # which respond to forces are difficult to control in a satisfactory way using typical video game
        # controls.  Players expect them to move instantly when a button is pressed, but physics dictates that
        # they should take a short time to accelerate.)
        node = BulletCharacterControllerNode(shape, 0.4, tag)
        node_path = self.render.attachNewNode(node)
        Thing.add(tag, node, node_path)
        self.world.attachCharacter(node)

        # Does this object represent the player who is using this client?
        if tag == self.__player_tag:
            # If yes, attach the camera to the object, so the player's view follows the object.
            self.camera.reparentTo(node_path)
        else:
            # If no, create a new Actor to represent the player or NPC.
            humanoid = Actor("player.bam")
            humanoid.setH(180)
            humanoid.reparentTo(node_path)

            # Scale the Actor so it is the same height as the bounding volume requested by the server.
            point1 = Point3()
            point2 = Point3()
            humanoid.calcTightBounds(point1, point2)
            humanoid.setScale(height / (point2.z - point1.z))

            # If the 3D model has the origin point at floor level, we need to move it down by half the height
            # of the bounding volume.  Otherwise it will hang in mid air, with its feet in the middle of the
            # bounding volume.
            humanoid.setZ(-height / 2)

    def server_removed_object(self, tag):
        thing = Thing.get_thing(tag)
        self.world.removeCharacter(thing.node)
        thing.node_path.removeNode()
        thing.remove()

    def server_moves_thing(self, tag, loc_x, loc_y, loc_z, speed_x, speed_y, speed_z, angle, angular_velocity):
        thing = Thing.get_thing(tag)
        thing.node_path.setPos(loc_x, loc_y, loc_z)
        thing.node.setLinearMovement(Vec3(speed_x, speed_y, speed_z), True)

        # I don't know why deg2Rad is required in the following line; I suspect it is a Panda bug.
        thing.node_path.setH(deg2Rad(angle))

        if angular_velocity != 0:
            self.__rotations[thing.node] = angular_velocity
        elif thing.node in self.__rotations:
            del self.__rotations[thing.node]
Ejemplo n.º 7
0
class FriendlyFruit(ShowBase, Scene):
    def __init__(self, server_connection, player_tag):
        ShowBase.__init__(self)
        self.__server_connection = server_connection
        self.__player_tag = player_tag
        self.__rotations = {}

        # Panda pollutes the global namespace.  Some of the extra globals can be referred to in nicer ways
        # (for example self.render instead of render).  The globalClock object, though, is only a global!  We
        # create a reference to it here, in a way that won't upset PyFlakes.
        self.globalClock = __builtins__["globalClock"]

        # Turn off the debugging system which allows the camera to be adjusted directly by the mouse.
        self.disableMouse()

        # Set up physics: the ground plane and the capsule which represents the player.
        self.world = BulletWorld()

        # The ground first:
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
        node = BulletRigidBodyNode("Ground")
        node.addShape(shape)
        np = self.render.attachNewNode(node)
        np.setPos(0, 0, 0)
        self.world.attachRigidBody(node)

        # Enable shader generation (for more sophisticated lighting etc.)
        self.render.setShaderAuto()

        # Create lights so we can see the scene.
        dlight = DirectionalLight("dlight")
        dlight.setColor(VBase4(2, 2, 2, 0))
        dlnp = self.render.attachNewNode(dlight)
        dlnp.setHpr(0, -60, 0)
        self.render.setLight(dlnp)

        alight = AmbientLight('alight')
        alight.setColor(VBase4(0.75, 0.75, 0.75, 0))
        alnp = self.render.attachNewNode(alight)
        self.render.setLight(alnp)

        # Create a task to update the scene regularly.
        self.taskMgr.add(self.update, "UpdateTask")

    # Update the scene by turning objects if necessary, and processing physics.
    def update(self, task):
        asyncore.loop(timeout=0.01, use_poll=True, count=1)

        for node, angular_velocity in self.__rotations.iteritems():
            node.setAngularMovement(angular_velocity)

        dt = self.globalClock.getDt()
        self.world.doPhysics(dt)
        return task.cont

    def server_created_object(self, tag, height, radius):
        # This shape is used for collision detection, preventing the player falling through the ground for
        # example.
        shape = BulletCapsuleShape(radius, height - 2 * radius, ZUp)

        # A character controller is a physical body which responds instantly to keyboard controls.  (Bodies
        # which respond to forces are difficult to control in a satisfactory way using typical video game
        # controls.  Players expect them to move instantly when a button is pressed, but physics dictates that
        # they should take a short time to accelerate.)
        node = BulletCharacterControllerNode(shape, 0.4, tag)
        node_path = self.render.attachNewNode(node)
        Thing.add(tag, node, node_path)
        self.world.attachCharacter(node)

        # Does this object represent the player who is using this client?
        if tag == self.__player_tag:
            # If yes, attach the camera to the object, so the player's view follows the object.
            self.camera.reparentTo(node_path)
        else:
            # If no, create a new Actor to represent the player or NPC.
            humanoid = Actor("player.bam")
            humanoid.setH(180)
            humanoid.reparentTo(node_path)

            # Scale the Actor so it is the same height as the bounding volume requested by the server.
            point1 = Point3()
            point2 = Point3()
            humanoid.calcTightBounds(point1, point2)
            humanoid.setScale(height / (point2.z - point1.z))

            # If the 3D model has the origin point at floor level, we need to move it down by half the height
            # of the bounding volume.  Otherwise it will hang in mid air, with its feet in the middle of the
            # bounding volume.
            humanoid.setZ(-height / 2)

    def server_removed_object(self, tag):
        thing = Thing.get_thing(tag)
        self.world.removeCharacter(thing.node)
        thing.node_path.removeNode()
        thing.remove()

    def server_moves_thing(self, tag, loc_x, loc_y, loc_z, speed_x, speed_y,
                           speed_z, angle, angular_velocity):
        thing = Thing.get_thing(tag)
        thing.node_path.setPos(loc_x, loc_y, loc_z)
        thing.node.setLinearMovement(Vec3(speed_x, speed_y, speed_z), True)

        # I don't know why deg2Rad is required in the following line; I suspect it is a Panda bug.
        thing.node_path.setH(deg2Rad(angle))

        if angular_velocity != 0:
            self.__rotations[thing.node] = angular_velocity
        elif thing.node in self.__rotations:
            del self.__rotations[thing.node]
Ejemplo n.º 8
0
    def __init__(self):

        # Notice that you must not call ShowBase.__init__ (or super), the
        # render pipeline does that for you. If this is unconvenient for you,
        # have a look at the other initialization possibilities.

        # Insert the pipeline path to the system path, this is required to be
        # able to import the pipeline classes. In case you placed the render
        # pipeline in a subfolder of your project, you have to adjust this.
        sys.path.insert(0, "../../")
        sys.path.insert(0, "../../RenderPipeline")

        # Import the main render pipeline class
        from rpcore import RenderPipeline, SpotLight
        world = BulletWorld()
        # Construct and create the pipeline
        self.render_pipeline = RenderPipeline()
        self.render_pipeline.create(self)
        from rpcore.util.movement_controller import MovementController
        self.render_pipeline.daytime_mgr.time = 0.769
        self.controller = MovementController(self)
        self.controller.set_initial_position(Vec3(6.6, -18.8, 4.5),
                                             Vec3(4.7, -16.7, 3.4))
        self.controller.setup()

        # Done! You can start setting up your application stuff as regular now.
        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-left": 0,
            "cam-right": 0
        }
        self.speed = 1.0
        base.win.setClearColor(Vec4(0, 0, 0, 1))

        #
        # vertex_format = GeomVertexFormat.get_v3n3()
        # vertex_data = GeomVertexData("triangle_data", vertex_format, Geom.UH_static)
        #
        # pos_writer = GeomVertexWriter(vertex_data,"vertex")
        # normal_writer = GeomVertexWriter(vertex_data,"normal")
        # normal = Vec3(0., -1., 0.)
        #
        # pos_writer.add_data3(-1., 0., -1.)
        # pos_writer.add_data3(1., 0., -1.)
        # pos_writer.add_data3(0., 0., 1.)
        #
        # for _ in range(3):
        #     normal_writer.add_data3(normal)
        #
        # prim = GeomTriangles(Geom.UH_static)
        # prim.add_vertices(0, 1, 2)
        #
        # geom = Geom(vertex_data)
        # geom.add_primitive(prim)
        # node = GeomNode("my_triangle")
        # node.add_geom(geom)
        # triangle = NodePath(node)
        # triangle.reparent_to(some_other_nodepath)
        # square1 = create_colored_rect(0, 0, 200, 200)
        # square2 = create_colored_rect(350, 100, 200, 200, (0, 0, 1, 1))
        # square3 = create_colored_rect(-640, -360, 200, 200, (0, 1, 0, 1))
        self.tr1 = create_triangle(0, 0, 0, 0, 200, 0, 0, 0, 200, (0, 1, 0, 1))
        self.tr2 = create_triangle(-500, 0, 0, -300, 200, 0, -300, 0, 200,
                                   (0, 1, 0, 1))
        radius = 60
        height = 40
        shape1 = BulletCylinderShape(radius, height, ZUp)
        shape2 = BulletCylinderShape(Vec3(radius, 0, 0.5 * height), ZUp)
        self.gnode = GeomNode('square')
        # gnode.addGeom(square1)
        # gnode.addGeom(square2)
        # gnode.addGeom(square3)
        height = 1.75
        radius = 0.4
        shape = BulletCapsuleShape(radius, height - 2 * radius, ZUp)
        self.gnode.addGeom(self.tr1)
        self.gnode.addGeom(self.tr2)
        playerNode = BulletCharacterControllerNode(shape, 0.4, 'Player')
        playerNP = self.render.attachNewNode(playerNode)
        playerNP.setPos(0, 0, 14)
        playerNP.setH(45)
        playerNP.setCollideMask(BitMask32.allOn())

        world.attachCharacter(playerNP.node())
        # self.tr1.setPos(400,400, 0)
        # self.render.attachNewNode(self.gnode)

        gnode2 = GeomNode('square2')
        textured_rect = create_textured_rect(-320, 0, 200, 280)
        gnode2.addGeom(textured_rect)

        texture = self.loader.loadTexture("assets/playte.png")
        ship = self.render.attachNewNode(gnode2)
        ship.setTransparency(TransparencyAttrib.MAlpha)
        ship.setTexture(texture)

        # self.ralph = Actor(tr1)

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        self.accept("escape", sys.exit)
        self.accept("a", self.setKey, ["left", 1])
        self.accept("d", self.setKey, ["right", 1])
        self.accept("w", self.setKey, ["forward", 1])
        self.accept("p", self.setKey, ["backward", 1])
        self.accept("arrow_left", self.setKey, ["cam-left", 1])
        self.accept("arrow_right", self.setKey, ["cam-right", 1])
        self.accept("a-up", self.setKey, ["left", 0])
        self.accept("d-up", self.setKey, ["right", 0])
        self.accept("w-up", self.setKey, ["forward", 0])
        self.accept("s-up", self.setKey, ["backward", 0])
        self.accept("arrow_left-up", self.setKey, ["cam-left", 0])
        self.accept("arrow_right-up", self.setKey, ["cam-right", 0])
        self.accept("=", self.adjustSpeed, [0.25])
        self.accept("+", self.adjustSpeed, [0.25])
        self.accept("-", self.adjustSpeed, [-0.25])

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera

        base.disableMouse()
        base.camera.setPos(5, 5, 0)
        base.camLens.setFov(80)
Ejemplo n.º 9
0
class Game(DirectObject):
    def __init__(self):
        #ShowBase.__init__(self)
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -20, 4)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(1, 1, -1))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        #self.accept('space', self.doJump)
        #self.accept('c', self.doCrouch)

        inputState.watchWithModifiers('forward', 'w')
        inputState.watchWithModifiers('left', 'a')
        inputState.watchWithModifiers('reverse', 's')
        inputState.watchWithModifiers('right', 'd')
        inputState.watchWithModifiers('turnLeft', 'q')
        inputState.watchWithModifiers('turnRight', 'e')

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    #def doJump(self):
    #  self.player.setMaxJumpHeight(5.0)
    #  self.player.setJumpSpeed(8.0)
    #  self.player.doJump()

    #def doCrouch(self):
    #  self.crouching = not self.crouching
    #  sz = self.crouching and 0.6 or 1.0

    #  self.playerNP2.setScale(Vec3(1, 1, sz))

    # ____TASK___

    def processInput(self, dt):
        speed = Vec3(0, 0, 0)
        omega = 0.0

        if inputState.isSet('forward'): speed.setY(2.0 * dt * 60.0)
        if inputState.isSet('reverse'): speed.setY(-2.0)
        if inputState.isSet('left'): speed.setX(-2.0)
        if inputState.isSet('right'): speed.setX(2.0)
        if inputState.isSet('turnLeft'): omega = 120.0
        if inputState.isSet('turnRight'): omega = -120.0

        self.player.setAngularMovement(omega)
        self.player.setLinearMovement(speed, True)

    def update(self, task):
        dt = globalClock.getDt()

        self.processInput(dt)
        self.world.doPhysics(dt, 4, 1. / 240.)
        self.updateCamera()

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def updateCamera(self):
        camvec = self.playerNP.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        self.camera.setZ(self.playerNP.getZ() + 2)
        self.camera.lookAt(self.playerNP)

    ###################################
    ############## SETUP ##############
    ###################################
    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        ####### MV
        self.environ = loader.loadModel("world/world")
        self.environ.reparentTo(render)

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

        #actor = Actor('world/world')
        mesh = BulletTriangleMesh()

        ###### create terrein colligion shape
        geomNodeCollection = self.environ.findAllMatches('**/+GeomNode')
        for nodePath in geomNodeCollection:  #.asList():
            geomNode = nodePath.node()
            print("here1")
            for i in range(geomNode.getNumGeoms()):
                geom = geomNode.getGeom(i)
                print("here2")
                print(geom)
                mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)
        shape.set_margin(0.0)

        #print(geomNodeCollection)

        #    for geom in actor.getGeomNode().get_geoms():
        #      mesh.addGeom(geom)
        #    shape = BulletTriangleMeshShape(mesh, dynamic=False)

        #img = PNMImage(Filename('models/elevation2.png'))
        #shape = BulletHeightfieldShape(img, 1.0, ZUp)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
        np.node().addShape(shape)
        np.setPos(0, 0, 0)  #-1)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Box
        shape = BulletBoxShape(Vec3(1.0, 3.0, 0.3))

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
        np.node().setMass(50.0)
        np.node().addShape(shape)
        np.setPos(3, 0, 7)
        np.setH(0)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Character

        h = 1.75
        w = 0.4
        shape = BulletCapsuleShape(w, h - 2 * w, ZUp)

        self.player = BulletCharacterControllerNode(
            shape, 0.4,
            'Player')  #MV was: BulletCharacterNode(shape, 0.4, 'Player')
        #self.player.setMass(20.0)
        self.player.setMaxSlope(70.0)
        self.player.setGravity(9.81)
        #self.player.setFrictionSlip(100.0)

        self.playerNP = self.worldNP.attachNewNode(self.player)
        #self.playerNP.setMass(20.0)
        self.playerNP.setPos(-2, 0, 10)
        self.playerNP.setH(-90)
        self.playerNP.setCollideMask(BitMask32.allOn())
        #self.playerNP.flattenLight()
        self.world.attachCharacter(self.player)

        self.ralph = Actor("ralph/ralph", {
            "run": "ralph/ralph-run",
            "walk": "ralph/ralph-walk"
        })
        self.ralph.reparentTo(render)
        self.ralph.setScale(0.3048)
        self.ralph.setPos(0, 0, -1)
        self.ralph.setH(180)
        self.ralph.reparentTo(self.playerNP)

        ## Camera
        self.camera = base.cam
        base.disableMouse()
        self.camera.setPos(self.playerNP.getX(), self.playerNP.getY() + 10, 2)
        self.camera.lookAt(self.playerNP)
Ejemplo n.º 10
0
class EccoGame(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        base.setBackgroundColor(0, 0, 0)
        game_title = "ECCO"
        titleN = TextNode('game-title')
        font = loader.loadFont("font/Caveman.ttf")
        titleN.setFont(font)
        titleN.setText(game_title)
        titleN.setTextColor(1, 1, 1, 1)
        titleN.setSlant(0.1)
        titleN.setShadow(0.05)
        titleN.setShadowColor(0, 0, 200, 1)
        titleN.setFrameColor(0, 0, 255, 1)
        titleN.setFrameLineWidth(5.0)
        textNodePath = self.aspect2d.attachNewNode(titleN)
        textNodePath.setPos(-0.4, 1.5, 0.5)
        textNodePath.setScale(0.2)

        self.level1Button = DirectButton(text=("Level 1"), scale=.1, pos=(0, 0, 0.2), command=self.level1)
        self.level2Button = DirectButton(text=("Level 2"), scale=.1, pos=(0, 0, 0), command=self.level2)


    def level1(self):
        titleNp = self.aspect2d.find('game-title')
        titleNp.removeNode()
        self.level1Button.destroy()
        self.level2Button.destroy()

        self.sizescale = 0.6
        self.setupWorld()
        self.setupSky()
        self.setupFloor()
        self.setupCharacter()

        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left key]: Turn Ecco Left")
        self.inst3 = addInstructions(0.85, "[Right key]: Turn Ecco Right")
        self.inst4 = addInstructions(0.80, "[Up key]: Jump Ecco")

        inputState.watchWithModifiers('esc', 'escape')
        inputState.watchWithModifiers('w', 'w')
        inputState.watchWithModifiers('arrow_left', 'arrow_left')
        inputState.watchWithModifiers('arrow_right', 'arrow_right')
        inputState.watchWithModifiers('pause', 'p')
        inputState.watchWithModifiers('space', 'space')
        inputState.watchWithModifiers('arrow_up', 'arrow_up')

        inputState.watchWithModifiers('cam-left', 'z')
        inputState.watchWithModifiers('cam-right', 'x')
        inputState.watchWithModifiers('cam-forward', 'c')
        inputState.watchWithModifiers('cam-backward', 'v')

        taskMgr.add(self.update, "update")

        # Game state variables
        self.isMoving = False

        # display framerate
        self.setFrameRateMeter(True)

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.characterNP.getX(), self.characterNP.getY() - 30, 4)
        self.setupSound()

        # coins variables
        self.coinsCollected = 0
        self.dictOfCoins = {}
        self.coins = []

        # Set up Coins as Collectables
        self.setupCoins()

        # Set up Obstacles
        self.setupObstacles()

        # Setup Level Display
        self.setupLevelDisplay()

        self.counter = 0

    def setupLevelDisplay(self):
        LEVEL_1 = "Level 1"
        levelDisplay(LEVEL_1)
        levelN = TextNode('level-display')
        levelN.setText(LEVEL_1)
        font = loader.loadFont("font/Caveman.ttf")
        levelN.setFont(font)
        levelN.setTextColor(1, 1, 1, 1)
        levelN.setSlant(0.1)
        levelN.setShadow(0.05)
        levelN.setShadowColor(255, 0, 0, 1)
        textNodePath = self.aspect2d.attachNewNode(levelN)
        textNodePath.setPos(-0.45, 0, 0)
        textNodePath.setScale(0.2)


    def update(self, task):
        dt = globalClock.getDt()
        self.pos = self.characterNP.getPos()
        self.counter = self.counter + 1
        if self.counter == 150:
            levelNp = self.aspect2d.find('level-display')
            levelNp.removeNode()
        self.setUpCamera()
        self.processInput(dt)
        self.processContacts()
        self.coinScoreDisplay()
        self.checkIfEccoDied()
        self.world.doPhysics(dt, 10, 1 / 230.0)
        return task.cont

    def setupWorld(self):
        # create bullet world
        self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug'))
        #self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

    def setupSky(self):

        self.milkyWayNp = render.attachNewNode('milkyway')
        self.milkyWay_2Np = render.attachNewNode('milkyway_2')
        self.marsNp = render.attachNewNode('mars')
        self.sunNp = render.attachNewNode('sun')

        # Load the model for the sky
        # self.sky = loader.loadModel("models/sky/solar_sky_sphere")
        self.sky = loader.loadModel("models/sky/solar_sky_sphere")
        # Load the texture for the sky.
        self.sky_tex = loader.loadTexture("models/sky/stars_1k_tex.jpg")
        # Set the sky texture to the sky model
        self.sky.setTexture(self.sky_tex, 1)
        # Parent the sky model to the render node so that the sky is rendered
        self.sky.reparentTo(self.render)
        # Scale the size of the sky.
        self.sky.setScale(15000)
        x = 0.005
        y = 1700.0
        z = 0.0
        self.sky.setPos(x, y, 0)

        # #milkyway 1
        self.milkyWay = loader.loadModel("models/sky/planet_sphere")
        self.milkWay_tex = loader.loadTexture("models/sky/milkyway_tex.jpg")
        self.milkyWay.setTexture(self.milkWay_tex, 1)
        self.milkyWay.reparentTo(self.milkyWayNp)
        self.milkyWay.setScale(200)
        self.milkyWay.setPos(x + 2000, y + 10000, z - 500)

        # milkyway 2
        self.milkyWay_2 = loader.loadModel("models/sky/planet_sphere")
        self.milkWay_2_tex = loader.loadTexture("models/sky/milkyway_2_tex.jpg")
        self.milkyWay_2.setTexture(self.milkWay_2_tex, 1)
        self.milkyWay_2.reparentTo(self.milkyWay_2Np)
        self.milkyWay_2.setScale(400)
        self.milkyWay_2.setPos(x - 3000, y + 10000, z + 500)

        # sun
        self.sun = loader.loadModel("models/sky/planet_sphere")
        self.sun_tex = loader.loadTexture("models/sky/sun_2_tex.jpg")
        self.sun.setTexture(self.sun_tex, 1)
        self.sun.reparentTo(self.sunNp)
        self.sun.setScale(600)
        self.sun.setPos(x + 1000, y + 10000, z + 1000)
        #
        # Load Mars
        self.mars = loader.loadModel("models/sky/planet_sphere")
        self.mars_tex = loader.loadTexture("models/sky/mars_1k_tex.jpg")
        self.mars.setTexture(self.mars_tex, 1)
        self.mars.reparentTo(self.marsNp)
        self.mars.setScale(200)
        self.mars.setPos(x + 3000, y + 10000, z + 500)

    def setupSound(self):
        # Set up sound
        mySound = base.loader.loadSfx("sounds/Farm Morning.ogg")
        mySound.play()
        mySound.setVolume(3.0)
        mySound.setLoop(True)
        footsteps = base.loader.loadSfx("sounds/Footsteps_on_Cement-Tim_Fryer.wav")
        footsteps.play()
        footsteps.setVolume(0.8)
        footsteps.setLoop(True)
        self.jumpSound = base.loader.loadSfx("sounds/Jump-SoundBible.com-1007297584.wav")
        self.jumpSound.setVolume(0.2)
        self.collectSound = base.loader.loadSfx("sounds/pin_dropping-Brian_Rocca-2084700791.wav")
        self.gameOverSound = base.loader.loadSfx("sounds/Bike Horn-SoundBible.com-602544869.wav")
        self.levelCompleteSound = base.loader.loadSfx("sounds/Ta Da-SoundBible.com-1884170640.wav")



    def setupFloor(self):
        size = Vec3(7.5, 3000, 1.81818)
        shape = BulletBoxShape(size * 0.55)
        # shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
        node = BulletRigidBodyNode('Box-Floor')
        node.addShape(shape)
        node.setMass(0)
        stairNP = self.render.attachNewNode(node)
        stairNP.setPos(0, 0, 0)
        stairNP.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(stairNP.node())

        modelNP = loader.loadModel('models/box.egg')
        modelNP.reparentTo(stairNP)
        modelNP.setPos(-size.x / 2.0, -size.y / 2.0, -size.z / 2.0)
        modelNP.setScale(size)


    def setupCharacter(self):
        # Character
        h = 1.75
        w = 0.4
        shape = BulletCapsuleShape(w, h - 2 * w, ZUp)
        self.character = BulletCharacterControllerNode(shape, 0.4, 'Player')
        self.character.setGravity(35)
        self.characterNP = self.render.attachNewNode(self.character)
        self.characterNP.setPos(0, 10, 5)
        self.characterNP.setCollideMask(BitMask32.allOn())
        self.world.attachCharacter(self.character)

        self.ecco = Actor('ralph-models/ralph.egg.pz', {
            'run': 'ralph-models/ralph-run.egg',
            'jump': 'ralph/ralph-run.egg',
            'damage': 'models/lack-damage.egg'})
        self.ecco.reparentTo(self.characterNP)
        self.ecco.setScale(0.7048)
        self.ecco.setH(180)

    def setUpCamera(self):
        # If the camera is too far from ecco, move it closer.
        # If the camera is too close to ecco, move it farther.
        camvec = self.characterNP.getPos() - self.camera.getPos()
        camvec.setZ(0.0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 40))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (35 - camdist))
            camdist = 5.0

    def processInput(self, dt):
        speed = Vec3(0, 0, 0)
        if inputState.isSet('esc'): sys.exit()
        if inputState.isSet('w'): speed.setY(35.0)
        if inputState.isSet('arrow_left'): speed.setX(-35.0)
        if inputState.isSet('arrow_right'): speed.setX(35.0)
        if inputState.isSet('space'):
            self.jump()
            self.jumpSound.play()
        if inputState.isSet('arrow_up'):
            self.jump()
            self.jumpSound.play()
        if inputState.isSet('cam-left'): self.camera.setX(self.camera, -20 * dt)
        if inputState.isSet('cam-right'): self.camera.setX(self.camera, +20 * dt)
        if inputState.isSet('cam-forward'): self.camera.setY(self.camera, -200 * dt)
        if inputState.isSet('cam-backward'): self.camera.setY(self.camera, +200 * dt)

        # Make Ecco run
        if self.isMoving is False:
            self.ecco.loop("run")
            self.isMoving = True

        if self.pos.getY() > 1450.0:
            speed.setY(0.0)
        else:
            speed.setY(40.0)

        self.character.setLinearMovement(speed, True)

    def jump(self):
        self.character.setMaxJumpHeight(3.0)
        self.character.setJumpSpeed(25.0)
        self.character.doJump()

    def setupCoins(self):
        # display coins = 0
        textN = TextNode('coin-score')
        textN.setText(str("Coins: " + str(self.coinsCollected)))
        textN.setSlant(0.1)
        textNodePath = self.aspect2d.attachNewNode(textN)
        textNodePath.setPos(0, 0.95, 0.9)
        textNodePath.setScale(0.08)
        randNum = random.sample(range(0, 1500, 200), 6)

        # coins
        for i in range(6):
            randX = random.uniform(-3.0, 3.2)
            randY = float(randNum[i])
            shape = BulletSphereShape(0.3)
            coinNode = BulletGhostNode('Coin-' + str(i))
            coinNode.addShape(shape)
            np = self.render.attachNewNode(coinNode)
            np.setCollideMask(BitMask32.allOff())
            np.setPos(randX, randY, 2)

            # Adding sphere model
            sphereNp = loader.loadModel('models/smiley.egg')
            sphereNp_tex = loader.loadTexture("models/sky/coin_2_tex.jpg")
            sphereNp.setTexture(sphereNp_tex, 1)
            sphereNp.reparentTo(np)
            sphereNp.setScale(0.45)
            sphereNp.hprInterval(2.5, Vec3(360, 0, 0)).loop()

            self.world.attachGhost(coinNode)
            self.coins.append(coinNode)
            print "node name:" + str(coinNode.getName())

    def processContacts(self):
        for coin in self.coins:
            self.testWithSingleBody(coin)

        self.coinsCollected = len(self.dictOfCoins)

    def testWithSingleBody(self, secondNode):
        contactResult = self.world.contactTestPair(self.character, secondNode)

        if contactResult.getNumContacts() > 0:
            self.collectSound.play()
            for contact in contactResult.getContacts():
                cp = contact.getManifoldPoint()
                node0 = contact.getNode0()
                node1 = contact.getNode1()
                self.dictOfCoins[node1.getName()] = 1
                np = self.render.find(node1.getName())
                np.node().removeAllChildren()
                self.world.removeGhost(np.node())

    def setupObstacles(self):
        # Obstacle
        origin = Point3(2, 0, 0)
        size = Vec3(2, 2.75, 1.5)
        shape = BulletBoxShape(size * 0.55)
        randNum1 = random.sample(range(0, 1500, 300), 3)
        randNum2 = random.sample(range(0, 1500, 500), 3)
        for i in range(2):
            randX = random.uniform(-3.5, 3.5)
            randY = float(randNum1[i])
            pos = origin + size * i
            ObstacleNP = self.render.attachNewNode(BulletRigidBodyNode('Obstacle%i' % i))
            ObstacleNP.node().addShape(shape)
            ObstacleNP.node().setMass(1.0)
            ObstacleNP.setPos(randX, randY, 3)
            ObstacleNP.setCollideMask(BitMask32.allOn())

            modelNP = loader.loadModel('models/box.egg')
            modelNP_tex = loader.loadTexture("models/sky/milkyway_tex.jpg")
            modelNP.setTexture(modelNP_tex, 1)
            modelNP.reparentTo(ObstacleNP)
            # modelNP.setPos(0, 0, 0)
            modelNP.setPos(-size.x / 2.0, -size.y / 2.0, -size.z / 2.0)
            modelNP.setScale(size)
            self.world.attachRigidBody(ObstacleNP.node())

        size_2 = Vec3(3, 2.75, 1.5)
        shape2 = BulletBoxShape(size_2 * 0.55)
        for i in range(2):
            randX = random.uniform(-3.5, 3.5)
            randY = float(randNum2[i])
            pos = origin + size_2 * i
            pos.setY(0)
            ObstacleNP = self.render.attachNewNode(BulletRigidBodyNode('ObstacleSmall%i' % i))
            ObstacleNP.node().addShape(shape2)
            ObstacleNP.node().setMass(1.0)
            ObstacleNP.setPos(randX, randY, 2)
            ObstacleNP.setCollideMask(BitMask32.allOn())

            modelNP = loader.loadModel('models/box.egg')
            modelNP_tex = loader.loadTexture("models/sky/moon_1k_tex.jpg")
            modelNP.setTexture(modelNP_tex, 1)
            modelNP.reparentTo(ObstacleNP)
            # modelNP.setPos(0, 0, 0)
            modelNP.setPos(-size_2.x / 2.0, -size_2.y / 2.0, -size_2.z / 2.0)
            modelNP.setScale(size_2)
            self.world.attachRigidBody(ObstacleNP.node())

    def checkIfEccoDied(self):
        print "position" + str(self.pos.getY())
        if self.pos.getZ() > -50.0 and self.pos.getZ() < 0.0:
            title = "Game Over"
            levelCompleteN = TextNode('ecco-died')
            font = loader.loadFont("font/Caveman.ttf")
            levelCompleteN.setFont(font)
            levelCompleteN.setText(title)
            levelCompleteN.setTextColor(1, 1, 1, 1)
            levelCompleteN.setSlant(0.1)
            levelCompleteN.setShadow(0.03)
            levelCompleteN.setShadowColor(0, 0, 200, 1)
            # levelN.setFrameAsMargin(0, 0, 0, 0)
            levelCompleteN.setFrameColor(200, 0, 0, 1)
            levelCompleteN.setFrameLineWidth(5.0)
            # textNp.node().setGlyphShift(1.0)
            textNodePath = self.aspect2d.attachNewNode(levelCompleteN)
            textNodePath.setPos(-0.9, 1.5, 0.5)
            textNodePath.setScale(0.2)
            if self.pos.getZ() < -49.0:
                self.gameOverSound.play()

        elif self.pos.getZ() < -50.0:
            if self.gameOverSound.status() != self.gameOverSound.PLAYING:
                sys.exit(1)

        elif self.pos.getY() > 1300.0:
            title = "Level 1 \n Complete"
            levelCompleteN = TextNode('level-complete')
            font = loader.loadFont("font/Caveman.ttf")
            levelCompleteN.setFont(font)
            levelCompleteN.setText(title)
            levelCompleteN.setTextColor(1, 1, 1, 1)
            levelCompleteN.setSlant(0.1)
            levelCompleteN.setShadow(0.03)
            levelCompleteN.setShadowColor(0, 0, 200, 1)
            # levelN.setFrameAsMargin(0, 0, 0, 0)
            levelCompleteN.setFrameColor(200, 0, 0, 1)
            levelCompleteN.setFrameLineWidth(5.0)
            # textNp.node().setGlyphShift(1.0)
            textNodePath = self.aspect2d.attachNewNode(levelCompleteN)
            textNodePath.setPos(-0.6, 1.5, 0.5)
            textNodePath.setScale(0.2)
            if self.levelCompleteSound.status() != self.levelCompleteSound.PLAYING:
                self.levelCompleteSound.play()
        else:
            pass


    def coinScoreDisplay(self):
        textNp = self.aspect2d.find('coin-score')
        textNp.node().clearText()
        textNp.node().setText(str("Coins: " + str(self.coinsCollected)))


    #Level 2
    def level2(self):
        titleNp2 = self.aspect2d.find('game-title')
        titleNp2.removeNode()
        self.level1Button.destroy()
        self.level2Button.destroy()

        self.sizescale2 = 0.6
        self.setupWorld2()
        self.setupSky2()
        self.setupFloor2()
        self.setupCharacter2()

        # self.title = addTitle(" ")
        self.inst12 = addInstructions(0.95, "[ESC]: Quit")
        self.inst22 = addInstructions(0.90, "[Left key]: Turn Ecco Left")
        self.inst32 = addInstructions(0.85, "[Right key]: Turn Ecco Right")
        self.inst42 = addInstructions(0.80, "[Up key]: Jump Ecco")

        inputState.watchWithModifiers('esc', 'escape')
        inputState.watchWithModifiers('w', 'w')
        inputState.watchWithModifiers('arrow_left', 'arrow_left')
        inputState.watchWithModifiers('arrow_right', 'arrow_right')
        inputState.watchWithModifiers('pause', 'p')
        inputState.watchWithModifiers('space', 'space')
        inputState.watchWithModifiers('arrow_up', 'arrow_up')

        inputState.watchWithModifiers('cam-left', 'z')
        inputState.watchWithModifiers('cam-right', 'x')
        inputState.watchWithModifiers('cam-forward', 'c')
        inputState.watchWithModifiers('cam-backward', 'v')

        taskMgr.add(self.update2, "update")

        # Game state variables
        self.isMoving2 = False


        # display framerate
        self.setFrameRateMeter(True)

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.characterNP2.getX(), self.characterNP2.getY() - 30, 4)
        self.setupSound2()

        # coins variables
        self.coinsCollected2 = 0
        self.dictOfCoins2 = {}
        self.coins2 = []

        # Set up Coins as Collectables
        self.setupCoins2()

        # Set up Floaters with coins
        self.setupFloaters2()

        # Set up Obstacles
        self.setupObstacles2()

        # Setup Level Display
        self.setupLevelDisplay2()

        self.counter2 = 0

    def setupLevelDisplay2(self):
        LEVEL_2 = "Level 2"
        levelDisplay(LEVEL_2)
        levelN = TextNode('level-display')
        levelN.setText(LEVEL_2)
        # www.webpagepublicity.com
        font = loader.loadFont("font/Caveman.ttf")
        levelN.setFont(font)
        levelN.setTextColor(1, 1, 1, 1)
        levelN.setSlant(0.1)
        levelN.setShadow(0.05)
        levelN.setShadowColor(255, 0, 0, 1)
        # levelN.setFrameAsMargin(0, 0, 0, 0)
        # levelN.setFrameColor(0, 0, 255, 1)
        # levelN.setFrameLineWidth(5.0)
        # # textNp.node().setGlyphShift(1.0)
        textNodePath = self.aspect2d.attachNewNode(levelN)
        textNodePath.setPos(-0.45, 0, 0)
        textNodePath.setScale(0.2)

    def update2(self, task):
        dt = globalClock.getDt()
        self.pos2 = self.characterNP2.getPos()
        self.counter2 = self.counter2 + 1
        if self.counter2 == 150:
            levelNp = self.aspect2d.find('level-display')
            levelNp.removeNode()
        self.setUpCamera2()
        self.processInput2(dt)
        self.processContacts2()
        self.coinScoreDisplay2()
        self.checkIfEccoDied2()
        self.world2.doPhysics(dt, 10, 1 / 230.0)
        return task.cont

    def setupWorld2(self):
        # create bullet world
        self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug'))
        #self.debugNP.show()

        self.world2 = BulletWorld()
        self.world2.setGravity(Vec3(0, 0, -9.81))
        self.world2.setDebugNode(self.debugNP.node())

    def setupSky2(self):

        self.milkyWayNp = render.attachNewNode('milkyway')
        self.milkyWay_2Np = render.attachNewNode('milkyway_2')
        self.marsNp = render.attachNewNode('mars')
        self.sunNp = render.attachNewNode('sun')

        # Load the model for the sky
        # self.sky = loader.loadModel("models/sky/solar_sky_sphere")
        self.sky = loader.loadModel("models/sky/solar_sky_sphere")
        # Load the texture for the sky.
        self.sky_tex = loader.loadTexture("models/sky/stars_1k_tex.jpg")
        # Set the sky texture to the sky model
        self.sky.setTexture(self.sky_tex, 1)
        # Parent the sky model to the render node so that the sky is rendered
        self.sky.reparentTo(self.render)
        # Scale the size of the sky.
        self.sky.setScale(15000)
        x = 0.005
        y = 1700.0
        z = 0.0
        self.sky.setPos(x, y, 0)

        # #milkyway 1
        self.milkyWay = loader.loadModel("models/sky/planet_sphere")
        self.milkWay_tex = loader.loadTexture("models/sky/milkyway_tex.jpg")
        self.milkyWay.setTexture(self.milkWay_tex, 1)
        self.milkyWay.reparentTo(self.milkyWayNp)
        self.milkyWay.setScale(200)
        self.milkyWay.setPos(x + 2000, y + 10000, z - 500)

        # milkyway 2
        self.milkyWay_2 = loader.loadModel("models/sky/planet_sphere")
        self.milkWay_2_tex = loader.loadTexture("models/sky/milkyway_2_tex.jpg")
        self.milkyWay_2.setTexture(self.milkWay_2_tex, 1)
        self.milkyWay_2.reparentTo(self.milkyWay_2Np)
        self.milkyWay_2.setScale(400)
        self.milkyWay_2.setPos(x - 3000, y + 10000, z + 500)

        # sun
        self.sun = loader.loadModel("models/sky/planet_sphere")
        self.sun_tex = loader.loadTexture("models/sky/sun_2_tex.jpg")
        self.sun.setTexture(self.sun_tex, 1)
        self.sun.reparentTo(self.sunNp)
        self.sun.setScale(600)
        self.sun.setPos(x + 1000, y + 10000, z + 1000)
        #
        # Load Mars
        self.mars = loader.loadModel("models/sky/planet_sphere")
        self.mars_tex = loader.loadTexture("models/sky/mars_1k_tex.jpg")
        self.mars.setTexture(self.mars_tex, 1)
        self.mars.reparentTo(self.marsNp)
        self.mars.setScale(200)
        self.mars.setPos(x + 3000, y + 10000, z + 500)

    def setUpCamera2(self):
        # If the camera is too far from ecco, move it closer.
        # If the camera is too close to ecco, move it farther.
        camvec = self.characterNP2.getPos() - self.camera.getPos()
        camvec.setZ(0.0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 40))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (35 - camdist))
            camdist = 5.0

    def setupSound2(self):
        # Set up sound
        mySound = base.loader.loadSfx("sounds/Farm Morning.ogg")
        mySound.play()
        mySound.setVolume(3.0)
        mySound.setLoop(True)
        footsteps = base.loader.loadSfx("sounds/Footsteps_on_Cement-Tim_Fryer.wav")
        footsteps.play()
        footsteps.setVolume(0.8)
        footsteps.setLoop(True)
        self.jumpSound2 = base.loader.loadSfx("sounds/Jump-SoundBible.com-1007297584.wav")
        self.jumpSound2.setVolume(0.2)
        self.collectSound2 = base.loader.loadSfx("sounds/pin_dropping-Brian_Rocca-2084700791.wav")
        self.gameOverSound2 = base.loader.loadSfx("sounds/Bike Horn-SoundBible.com-602544869.wav")
        self.levelCompleteSound2 = base.loader.loadSfx("sounds/Ta Da-SoundBible.com-1884170640.wav")

    def setupFloor2(self):
        size = Vec3(7.5, 3000, 1.81818)
        shape = BulletBoxShape(size * 0.55)
        # shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
        node = BulletRigidBodyNode('Box-Floor')
        node.addShape(shape)
        node.setMass(0)
        stairNP = self.render.attachNewNode(node)
        stairNP.setPos(0, 0, 0)
        stairNP.setCollideMask(BitMask32.allOn())
        self.world2.attachRigidBody(stairNP.node())

        modelNP = loader.loadModel('models/box.egg')
        modelNP.reparentTo(stairNP)
        modelNP.setPos(-size.x / 2.0, -size.y / 2.0, -size.z / 2.0)
        modelNP.setScale(size)


    def setupCharacter2(self):
        # Character
        h = 1.75
        w = 0.4
        shape = BulletCapsuleShape(w, h - 2 * w, ZUp)
        self.character2 = BulletCharacterControllerNode(shape, 0.4, 'Player')
        self.character2.setGravity(35)
        self.characterNP2 = self.render.attachNewNode(self.character2)
        self.characterNP2.setPos(0, 10, 5)
        self.characterNP2.setCollideMask(BitMask32.allOn())
        self.world2.attachCharacter(self.character2)

        self.ecco2 = Actor('ralph-models/ralph.egg.pz', {
            'run': 'ralph-models/ralph-run.egg',
            'jump': 'ralph/ralph-run.egg',
            'damage': 'models/lack-damage.egg'})
        self.ecco2.reparentTo(self.characterNP2)
        self.ecco2.setScale(0.7048)
        self.ecco2.setH(180)


    def processInput2(self, dt):
        speed = Vec3(0, 0, 0)
        if inputState.isSet('esc'): sys.exit()
        if inputState.isSet('w'): speed.setY(35.0)
        if inputState.isSet('arrow_left'): speed.setX(-35.0)
        if inputState.isSet('arrow_right'): speed.setX(35.0)
        if inputState.isSet('space'):
            self.jump2()
            self.jumpSound2.play()
        if inputState.isSet('arrow_up'):
            self.jump2()
            self.jumpSound2.play()
        if inputState.isSet('cam-left'): self.camera.setX(self.camera, -20 * dt)
        if inputState.isSet('cam-right'): self.camera.setX(self.camera, +20 * dt)
        if inputState.isSet('cam-forward'): self.camera.setY(self.camera, -200 * dt)
        if inputState.isSet('cam-backward'): self.camera.setY(self.camera, +200 * dt)

        # Make Ecco run
        if self.isMoving2 is False:
            self.ecco2.loop("run")
            self.isMoving2 = True

        if self.pos2.getY() > 1450.0:
            speed.setY(0.0)
        else:
            speed.setY(40.0)

        self.character2.setLinearMovement(speed, True)

    def jump2(self):
        self.character2.setMaxJumpHeight(3.0)
        self.character2.setJumpSpeed(25.0)
        self.character2.doJump()

    def setupCoins2(self):
        # display coins = 0
        textN = TextNode('coin-score')
        textN.setText(str("Coins: " + str(self.coinsCollected2)))
        textN.setSlant(0.1)
        textNodePath = self.aspect2d.attachNewNode(textN)
        textNodePath.setPos(0, 0.95, 0.9)
        textNodePath.setScale(0.08)
        randNum = random.sample(range(0, 1500, 200), 6)

        # coins
        for i in range(6):
            randX = random.uniform(-3.0, 3.2)
            randY = float(randNum[i])
            shape = BulletSphereShape(0.3)
            coinNode = BulletGhostNode('Coin-' + str(i))
            coinNode.addShape(shape)
            np = self.render.attachNewNode(coinNode)
            np.setCollideMask(BitMask32.allOff())
            np.setPos(randX, randY, 2)

            # Adding sphere model
            sphereNp = loader.loadModel('models/smiley.egg')
            sphereNp_tex = loader.loadTexture("models/sky/coin_2_tex.jpg")
            sphereNp.setTexture(sphereNp_tex, 1)
            sphereNp.reparentTo(np)
            sphereNp.setScale(0.45)
            sphereNp.hprInterval(2.5, Vec3(360, 0, 0)).loop()

            self.world2.attachGhost(coinNode)
            self.coins2.append(coinNode)
            print "node name:" + str(coinNode.getName())

    def setupObstacles2(self):
        # Obstacle
        origin = Point3(2, 0, 0)
        size = Vec3(2, 2.75, 1.5)
        shape = BulletBoxShape(size * 0.55)
        randNum1 = random.sample(range(0, 1500, 300), 3)
        randNum2 = random.sample(range(0, 1500, 500), 3)
        for i in range(2):
            randX = random.uniform(-3.5, 3.5)
            randY = float(randNum1[i])
            pos = origin + size * i
            ObstacleNP = self.render.attachNewNode(BulletRigidBodyNode('Obstacle%i' % i))
            ObstacleNP.node().addShape(shape)
            ObstacleNP.node().setMass(1.0)
            ObstacleNP.setPos(randX, randY, 3)
            ObstacleNP.setCollideMask(BitMask32.allOn())

            modelNP = loader.loadModel('models/box.egg')
            modelNP_tex = loader.loadTexture("models/sky/milkyway_tex.jpg")
            modelNP.setTexture(modelNP_tex, 1)
            modelNP.reparentTo(ObstacleNP)
            # modelNP.setPos(0, 0, 0)
            modelNP.setPos(-size.x / 2.0, -size.y / 2.0, -size.z / 2.0)
            modelNP.setScale(size)
            self.world2.attachRigidBody(ObstacleNP.node())

        size_2 = Vec3(3, 2.75, 1.5)
        shape2 = BulletBoxShape(size_2 * 0.55)
        for i in range(2):
            randX = random.uniform(-3.5, 3.5)
            randY = float(randNum2[i])
            pos = origin + size_2 * i
            pos.setY(0)
            ObstacleNP = self.render.attachNewNode(BulletRigidBodyNode('ObstacleSmall%i' % i))
            ObstacleNP.node().addShape(shape2)
            ObstacleNP.node().setMass(1.0)
            ObstacleNP.setPos(randX, randY, 2)
            ObstacleNP.setCollideMask(BitMask32.allOn())

            modelNP = loader.loadModel('models/box.egg')
            modelNP_tex = loader.loadTexture("models/sky/moon_1k_tex.jpg")
            modelNP.setTexture(modelNP_tex, 1)
            modelNP.reparentTo(ObstacleNP)
            # modelNP.setPos(0, 0, 0)
            modelNP.setPos(-size_2.x / 2.0, -size_2.y / 2.0, -size_2.z / 2.0)
            modelNP.setScale(size_2)
            self.world2.attachRigidBody(ObstacleNP.node())

    def setupFloaters2(self):
        size = Vec3(3.5, 5.5, 0.3)
        randNum = random.sample(range(10, 1500, 500), 3)
        for i in range(3):
            randX = random.randrange(-2, 3, 10)
            randY = float(randNum[i])
            # randY = random.randint(1000, 1500)
            shape = BulletBoxShape(size * 0.55)
            node = BulletRigidBodyNode('Floater')
            node.setMass(0)
            node.addShape(shape)
            np = self.render.attachNewNode(node)
            # np.setPos(9, 30, 3)
            np.setPos(randX, randY, 6)
            np.setR(0)
            self.world2.attachRigidBody(node)

            dummyNp = self.render.attachNewNode('milkyway')
            dummyNp.setPos(randX, randY, 6)

            modelNP = loader.loadModel('models/box.egg')
            modelNP_tex = loader.loadTexture("models/sky/moon_tex.jpg")
            modelNP.setTexture(modelNP_tex, 1)
            modelNP.reparentTo(dummyNp)
            modelNP.setPos(-1, 0, -1)
            modelNP.setPos(-size.x / 2.0, -size.y / 2.0, -size.z / 2.0)
            modelNP.setScale(size)
            dummyNp.hprInterval(2.5, Vec3(360, 0, 0)).loop()

            # Put A Coin On the Floater
            shape = BulletSphereShape(0.75)
            coinNode = BulletGhostNode('FloaterCoin-' + str(i))
            coinNode.addShape(shape)
            np = self.render.attachNewNode(coinNode)
            np.setCollideMask(BitMask32.allOff())
            # np.setPos(randX, randY, 2)
            np.setPos(randX, randY, 7.0)

            # Adding sphere model
            sphereNp = loader.loadModel('models/smiley.egg')
            sphereNp_tex = loader.loadTexture("models/sky/coin_2_tex.jpg")
            sphereNp.setTexture(sphereNp_tex, 1)
            sphereNp.reparentTo(np)
            sphereNp.setScale(0.85)
            sphereNp.hprInterval(1.5, Vec3(360, 0, 0)).loop()

            self.world2.attachGhost(coinNode)
            self.coins2.append(coinNode)
            print "node name:" + str(coinNode.getName())

    def processContacts2(self):
        for coin in self.coins2:
            self.testWithSingleBody2(coin)

        self.coinsCollected2 = len(self.dictOfCoins2)

    def testWithSingleBody2(self, secondNode):
        contactResult = self.world2.contactTestPair(self.character2, secondNode)

        if contactResult.getNumContacts() > 0:
            self.collectSound2.play()
            for contact in contactResult.getContacts():
                cp = contact.getManifoldPoint()
                node0 = contact.getNode0()
                node1 = contact.getNode1()
                self.dictOfCoins2[node1.getName()] = 1
                np = self.render.find(node1.getName())
                np.node().removeAllChildren()
                self.world2.removeGhost(np.node())


    def checkIfEccoDied2(self):
        print "position" + str(self.pos2.getY())
        if self.pos2.getZ() > -50.0 and self.pos2.getZ() < 0.0:
            title = "Game Over"
            levelCompleteN = TextNode('ecco-died')
            font = loader.loadFont("font/Caveman.ttf")
            levelCompleteN.setFont(font)
            levelCompleteN.setText(title)
            levelCompleteN.setTextColor(1, 1, 1, 1)
            levelCompleteN.setSlant(0.1)
            levelCompleteN.setShadow(0.03)
            levelCompleteN.setShadowColor(0, 0, 200, 1)
            # levelN.setFrameAsMargin(0, 0, 0, 0)
            levelCompleteN.setFrameColor(200, 0, 0, 1)
            levelCompleteN.setFrameLineWidth(5.0)
            # textNp.node().setGlyphShift(1.0)
            textNodePath = self.aspect2d.attachNewNode(levelCompleteN)
            textNodePath.setPos(-0.9, 1.5, 0.5)
            textNodePath.setScale(0.2)
            if self.pos2.getZ() < -49.0:
                self.gameOverSound2.play()

        elif self.pos2.getZ() < -50.0:
            if self.gameOverSound2.status() != self.gameOverSound2.PLAYING:
                sys.exit(1)
        elif self.pos2.getY() > 1300.0:
            title = "Level 2 \n Complete"
            levelCompleteN = TextNode('level-complete')
            font = loader.loadFont("font/Caveman.ttf")
            levelCompleteN.setFont(font)
            levelCompleteN.setText(title)
            levelCompleteN.setTextColor(1, 1, 1, 1)
            levelCompleteN.setSlant(0.1)
            levelCompleteN.setShadow(0.03)
            levelCompleteN.setShadowColor(0, 0, 200, 1)
            # levelN.setFrameAsMargin(0, 0, 0, 0)
            levelCompleteN.setFrameColor(200, 0, 0, 1)
            levelCompleteN.setFrameLineWidth(5.0)
            # textNp.node().setGlyphShift(1.0)
            textNodePath = self.aspect2d.attachNewNode(levelCompleteN)
            textNodePath.setPos(-0.6, 1.5, 0.5)
            textNodePath.setScale(0.2)
            if self.levelCompleteSound2.status() != self.levelCompleteSound2.PLAYING:
                self.levelCompleteSound2.play()
        else:
            pass

    def coinScoreDisplay2(self):
        textNp = self.aspect2d.find('coin-score')
        textNp.node().clearText()
        textNp.node().setText(str("Coins: " + str(self.coinsCollected2)))
Ejemplo n.º 11
0
class CharacterController(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.setupLights()
        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f3', self.toggleDebug)
        self.accept('space', self.doJump)
	self.accept("q", self.setKey, ["cam-left", True])
	self.accept("e", self.setKey, ["cam-right", True])
	self.accept("q-up", self.setKey, ["cam-left", False])
	self.accept("e-up", self.setKey, ["cam-right", False])

        inputState.watchWithModifiers('forward', 'w')
        inputState.watchWithModifiers('reverse', 's')
        inputState.watchWithModifiers('turnLeft', 'a')
        inputState.watchWithModifiers('turnRight', 'd')

        # Task
        taskMgr.add(self.update, 'updateWorld')

        self.setup()
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)
        base.disableMouse()
        base.camera.setPos(self.characterNP.getPos()+4)
        base.camera.setHpr(self.characterNP.getHpr())
        base.camera.lookAt(self.characterNP)
        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)
		
		# Game state variables
        self.isMoving = False
	self.tokensCount = 0
	self.lifeCount = 2
	# OnscreenText object to show Start and Finish game
	self.textObject = OnscreenText(text = 'Lets Go!!!', pos = (0, 0), scale = 0.1)
	
	# Post the instructions
	self.title = addTitle("TIME: 00:00")
	self.inst1 = addInstructions(0.06, "LIFE: "+ str(self.lifeCount))
	self.inst2 = addInstructions(0.12, "TOKEN: "+ str(self.tokensCount))
	
	self.startTime = globalClock.getFrameTime()

	# This is used to store which keys are currently pressed.
	self.keyMap = {"cam-left": 0, "cam-right": 0}
	
	# Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value	
	
    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doJump(self):
		self.character.setMaxJumpHeight(5.0)
		self.character.setJumpSpeed(8.0)
		self.character.doJump()
		self.actorNP.pose("jump", 2)

    def processInput(self, dt):
        speed = Vec3(0, 0, 0)
        omega = 0.0

        if inputState.isSet('forward'): speed.setY( 3.0)
        if inputState.isSet('reverse'): speed.setY(-3.0)
        if inputState.isSet('left'):    speed.setX(-3.0)
        if inputState.isSet('right'):   speed.setX( 3.0)
        if inputState.isSet('turnLeft'):  omega =  120.0
        if inputState.isSet('turnRight'): omega = -120.0
		
	if (inputState.isSet('forward')!=0) or (inputState.isSet('reverse')!=0) or (inputState.isSet('left')!=0) or (inputState.isSet('right')!=0):
            if self.isMoving is False:
                self.actorNP.loop("walk")
                self.isMoving = True
        else:
            if self.isMoving:
                self.actorNP.stop()
                self.isMoving = False


        self.character.setAngularMovement(omega)
        self.character.setLinearMovement(speed, True)

    def update(self, task):
        dt = globalClock.getDt()
        self.processInput(dt)
        self.world.doPhysics(dt, 4, 1./240.)
		
	if self.keyMap["cam-left"]:
		base.camera.setX(base.camera, -20 * dt)
	if self.keyMap["cam-right"]:
		base.camera.setX(base.camera, +20 * dt)
		
	# Game timer
	nowTime = globalClock.getFrameTime() - self.startTime
	self.gameTimer = int(60-round( nowTime ))
	if int(round( nowTime )) == 2:
		self.textObject.setText("")
	self.title.setText("TIME: "+str (self.gameTimer))
        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.
        camvec = self.characterNP.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 10.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-10))
            camdist = 10.0
        if (camdist < 5.0):
            base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
            camdist = 5.0

        self.floater.setPos(self.characterNP.getPos())
        self.floater.setZ(self.characterNP.getZ() + 2.0)
        base.camera.lookAt(self.floater)
	
	# Game end conditions
	if self.lifeCount == 0 or self.gameTimer == 0:
		self.textObject.setText("YOU LOSE!!!")
		self.actorNP.pose("die", 2)
	
	# Game Completion
	distanceToGoal =  self.panda.getPos() - self.characterNP.getPos()
	if distanceToGoal.length() < 1:
		self.panda.loop("walk")
		self.textObject.setText("GAMEOVER!")
		
	
	# If Character fell logic
	if self.characterNP.getZ() < 1:
		print str(self.characterNP.getZ())
		self.lifeCount = self.lifeCount - 1
		self.tokensCount = 0
		self.inst2.setText("TOKEN: "+ str(self.tokensCount))
		self.inst1.setText("LIFE: "+ str(self.lifeCount))
		self.actorNP.pose("die", 2)
		self.characterNP.setPos(0, 0, 10)
	
	# Collecting tokens logic
	for token in render.findAllMatches("**/=token"):
		distance =  token.getPos() - self.characterNP.getPos()
		if (distance.length() < 1.0):
				self.tokensCount = self.tokensCount + 1
				self.inst2.setText("TOKEN: "+ str(self.tokensCount))
				if self.tokensCount == 3:
					self.lifeCount = self.lifeCount + 1
					self.tokensCount = 0
					self.inst2.setText("TOKEN: "+ str(self.tokensCount))
					self.inst1.setText("LIFE: "+ str(self.lifeCount))
				print "Reached Token with distance: " + str(distance) + " COUNT: " + str(self.tokensCount) + " LIFE: " + str(self.lifeCount)
				token.removeNode()
				

        return task.cont

    def cleanup(self):
        self.world = None
        self.render.removeNode()

    def setupLights(self):
        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(1, 1, -1))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        self.render.clearLight()
        self.render.setLight(alightNP)
        self.render.setLight(dlightNP)

    def setup(self):

        # World
        self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.hide()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Floor
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
        floorNP = self.render.attachNewNode(BulletRigidBodyNode('Floor'))
        floorNP.node().addShape(shape)
        floorNP.setPos(0, 0, 0)
        floorNP.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(floorNP.node())
	self.environ = loader.loadModel('models/environment')
	self.environ.reparentTo(floorNP)

	# Stair
	origin = Point3(2, 0, 0)
	size = Vec3(4, 4.75, 0.5)
	shape = BulletBoxShape(size * 0.55)
	for i in range(15):
		
		pos = origin*i + size * i
		pos.setY(0)
		pos.setZ(4)
		stairNP = self.render.attachNewNode(BulletRigidBodyNode('Stair%i' % i))
		stairNP.node().addShape(shape)
		stairNP.setPos(pos)
		stairNP.setCollideMask(BitMask32.allOn())
			
		if i > 0 and i != 14:
			if i%2 != 0:
				# Rotating stairs
				StairHprInterval1 = stairNP.hprInterval(2, Point3(0, 0, 0),startHpr=Point3(0, 0, 0))
				StairHprInterval2 = stairNP.hprInterval(2, Point3(0, 0, 0),startHpr=Point3(360, 0, 0))
				self.StairPace1 = Sequence(StairHprInterval1,StairHprInterval2)
				self.StairPace1.loop()
				
			if i%2 == 0 and i%3 != 0:
				# Up-down motion stairs
				StairsPosInterval1 = stairNP.posInterval(3, Point3(pos.getX(),pos.getY(),pos.getZ()-2),startPos=Point3(pos.getX(),pos.getY(),pos.getZ()+2))
				StairsPosInterval2 = stairNP.posInterval(3, Point3(pos.getX(),pos.getY(),pos.getZ()+2),startPos=Point3(pos.getX(),pos.getY(),pos.getZ()-2))
				self.StairPace2 = Sequence(StairsPosInterval1,StairsPosInterval2)
				self.StairPace2.loop()
			
			if i%2 == 0 and i%3 == 0:
				# Side to side motion stairs
				StairsPosInterval1 = stairNP.posInterval(3, Point3(pos.getX(),pos.getY()-4,pos.getZ()),startPos=Point3(pos.getX(),pos.getY()+4,pos.getZ()))
				StairsPosInterval2 = stairNP.posInterval(3, Point3(pos.getX(),pos.getY()+4,pos.getZ()),startPos=Point3(pos.getX(),pos.getY()-4,pos.getZ()))
				self.StairPace2 = Sequence(StairsPosInterval1,StairsPosInterval2)
				self.StairPace2.loop()

		modelNP = loader.loadModel('models/stone-cube/stone.egg')
		modelNP.reparentTo(stairNP)
		modelNP.setPos(0, 0, 0)
		modelNP.setScale(size)
		
		self.world.attachRigidBody(stairNP.node())
		
		# panda character
		if i == 14:
			self.panda = Actor("models/panda-model", {"walk": "models/panda-walk4"})
			self.panda.reparentTo(render)
			self.panda.setScale(0.002, 0.002, 0.002)
			self.panda.setPos(pos.getX(),pos.getY(),pos.getZ()+0.5)
		
		if i%2 != 0:
			TokenModel = self.loader.loadModel('models/smiley')
			TokenModel.reparentTo(self.render)
			
			TokenModel.setPos(pos.getX(),pos.getY(),pos.getZ()+1)
			TokenModel.setScale(0.6)
			TokenModel.setTag("token",str(i))
		
        # Character
        h = 1.75
        w = 0.4
        shape = BulletCapsuleShape(w, h - 2 * w, ZUp)

        self.character = BulletCharacterControllerNode(shape, 0.4, 'Player')
        #self.character.setMass(1.0)
        self.characterNP = self.render.attachNewNode(self.character)
        self.characterNP.setPos(0, 0, 14)
        self.characterNP.setH(45)
        self.characterNP.setCollideMask(BitMask32.allOn())
        self.world.attachCharacter(self.character)
		# Special thanks to the creator of LEGO Characters "Lewis Chen"
        self.actorNP = Actor('models/Voltage/Voltage.egg', {
						 'die'	: 'models/Voltage/Voltage-FallbackGetup.egg',
                         'walk' : 'models/Voltage/Voltage-walk.egg',
                         'jump' : 'models/Voltage/Voltage-jump.egg'})

        self.actorNP.reparentTo(self.characterNP)
        self.actorNP.setScale(0.3048)
        self.actorNP.setH(180)
        self.actorNP.setPos(0, 0, 0.35)