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])
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)
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
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)
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
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]
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]
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)
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)
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)))
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)