def __init__(self, world:BulletWorld, entity:Entity, shape, name, rotation): super().__init__(name) self.addShape(shape) self.np = application.base.render.attachNewNode(self) world.attachGhost(self) if entity.parent: self.np.reparent_to(entity.parent) if None in rotation: hpr = entity.getHpr() for x in range(len(hpr)): rotation[x] = hpr[x] self.np.setHpr(Vec3(*rotation)) self.np.setPos(entity.x, entity.y, entity.z) entity.reparent_to(self.np)
class GameScene(ShowBase): def __init__(self): ShowBase.__init__(self) self.level = 1 # self.setupScene() def getPhycisWorld(self): return self.world def setupScene(self): # Set Scene Background Color base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) # TODO: remove this Add Camera self.cameraHeight = DEFAULT_CAMERA_HEIGHT # Add Physics to GameScene self.addPhysicsWorld() # Add lightings to GameScene self.addLights() # Load Game Map self.loadMap() # Add Character self.addCharacters() # Add Sound Effects self.addSoundEffects() def addCharacters(self): self.addPlayer() self.addShield() self.addGuard() def addSoundEffects(self): self.completeLevelSound = base.loader.loadSfx( "sounds/completeLevel.mp3") self.deadthSound = base.loader.loadSfx("sounds/dead.wav") # self.completeLevelSound.setVolume(5) # self.completeLevelSound.play() self.hitSound = base.loader.loadSfx("sounds/hit.mp3") self.pushSound = base.loader.loadSfx("sounds/push.wav") self.jumpSound = base.loader.loadSfx("sounds/Jump.wav") self.pickupSpringSound = base.loader.loadSfx( "sounds/Pickup_Spring.wav") self.backgroundSound = base.loader.loadSfx("sounds/background.mp3") self.backgroundSound.setVolume(0.5) self.backgroundSound.setLoop(True) self.backgroundSound.play() # ========== Functions setting up GameScene def loadMap(self): self.addSky() self.addGround() self.addWalls() self.addStages() self.addSpings() def addPhysicsWorld(self): # Create Physics World self.world = BulletWorld() # Add Gravity towards ground self.world.setGravity(Vec3(0, 0, -9.81)) def addLights(self): # Add Lights 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 addSky(self): self.blue_sky_sphere = self.loader.loadModel( "models/blue_sky_sphere/blue_sky_sphere.egg") self.blue_sky_sphere.reparentTo(self.render) self.blue_sky_sphere.setScale(0.04, 0.04, 0.04) self.blue_sky_sphere.setPos(0, 0, 0) def addGround(self): self.garden = self.loader.loadModel( "models/garden/garden.egg") self.garden.reparentTo(self.render) self.garden.setScale(2, 2, 2) self.garden.setPos(0, 0, 0) shape = BulletPlaneShape(Vec3(0, 0, 1), 0) floorNP = self.render.attachNewNode(BulletRigidBodyNode('Ground')) floorNP.node().addShape(shape) floorNP.setPos(0, 0, 0) floorNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(floorNP.node()) def addWalls(self): def addWall(size, posX, posY): shape = BulletBoxShape(size) wallNP = self.render.attachNewNode(BulletRigidBodyNode('wall')) wallNP.node().addShape(shape) wallNP.setPos(posX, posY, size.getZ()) wallNP.setCollideMask(BitMask32.allOn()) if (posY is 0): left = -(size.getY()) right = -left pos = left - 5 while pos <= right: wallModel = loader.loadModel('models/fence.egg') wallModel.reparentTo(wallNP) wallModel.setPos(0, pos, -(size.getZ())) wallModel.setScale(1, 1, 1) wallModel.setH(90) pos += 13.5 else: left = -(size.getX()) right = -left pos = left - 5 while pos <= right: wallModel = loader.loadModel('models/fence.egg') wallModel.reparentTo(wallNP) wallModel.setPos(pos, 0, -(size.getZ())) wallModel.setScale(1, 1, 1) pos += 13.5 self.world.attachRigidBody(wallNP.node()) addWall(Vec3(1, 90, 5), 80, 0) addWall(Vec3(1, 90, 5), -80, 0) addWall(Vec3(100, 1, 5), 0, 100) addWall(Vec3(100, 1, 5), 0, -100) def addStages(self): for stage in STAGE_POS_LIST: boxSize = stage[0] pos = stage[1] name = stage[2] # create a BodyNode and attach to render become a NodePath objNP = self.render.attachNewNode(BulletRigidBodyNode(name)) # attach the BodyNode inside the NodePath to physics world self.world.attachRigidBody(objNP.node()) # set the properties of the NodePath # - shape shape = BulletBoxShape(boxSize) objNP.node().addShape(shape) # - position objNP.setPos(pos.getX(), pos.getY(), pos.getZ()) # - collideMask objNP.setCollideMask(BitMask32.allOn()) # - model objModel = self.loader.loadModel( "models/brick-cube/brick.egg") objModel.setScale(boxSize.getX() * 2, boxSize.getY() * 2, boxSize.getZ() * 2) objModel.setPos(0, 0, boxSize.getZ() / -1) objModel.reparentTo(objNP) # - texture ts = TextureStage.getDefault() texture = objModel.getTexture() objModel.setTexOffset(ts, -0.5, -0.5) objModel.setTexScale(ts, boxSize.getX() / 2.0, boxSize.getY() / 2.0, boxSize.getZ() / 2.0) def addSpings(self): self.springs = [] for pos in SPRING_LIST: print "add spring #{} at: {}".format(len(self.springs), pos) shape = BulletBoxShape(Vec3(0.3, 0.3, 0.8)) node = BulletGhostNode('Spring' + str(len(self.springs))) node.addShape(shape) springNP = self.render.attachNewNode(node) springNP.setCollideMask(BitMask32.allOff()) springNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 3.4) modelNP = loader.loadModel('models/spring/spring.egg') modelNP.reparentTo(springNP) modelNP.setScale(1, 1, 1) modelNP.setPos(0, 0, -1) self.world.attachGhost(node) self.springs.append(springNP) # ========== Functions add Characters into GameScene def addPlayer(self): self.player = Player(self.world, self.render, "Bricker", PLAYER_POSITIONS[self.level]) def addShield(self): counter = 0 self.shields = [] for position in SHIELD_POSITIONS: shield = Shield(self.world, self.render, "Shield_{}".format(counter), position) counter+=1 self.shields.append(shield) def addGuard(self): counter = 0 self.guards = [] for position in GUARD_POSITIONS: guard = Guard(self.world, self.render, "Guard_{}".format(counter), position) counter+=1 self.guards.append(guard)
class PhysicsManager(object): num_rigidBodies = 0 num_ghosts = 0 def __init__(self, gravity=(0,0,-9.81) ): self.world = BulletWorld() self.world.setGravity(Vec3(gravity) ) self.addShape = {} self.addShape['plane'] = self.__addPlane self.addShape['sphere'] = self.__addSphere self.addShape['box'] = self.__addBox self.addShape['cylinder'] = self.__addCylinder self.addShape['capsule'] = self.__addCapsule self.addShape['cone'] = self.__addCone self.addShape['hull'] = self.__addConvexHull self.addShape['trimesh'] = self.__addTriangleMesh #self.composer = Composer() self.addShape['compound'] = self.__addCompound # self.shapesList = self.addShape.keys() def getRigidBodyDefaultProps(self): props = {} props['mass'] = .0 props['friction'] = .5 props['restitution'] = .0 props['adamping'] = .0 props['ldamping'] = .0 props['asleep'] = .08 props['lsleep'] = 1. props['deactivation'] = True props['kinematic'] = False return props def getRigidBody(self, name=None): PhysicsManager.num_rigidBodies+=1 return BulletRigidBodyNode(name or 'rigidbody'+str(PhysicsManager.num_rigidBodies) ) def createRigidBody(self, shapetype, model, props={}, name=None): body = self.getRigidBody(name) self.addShape[shapetype](body, model) props = dict(self.getRigidBodyDefaultProps().items() + props.items() ) self.setBodyProps(body, props) self.world.attachRigidBody( body ) return body def getGhost(self, name=None): PhysicsManager.num_ghosts+=1 return BulletGhostNode(name or 'ghost'+str(PhysicsManager.num_ghosts) ) def createGhost(self, shapetype, size, name=None): ghost = self.getGhost(name) self.addShape[shapetype](ghost, size) self.world.attachGhost(ghost) return ghost def attachRigidBody(self, body, props): self.setBodyProps(body, props) self.world.attachRigidBody(body) def __addCompound(self, body, model): self.createCompound(model,body) def __addSphere(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): size = self.getSize(model) shape = BulletSphereShape( max(size)/2 ) body.addShape(shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addBox(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): size = self.getSize(model) shape = BulletBoxShape( size/2 ) body.addShape(shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addCylinder(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): size = self.getSize(model) shape = BulletCylinderShape(max(size.x,size.y)/2, size.z, ZUp) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addCapsule(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): size = self.getSize(model) diam = max(size.x,size.y) shape = BulletCapsuleShape(diam/2, size.z-diam, ZUp) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addCone(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): size = self.getSize(model) shape = BulletConeShape(max(size.x,size.y)/2, size.z, ZUp) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addConvexHull(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): def one(): geom = model.node().getGeom(0) shape = BulletConvexHullShape() shape.addGeom(geom) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) return [] children = model.findAllMatches('**/+GeomNode') or one() model.flattenLight() for piece in children: shape = BulletConvexHullShape() geom = piece.node().getGeom(0) shape.addGeom(geom) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addTriangleMesh(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1), dynamic=True): mesh = BulletTriangleMesh() def one(): geom = model.node().getGeom(0) mesh.addGeom(geom) return [] children = model.findAllMatches('**/+GeomNode') or one() model.flattenLight() for piece in children: geom = piece.node().getGeom(0) mesh.addGeom(geom) shape = BulletTriangleMeshShape(mesh, dynamic=dynamic ) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addPlane(self, body, size=(0,0,1), pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletPlaneShape(Vec3(size), 0) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def setBodyProps(self, body, props): body.setMass( props['mass'] ) body.setFriction( props['friction'] ) body.setRestitution( props['restitution'] ) body.setAngularDamping( props['adamping'] ) body.setLinearDamping( props['ldamping'] ) body.setAngularSleepThreshold( props['asleep'] ) body.setLinearSleepThreshold( props['lsleep'] ) if not props['deactivation']: body.setDeactivationEnabled( False ) body.setKinematic( props['kinematic'] ) def characterController(self, name, height, mass, radius, step_height): shape = BulletCapsuleShape(radius, height - 2*radius, ZUp) body = BulletRigidBodyNode(name) body.setMass(mass) body.addShape(shape) return BulletCharacterControllerNode(shape, step_height, name) def debug(self): from panda3d.bullet import BulletDebugNode debugNP = render.attachNewNode(BulletDebugNode('Debug') ) #debugNP.show() debugNP.node().showWireframe(True) debugNP.node().showConstraints(True) debugNP.node().showBoundingBoxes(False) debugNP.node().showNormals(False) self.world.setDebugNode(debugNP.node()) return debugNP def getSize(self,model): hpr = model.getHpr() model.setHpr(0,0,0) minLimit, maxLimit = model.getTightBounds() model.setHpr(hpr) return maxLimit - minLimit def setShape(self, model, body): #To Re-Do name = model.getName() pos,hpr,scale = model.getPos(), model.getHpr(), model.getScale() shapetype = re.findall("[-a-z]+",name.lower())[0].split('-') shapetype = filter(None,shapetype) if shapetype[0] in self.addShape.keys(): self.addShape[shapetype[0]](body,model,pos,hpr,scale) not '-' in name or model.remove() def createCompound(self, model, body): children = model.find('**/*').getChildren() or model.getChildren() [self.setShape(child,body) for child in children]
class MyApp(ShowBase): def __init__(self, screen_size=84, DEBUGGING=False): ShowBase.__init__(self) self.render_stuff = True self.actions = 3 self.render.setShaderAuto() self.cam.setPos(0, 0, 7) self.cam.lookAt(0, 0, 0) wp = WindowProperties() window_size = screen_size wp.setSize(window_size, window_size) self.win.requestProperties(wp) # Create Ambient Light self.ambientLight = AmbientLight('ambientLight') self.ambientLight.setColor((0.2, 0.2, 0.2, 1)) self.ambientLightNP = self.render.attachNewNode(self.ambientLight) self.render.setLight(self.ambientLightNP) # Spotlight self.light = Spotlight('light') self.light.setColor((0.9, 0.9, 0.9, 1)) self.lightNP = self.render.attachNewNode(self.light) self.lightNP.setPos(0, 10, 10) self.lightNP.lookAt(0, 0, 0) self.lightNP.node().getLens().setFov(40) self.lightNP.node().getLens().setNearFar(10, 100) self.lightNP.node().setShadowCaster(True, 1024, 1024) self.render.setLight(self.lightNP) self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) if DEBUGGING is True: debugNode = BulletDebugNode('Debug') debugNode.showWireframe(True) debugNode.showConstraints(True) debugNode.showBoundingBoxes(False) debugNode.showNormals(False) debugNP = render.attachNewNode(debugNode) debugNP.show() self.world.setDebugNode(debugNP.node()) # Reward zone self.rzone_shape = BulletBoxShape(Vec3(.8, 1, 0.5)) self.rzone_ghost = BulletGhostNode('Reward Zone') self.rzone_ghost.addShape(self.rzone_shape) self.rzone_ghostNP = self.render.attachNewNode(self.rzone_ghost) self.rzone_ghostNP.setPos(2.2, 0.0, 0.86) self.rzone_ghostNP.setCollideMask(BitMask32(0x0f)) self.world.attachGhost(self.rzone_ghost) # Needed for camera image self.dr = self.camNode.getDisplayRegion(0) # Needed for camera depth image winprops = WindowProperties.size(self.win.getXSize(), self.win.getYSize()) fbprops = FrameBufferProperties() fbprops.setDepthBits(1) self.depthBuffer = self.graphicsEngine.makeOutput( self.pipe, "depth buffer", -2, fbprops, winprops, GraphicsPipe.BFRefuseWindow, self.win.getGsg(), self.win) self.depthTex = Texture() self.depthTex.setFormat(Texture.FDepthComponent) self.depthBuffer.addRenderTexture(self.depthTex, GraphicsOutput.RTMCopyRam, GraphicsOutput.RTPDepth) lens = self.cam.node().getLens() # the near and far clipping distances can be changed if desired # lens.setNear(5.0) # lens.setFar(500.0) self.depthCam = self.makeCamera(self.depthBuffer, lens=lens, scene=render) self.depthCam.reparentTo(self.cam) def reset(self): namelist = [ 'Ground', 'Conveyor', 'Finger', 'Block', 'Scrambled Block', 'Not Rewardable', 'Teleport Me' ] for child in render.getChildren(): for test in namelist: if child.node().name == test: self.world.remove(child.node()) child.removeNode() break # Plane self.plane_shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.plane_node = BulletRigidBodyNode('Ground') self.plane_node.addShape(self.plane_shape) self.plane_np = self.render.attachNewNode(self.plane_node) self.plane_np.setPos(0.0, 0.0, -1.0) self.world.attachRigidBody(self.plane_node) # Conveyor self.conv_node = BulletRigidBodyNode('Conveyor') self.conv_node.setFriction(1.0) self.conv_np = self.render.attachNewNode(self.conv_node) self.conv_shape = BulletBoxShape(Vec3(100.0, 1.0, 0.05)) self.conv_node.setMass(1000.0) self.conv_np.setPos(-95.0, 0.0, 0.1) self.conv_node.addShape(self.conv_shape) self.world.attachRigidBody(self.conv_node) self.model = loader.loadModel('assets/conv.egg') self.model.flattenLight() self.model.reparentTo(self.conv_np) # Finger self.finger_node = BulletRigidBodyNode('Finger') self.finger_node.setFriction(1.0) self.finger_np = self.render.attachNewNode(self.finger_node) self.finger_shape = BulletCylinderShape(0.1, 0.25, ZUp) self.finger_node.setMass(0) self.finger_np.setPos(1.8, 0.0, 0.24 + 0.0254 * 3.5) self.finger_node.addShape(self.finger_shape) self.world.attachRigidBody(self.finger_node) self.model = loader.loadModel('assets/finger.egg') self.model.flattenLight() self.model.reparentTo(self.finger_np) self.blocks = [] for block_num in range(15): new_block = self.spawn_block(Vec3(18, 0, (0.2 * block_num) + 2.0)) self.blocks.append(new_block) self.have_scramble = False self.penalty_applied = False self.spawnned = False self.score = 10 self.teleport_cooled_down = True self.fps = 20 self.framecount = 0 return self.step(1)[0] def spawn_block(self, location): node = BulletRigidBodyNode('Block') node.setFriction(1.0) block_np = self.render.attachNewNode(node) block_np.setAntialias(AntialiasAttrib.MMultisample) shape = BulletBoxShape(Vec3(0.0254 * 4, 0.0254 * 24, 0.0254 * 2)) node.setMass(1.0) #block_np.setPos(-3.7, 0.0, 2.0) block_np.setPos(location) block_np.setHpr(random.uniform(-60, 60), 0.0, 0.0) node.addShape(shape) self.world.attachRigidBody(node) model = loader.loadModel('assets/bullet-samples/models/box.egg') model.setH(90) model.setSy(0.0254 * 4 * 2) model.setSx(0.0254 * 24 * 2) model.setSz(0.0254 * 2 * 2) model.flattenLight() model.reparentTo(block_np) return block_np def get_camera_image(self, requested_format=None): """ Returns the camera's image, which is of type uint8 and has values between 0 and 255. The 'requested_format' argument should specify in which order the components of the image must be. For example, valid format strings are "RGBA" and "BGRA". By default, Panda's internal format "BGRA" is used, in which case no data is copied over. """ tex = self.dr.getScreenshot() if requested_format is None: data = tex.getRamImage() else: data = tex.getRamImageAs(requested_format) image = np.frombuffer( data, np.uint8) # use data.get_data() instead of data in python 2 image.shape = (tex.getYSize(), tex.getXSize(), tex.getNumComponents()) image = np.flipud(image) return image[:, :, :3] def reset_conv(self): conveyor_dist_left = 1 - self.conv_np.getPos()[0] if conveyor_dist_left < 10: self.conv_np.setX(-95.0) self.conv_np.setY(0.0) # self.conv_np.setY(0.0) # self.conv_np.setHpr(0.0, 0.0, 0.0) def check_penalty(self): penalty = 0 self.pzone_ghost = self.pzone_ghostNP.node() for node in self.pzone_ghost.getOverlappingNodes(): if node.name == 'Block': penalty = 1 node.name = 'Scramble' self.have_scramble = False return penalty def check_rewards(self): reward = 0 # Check for reward blocks (recently cleared scrambles) rzone_ghost = self.rzone_ghostNP.node() scrambled = False for node in rzone_ghost.getOverlappingNodes(): if node.name == 'Block' or node.name == 'Scrambled Block': node.name = 'Scrambled Block' scrambled = True # Rename blocks that are not eligable for reward due to being too late for block in self.blocks: block_x = block.getPos()[0] block_name = block.node().name if block_x > 2.4 and block_name == 'Scrambled Block': self.have_scramble = False scrambled = False block.node().name = 'Not Rewardable' if scrambled is True: self.have_scramble = True else: if self.have_scramble is True: reward = 1 self.have_scramble = False return reward def check_teleportable(self, blocks_per_minute): self.time = self.framecount / self.fps if self.time % (1 / (blocks_per_minute / 60)) < 0.1: self.time_to_teleport = True else: self.time_to_teleport = False self.teleport_cooled_down = True for block in self.blocks: block_x = block.getPos()[0] if block_x > 5: if block.node().name == 'Scrambled Block': self.have_scramble = False block.node().name = 'Teleport Me' if self.time_to_teleport is True and self.teleport_cooled_down is True: self.teleport_cooled_down = False block.setX(-4) block.setY(0.0) block.setZ(2.0) block.setHpr(random.uniform(-60, 60), 0.0, 0.0) block.node().name = 'Block' def step(self, action): dt = 1 / self.fps self.framecount += 1 finger_meters_per_second = 2 max_dist = 1.1 real_displacement = finger_meters_per_second * dt # Move finger if action == 0: self.finger_np.setY(self.finger_np.getY() + real_displacement) if self.finger_np.getY() > max_dist: self.finger_np.setY(max_dist) if action == 2: self.finger_np.setY(self.finger_np.getY() - real_displacement) if self.finger_np.getY() < -max_dist: self.finger_np.setY(-max_dist) self.world.doPhysics(dt, 5, 1.0 / 120.0) self.reset_conv() self.check_teleportable(blocks_per_minute=1.1 * 60) # Keep the conveyor moving self.conv_np.node().setLinearVelocity(Vec3(1.0, 0.0, 0.0)) if self.render_stuff == True: self.graphicsEngine.renderFrame() image = self.get_camera_image() # image = cv2.resize(image, (84, 84), interpolation=cv2.INTER_CUBIC) score = 0 score += self.check_rewards() #score -= self.check_penalty() done = False return image, score, done
class BallInMaze(DirectObject): def __init__(self): base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) base.cam.setPosHpr(0, 0, 25, 0, -90, 0) base.disableMouse() # Input self.accept('escape', self.exitGame) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) # Setup scene 1: World self.debugNP = render.attachNewNode(BulletDebugNode('Debug')) self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(True) self.debugNP.node().showNormals(True) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Setup scene 2: Ball visNP = loader.loadModel('models/ball.egg') visNP.clearModelNodes() bodyNPs = BulletHelper.fromCollisionSolids(visNP, True) self.ballNP = bodyNPs[0] self.ballNP.reparentTo(render) self.ballNP.node().setMass(1.0) self.ballNP.setPos(4, -4, 1) self.ballNP.node().setDeactivationEnabled(False) visNP.reparentTo(self.ballNP) # Setup scene 3: Maze visNP = loader.loadModel('models/maze.egg') visNP.clearModelNodes() visNP.reparentTo(render) self.holes = [] self.maze = [] self.mazeNP = visNP bodyNPs = BulletHelper.fromCollisionSolids(visNP, True) for bodyNP in bodyNPs: bodyNP.reparentTo(render) if isinstance(bodyNP.node(), BulletRigidBodyNode): bodyNP.node().setMass(0.0) bodyNP.node().setKinematic(True) self.maze.append(bodyNP) elif isinstance(bodyNP.node(), BulletGhostNode): self.holes.append(bodyNP) # Lighting and material for the ball ambientLight = AmbientLight('ambientLight') ambientLight.setColor(Vec4(0.55, 0.55, 0.55, 1)) directionalLight = DirectionalLight('directionalLight') directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballNP.setLight(render.attachNewNode(ambientLight)) self.ballNP.setLight(render.attachNewNode(directionalLight)) m = Material() m.setSpecular(Vec4(1, 1, 1, 1)) m.setShininess(96) self.ballNP.setMaterial(m, 1) # Startup self.startGame() def exitGame(self): sys.exit() 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 startGame(self): self.ballNP.setPos(4, -4, 1) self.ballNP.node().setLinearVelocity(Vec3(0, 0, 0)) self.ballNP.node().setAngularVelocity(Vec3(0, 0, 0)) # Mouse p = base.win.getProperties() base.win.movePointer(0, p.getXSize() / 2, p.getYSize() / 2) # Add bodies and ghosts self.world.attachRigidBody(self.ballNP.node()) for bodyNP in self.maze: self.world.attachRigidBody(bodyNP.node()) for ghostNP in self.holes: self.world.attachGhost(ghostNP.node()) # Simulation task taskMgr.add(self.updateGame, 'updateGame') def stopGame(self): # Remove bodies and ghosts self.world.removeRigidBody(self.ballNP.node()) for bodyNP in self.maze: self.world.removeRigidBody(bodyNP.node()) for ghostNP in self.holes: self.world.removeGhost(ghostNP.node()) # Simulation task taskMgr.remove('updateGame') def updateGame(self, task): dt = globalClock.getDt() # Get mouse position and tilt maze if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() hpr = Vec3(0, mpos.getY() * -10, mpos.getX() * 10) # Maze visual node self.mazeNP.setHpr(hpr) # Maze body nodes for bodyNP in self.maze: bodyNP.setHpr(hpr) # Update simulation self.world.doPhysics(dt) # Check if ball is touching a hole for holeNP in self.holes: if holeNP.node().getNumOverlappingNodes() > 2: if (self.ballNP.node() in holeNP.node().getOverlappingNodes()): self.looseGame(holeNP) return task.cont def looseGame(self, holeNP): toPos = holeNP.node().getShapePos(0) self.stopGame() Sequence( Parallel( LerpFunc(self.ballNP.setX, fromData=self.ballNP.getX(), toData=toPos.getX(), duration=.1), LerpFunc(self.ballNP.setY, fromData=self.ballNP.getY(), toData=toPos.getY(), duration=.1), LerpFunc(self.ballNP.setZ, fromData=self.ballNP.getZ(), toData=self.ballNP.getZ() - .9, duration=.2)), Wait(1), Func(self.startGame)).start()
class Models(object): def __init__(self): self.setup() self.angel = 1 # Set up the environment # self.environ = loader.loadModel("models/square") self.environ.reparentTo(render) self.environ.setPos(0,0,0) self.environ.setScale(3000,3000,1) self.desert_tex = loader.loadTexture("models/desert.jpg") self.environ.setTexture(self.desert_tex, 1) self.sky = loader.loadModel("models/solar_sky_sphere") self.sky.reparentTo(render) self.sky.setScale(10000) self.sky.setPos(0,0,0) self.sky_tex = loader.loadTexture("models/stars_1k_tex.jpg") self.sky.setTexture(self.sky_tex, 1) def setup(self): #World self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) #Ground shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.ground = BulletRigidBodyNode('Ground') self.ground.addShape(shape) self.groundNp = render.attachNewNode(self.ground) self.groundNp.setPos(0, 0, 0) self.groundNp.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.ground) #BoxPyramid1 self.pyramid1 = loader.loadModel("models/pyramid/Pyramid") self.pyramid1.reparentTo(render) self.pyramid1.setScale(.5) self.pyramid1.setPos(0,-400,0) mesh = BulletTriangleMesh() for geomNP in self.pyramid1.findAllMatches('**/+GeomNode'): geomNode = geomNP.node() ts = geomNP.getTransform(self.pyramid1) for geom in geomNode.getGeoms(): mesh.addGeom(geom, ts) shape2 = BulletTriangleMeshShape(mesh, dynamic=False) self.node = BulletRigidBodyNode('BoxPyramid1') self.node.setMass(0) self.node.addShape(shape2) self.np = render.attachNewNode(self.node) self.np.setPos(0, -400, 0) self.np.setScale(1.65) self.np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node) #BoxPyramid2 self.pyramid2 = loader.loadModel("models/pyramid/Pyramid") self.pyramid2.reparentTo(render) self.pyramid2.setScale(.25) self.pyramid2.setPos(180,-400,0) mesh2 = BulletTriangleMesh() for geomNP in self.pyramid2.findAllMatches('**/+GeomNode'): geomNode = geomNP.node() ts = geomNP.getTransform(self.pyramid2) for geom in geomNode.getGeoms(): mesh2.addGeom(geom, ts) shape3 = BulletTriangleMeshShape(mesh2, dynamic=False) self.node3 = BulletRigidBodyNode('BoxPyramid2') self.node3.setMass(0) self.node3.addShape(shape3) self.np3 = render.attachNewNode(self.node3) self.np3.setPos(180, -400, 0) self.np3.setScale(0.85) self.np3.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node3) #BoxPyramid3 self.pyramid3 = loader.loadModel("models/pyramid/Pyramid") self.pyramid3.reparentTo(render) self.pyramid3.setScale(.25) self.pyramid3.setPos(-180,-400,0) mesh3 = BulletTriangleMesh() for geomNP in self.pyramid3.findAllMatches('**/+GeomNode'): geomNode = geomNP.node() ts = geomNP.getTransform(self.pyramid3) for geom in geomNode.getGeoms(): mesh3.addGeom(geom, ts) shape4 = BulletTriangleMeshShape(mesh2, dynamic=False) self.node4 = BulletRigidBodyNode('BoxPyramid3') self.node4.setMass(0) self.node4.addShape(shape4) self.np4 = render.attachNewNode(self.node4) self.np4.setPos(-180, -400, 0) self.np4.setScale(0.85) self.np4.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node4) #BoxSphinx self.sphinx = loader.loadModel("models/sphinx/Sphinx") self.sphinx.reparentTo(render) self.sphinx.setScale(.08) self.sphinx.setPos(100,-50,20) shape5 = BulletBoxShape(Vec3(18, 55, 30)) self.node5 = BulletRigidBodyNode('BoxSphinx') self.node5.setMass(0) self.node5.addShape(shape5) self.np5 = render.attachNewNode(self.node5) self.np5.setPos(100, -50, 10) self.np5.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node5) #start blocks_tex6 = loader.loadTexture("models/blocks_tex6.jpg") self.box1= loader.loadModel("models/box/box3") self.box1.reparentTo(render) self.box1.setScale(10,400,10) self.box1.setPos(-300,850,0) shape8 = BulletBoxShape(Vec3(8, 315, 13.5)) self.node8 = BulletRigidBodyNode('Box1') self.node8.setMass(0) self.node8.addShape(shape8) self.np8 = render.attachNewNode(self.node8) self.np8.setPos(-300, 850, 10) self.np8.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node8) self.box2= loader.loadModel("models/box/box3") self.box2.reparentTo(render) self.box2.setScale(10,400,10) self.box2.setPos(-350,850,0) shape9 = BulletBoxShape(Vec3(8, 315, 13.5)) self.node9 = BulletRigidBodyNode('Box2') self.node9.setMass(0) self.node9.addShape(shape9) self.np9 = render.attachNewNode(self.node9) self.np9.setPos(-350, 850, 10) self.np9.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node9) self.box3= loader.loadModel("models/box/box4") self.box3.reparentTo(render) self.box3.setScale(40,10,10) self.box3.setPos(-325,543,0) shape10 = BulletBoxShape(Vec3(30, 8, 13.5)) self.node10 = BulletRigidBodyNode('Box3') self.node10.setMass(0) self.node10.addShape(shape10) self.np10 = render.attachNewNode(self.node10) self.np10.setPos(-325, 543, 10) self.np10.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node10) self.box4= loader.loadModel("models/box/box4") self.box4.reparentTo(render) self.box4.setScale(40,10,10) self.box4.setPos(-325,1157,0) shape11 = BulletBoxShape(Vec3(30, 8, 13.5)) self.node11 = BulletRigidBodyNode('Box4') self.node11.setMass(0) self.node11.addShape(shape11) self.np11 = render.attachNewNode(self.node11) self.np11.setPos(-325, 1157, 10) self.np11.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node11) #Stars 1 self.stairsList = [0] * 10 self.stairsListNp = [0] * 10 n5 = 0 for i in range(10): n5 += 2 self.stairsList[i]= loader.loadModel("models/box/box1") self.stairsList[i].reparentTo(render) self.stairsList[i].setScale(1.3) self.stairsList[i].setPos(-325,925-(n5*1.2),n5) self.stairsList[i].setHpr(0,0,90) shape6 = BulletBoxShape(Vec3(3.2, 1.1, 1.1)) node6 = BulletRigidBodyNode('Box5 '+str(i)) node6.setMass(0) node6.addShape(shape6) self.stairsListNp[i] = render.attachNewNode(node6) self.stairsListNp[i].setPos(-325, 925-(n5*1.2), n5) self.stairsListNp[i].setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(node6) self.n5Upstairs = n5 self.box6= loader.loadModel("models/box/box1") self.box6.reparentTo(render) self.box6.setScale(10,87,0.2) self.box6.setPos(-325,829,n5) self.shape12 = BulletBoxShape(Vec3(8, 70, 0.75)) self.node12 = BulletRigidBodyNode('Box6') self.node12.setMass(0) self.node12.addShape(self.shape12) self.np12 = render.attachNewNode(self.node12) self.np12.setPos(-325, 829, n5) self.np12.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node12) self.box7= loader.loadModel("models/box/box2") self.box7.reparentTo(render) self.box7.setScale(5,12,0.25) self.box7.setPos(-325,749,n5) shape13 = BulletBoxShape(Vec3(4, 10, 0.8)) self.node13 = BulletRigidBodyNode('Box7') self.node13.setMass(0) self.node13.addShape(shape13) self.np13 = render.attachNewNode(self.node13) self.np13.setPos(-325, 749, n5) self.np13.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node13) box7Interval1 = self.box7.posInterval(3.3, Point3(-325, 749, n5+5), startPos=Point3(-325, 749, n5-5)) np13Interval1 = self.np13.posInterval(3, Point3(-325, 749, n5+5), startPos=Point3(-325, 749, n5-5)) box7Interval2 = self.box7.posInterval(3.3, Point3(-325, 749, n5-5), startPos=Point3(-325, 749, n5+5)) np13Interval2 = self.np13.posInterval(3, Point3(-325, 749, n5-5), startPos=Point3(-325, 749, n5+5)) self.box7Pace = Sequence(Parallel(box7Interval1,np13Interval1), Parallel(box7Interval2,np13Interval2), name="box7Pace") self.box7Pace.loop() self.box8= loader.loadModel("models/box/box2") self.box8.reparentTo(render) self.box8.setScale(5,12,0.25) self.box8.setPos(-325,725,n5) shape14 = BulletBoxShape(Vec3(4, 10, 0.8)) node14 = BulletRigidBodyNode('Box8') node14.setMass(0) node14.addShape(shape14) self.np14 = render.attachNewNode(node14) self.np14.setPos(-325, 725, n5) self.np14.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(node14) box8Interval1 = self.box8.posInterval(3.3, Point3(-325, 725, n5-5), startPos=Point3(-325, 725, n5+5)) np14Interval1 = self.np14.posInterval(3, Point3(-325, 725, n5-5), startPos=Point3(-325, 725, n5+5)) box8Interval2 = self.box8.posInterval(3.3, Point3(-325, 725, n5+5), startPos=Point3(-325, 725, n5-5)) np14Interval2 = self.np14.posInterval(3, Point3(-325, 725, n5+5), startPos=Point3(-325, 725, n5-5)) self.box8Pace = Sequence(Parallel(box8Interval1,np14Interval1), Parallel(box8Interval2,np14Interval2), name="box8Pace") self.box8Pace.loop() self.Cylinder1= loader.loadModel("models/Cylinder/Cylinder") self.Cylinder1.reparentTo(render) self.Cylinder1.setScale(8,8,0.2) self.Cylinder1.setPos(-322,700,n5) self.Cylinder1.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape16 = BulletCylinderShape(radius, height, ZUp) self.node16 = BulletRigidBodyNode('Cylinder1') self.node16.setMass(0) self.node16.addShape(shape16) self.np16 = render.attachNewNode(self.node16) self.np16.setPos(-322, 700, n5) self.np16.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node16) self.Cylinder2= loader.loadModel("models/Cylinder/Cylinder") self.Cylinder2.reparentTo(render) self.Cylinder2.setScale(8,8,0.2) self.Cylinder2.setPos(-327,680,n5) self.Cylinder2.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape17 = BulletCylinderShape(radius, height, ZUp) self.node17 = BulletRigidBodyNode('Cylinder2') self.node17.setMass(0) self.node17.addShape(shape17) self.np17 = render.attachNewNode(self.node17) self.np17.setPos(-327, 680, n5) self.np17.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node17) self.Cylinder3= loader.loadModel("models/Cylinder/Cylinder") self.Cylinder3.reparentTo(render) self.Cylinder3.setScale(8,8,0.2) self.Cylinder3.setPos(-322,660,n5) self.Cylinder3.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape18 = BulletCylinderShape(radius, height, ZUp) self.node18 = BulletRigidBodyNode('Cylinder3') self.node18.setMass(0) self.node18.addShape(shape18) self.np18 = render.attachNewNode(self.node18) self.np18.setPos(-322, 660, n5) self.np18.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node18) self.Cylinder4= loader.loadModel("models/Cylinder/Cylinder") self.Cylinder4.reparentTo(render) self.Cylinder4.setScale(8,8,0.2) self.Cylinder4.setPos(-327,640,n5) self.Cylinder4.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape19 = BulletCylinderShape(radius, height, ZUp) self.node19 = BulletRigidBodyNode('Cylinder4') self.node19.setMass(0) self.node19.addShape(shape19) self.np19 = render.attachNewNode(self.node19) self.np19.setPos(-327, 640, n5) self.np19.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node19) self.fire= loader.loadModel("models/stop_sign/stop_sign") self.fire.setScale(0.01) self.fire.reparentTo(render) self.fire.setPos(-327,640,n5+5) #setup the items to be collected self.setupItems() self.setupEndPoint() #################End point################################### def setupEndPoint(self): blocks_tex8 = loader.loadTexture("models/blocks_tex8.jpg") self.endpoint= loader.loadModel("models/Sphere_HighPoly/Sphere_HighPoly") self.endpoint.reparentTo(render) self.endpoint.setScale(.8) self.endpoint.setPos(0,-200,2) self.endpoint.setTexture(blocks_tex8, 1) radius = 2.65 self.shapeEnd = BulletSphereShape(radius) self.nodeEnd = BulletGhostNode('EndPoint') self.nodeEnd.addShape(self.shapeEnd) self.npEnd = render.attachNewNode(self.nodeEnd) self.npEnd.setPos(0, -200, 2) self.npEnd.setCollideMask(BitMask32.allOn()) self.world.attachGhost(self.nodeEnd) def setupItems(self): #############Items######################################## self.iteamsModelsList = [0] * 50 self.iteamsNodesList = [0] * 50 self.iteamsNpsList = [0] * 50 self.index = 0 n6 = 0 for i in range(10): t1= loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(-325,925-(n6*1.2),n6+2) t1.setHpr(0,90,0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(-325, 925-(n6*1.2), n6+2) npt1.setHpr(0,90,0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 n6 += 2 self.index += 1 n7 = 20 for i in range(5): t1= loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(-325,880-n7,n6+2) t1.setHpr(0,90,0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(-325, 880-n7, n6+2) npt1.setHpr(0,90,0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 n7 += 20 self.index += 1 t1= loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(self.Cylinder1.getX(),self.Cylinder1.getY(),n6+2) t1.setHpr(0,90,0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(self.Cylinder1.getX(),self.Cylinder1.getY(),n6+2) npt1.setHpr(0,90,0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 t1= loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(self.Cylinder2.getX(),self.Cylinder2.getY(),n6+2) t1.setHpr(0,90,0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(self.Cylinder2.getX(),self.Cylinder2.getY(),n6+2) npt1.setHpr(0,90,0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 t1= loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(self.Cylinder3.getX(),self.Cylinder3.getY(),n6+2) t1.setHpr(0,90,0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(self.Cylinder3.getX(),self.Cylinder3.getY(),n6+2) npt1.setHpr(0,90,0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 n6 = 0 for i in range(30): x = random.randint(-50, 50) y = random.randint(-50, 50) t1= loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(x,y,2) t1.setHpr(0,90,0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(x, y, 2) npt1.setHpr(0,90,0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 n6 += 2 self.index += 1
class BallInMaze(DirectObject): def __init__(self): base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) base.cam.setPosHpr(0, 0, 25, 0, -90, 0) base.disableMouse() # Input self.accept('escape', self.exitGame) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) # Setup scene 1: World self.debugNP = render.attachNewNode(BulletDebugNode('Debug')) self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(True) self.debugNP.node().showNormals(True) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Setup scene 2: Ball visNP = loader.loadModel('models/ball.egg') visNP.clearModelNodes() bodyNPs = BulletHelper.fromCollisionSolids(visNP, True) self.ballNP = bodyNPs[0] self.ballNP.reparentTo(render) self.ballNP.node().setMass(1.0) self.ballNP.setPos(4, -4, 1) self.ballNP.node().setDeactivationEnabled(False) visNP.reparentTo(self.ballNP) # Setup scene 3: Maze visNP = loader.loadModel('models/maze.egg') visNP.clearModelNodes() visNP.reparentTo(render) self.holes = [] self.maze = [] self.mazeNP = visNP bodyNPs = BulletHelper.fromCollisionSolids(visNP, True); for bodyNP in bodyNPs: bodyNP.reparentTo(render) if isinstance(bodyNP.node(), BulletRigidBodyNode): bodyNP.node().setMass(0.0) bodyNP.node().setKinematic(True) self.maze.append(bodyNP) elif isinstance(bodyNP.node(), BulletGhostNode): self.holes.append(bodyNP) # Lighting and material for the ball ambientLight = AmbientLight('ambientLight') ambientLight.setColor(Vec4(0.55, 0.55, 0.55, 1)) directionalLight = DirectionalLight('directionalLight') directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballNP.setLight(render.attachNewNode(ambientLight)) self.ballNP.setLight(render.attachNewNode(directionalLight)) m = Material() m.setSpecular(Vec4(1,1,1,1)) m.setShininess(96) self.ballNP.setMaterial(m, 1) # Startup self.startGame() def exitGame(self): sys.exit() 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 startGame(self): self.ballNP.setPos(4, -4, 1) self.ballNP.node().setLinearVelocity(Vec3(0, 0, 0)) self.ballNP.node().setAngularVelocity(Vec3(0, 0, 0)) # Mouse p = base.win.getProperties() base.win.movePointer(0, p.getXSize()/2, p.getYSize()/2) # Add bodies and ghosts self.world.attachRigidBody(self.ballNP.node()) for bodyNP in self.maze: self.world.attachRigidBody(bodyNP.node()) for ghostNP in self.holes: self.world.attachGhost(ghostNP.node()) # Simulation task taskMgr.add(self.updateGame, 'updateGame') def stopGame(self): # Remove bodies and ghosts self.world.removeRigidBody(self.ballNP.node()) for bodyNP in self.maze: self.world.removeRigidBody(bodyNP.node()) for ghostNP in self.holes: self.world.removeGhost(ghostNP.node()) # Simulation task taskMgr.remove('updateGame') def updateGame(self, task): dt = globalClock.getDt() # Get mouse position and tilt maze if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() hpr = Vec3(0, mpos.getY() * -10, mpos.getX() * 10) # Maze visual node self.mazeNP.setHpr(hpr) # Maze body nodes for bodyNP in self.maze: bodyNP.setHpr(hpr) # Update simulation self.world.doPhysics(dt) # Check if ball is touching a hole for holeNP in self.holes: if holeNP.node().getNumOverlappingNodes() > 2: if (self.ballNP.node() in holeNP.node().getOverlappingNodes()): self.looseGame(holeNP) return task.cont def looseGame(self, holeNP): toPos = holeNP.node().getShapePos(0) self.stopGame() Sequence( Parallel( LerpFunc(self.ballNP.setX, fromData = self.ballNP.getX(), toData = toPos.getX(), duration = .1), LerpFunc(self.ballNP.setY, fromData = self.ballNP.getY(), toData = toPos.getY(), duration = .1), LerpFunc(self.ballNP.setZ, fromData = self.ballNP.getZ(), toData = self.ballNP.getZ() - .9, duration = .2)), Wait(1), Func(self.startGame)).start()
class Game(ShowBase, object): """What should be done here: Nothing that doesnt have to be. If something can have its own class, it should. Things that are here that shouldnt be: Setting up physics Setting up the world Menus GUI World/level things Things that are here that should be: Setting properties Main update loop Initalizing things (worlds, physics) Via other classes Remember to ask yourself this "Does a X have a Y?" So does a game have physics? No, a game has a world, and a world has physics. An entity is a panda node. """ forceFPS = True fsmState = True bulletDict = {} playerList = {} grav_ghost_NP = 0 def __init__(self): #self.gui = loadGui() #init_pause_state(self.menu) init_pause_state() test = World() debugNode = BulletDebugNode('Debug') debugNode.showWireframe(True) debugNode.showConstraints(True) debugNode.showBoundingBoxes(False) debugNode.showNormals(False) debugNP = render.attachNewNode(debugNode) debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9)) self.world.setDebugNode(debugNP.node()) #Add a gravity region self.add_gravity_region( (100, 100, 100), (100, -400, 0), (0, 0, 1000)) taskMgr.add(self.update_bullet, 'update_bullet') self.bulletList = self.loadBulletList() base.disableMouse() self.loadLevel() self.initClasses() self.setCamera() self.addWinProps() #TODO: Fix the healthbars #self.gui.healthBar("Player1") #self.gui.healthBar("AI1") #self.gui.healthBar("AI2") #self.gui.healthBar("AI3") self.loadStation() self.addlight() self.createControls() taskMgr.add(self.updateMenus, 'MenuUpdater') print("Instance of game class running.") self.simmpoleXP() self.flipsXP() def update_bullet(self, task): dt = globalClock.getDt() self.world.doPhysics(dt) return task.cont def add_gravity_region(self, size, pos, gravity): """Makes a bullet ghost, when a object enters its gravity is changed to match the arguments passed """ shape = BulletBoxShape(Vec3(size)) grav_ghost = BulletGhostNode('Ghost') grav_ghost.addShape(shape) grav_ghost_NP = render.attachNewNode(grav_ghost) grav_ghost_NP.setPos(pos) grav_ghost_NP.setCollideMask(BitMask32(0x0f)) self.world.attachGhost(grav_ghost) def check_gravity_region(task): """Check what bullet nodes are inside and apply gravity to them. """ ghost = grav_ghost_NP.node() print ghost.getNumOverlappingNodes() for node in ghost.getOverlappingNodes(): print node #TODO: Make this only apply when in the region #EX: Gravity is set to X inside, set back to normal when out node.setGravity(Vec3(gravity)) return task.cont #Add the region checker task taskMgr.add(check_gravity_region, "check_gravity_region") def simmpoleXP(self): for i in range(101): if i < 6: xpToLvl = ((i) * ((i * i) / 2) * 256) else: xpToLvl = (i) * ((i * i) / 2) * 128 print("SimmPole: Level " + str(i) + ":" + str(xpToLvl)) #print(str(xpToLvl)+", ") def flipsXP(self): for i in range(101): xpToLvl = (i) * ((i * i) / 2) * 100 print("Flips: Level " + str(i) + ":" + str(xpToLvl)) #print(str(xpToLvl)+", ") def loadBulletList(self): self.bulletDict[0] = ("_normalBullet") self.bulletDict[1] = ("_normalMissile") return self.bulletDict def sortedBulletDictValues(self): items = self.bulletDict.items() items.sort() return [value for key, value in items] def initClasses(self): '''Makes some instances of some classes''' self.playerList["Player1"] = Player( self.world, "Player1", False, False, None, 50) # Makes the main ship, using the base.camera. self.playerList["AI1"] = Player( self.world, "AI1", True, True, self.playerList["Player1"].getShip(), 10) # Makes an AI ship, using no camera. self.playerList["AI2"] = Player( self.world, "AI2", True, True, self.playerList["Player1"].getShip(), 10) self.playerList["AI3"] = Player( self.world, "AI3", True, True, self.playerList["Player1"].getShip(), 10) self.gameSettings = GameSettings() def createPlayer(self): '''To be implemented. Players (and ships) could be in an array, and the array could be in a function to assign new players (and ships). This would allow direct access to class instances, giving more control to the program. Example: playerArray = [] def createPlayer(self, playerArray, args, args1): player = Player(args, args1) playerArray.append(player) ''' def addWinProps(self): #Hides the cursor and sets the window title self.props = WindowProperties() self.props.setCursorHidden(True) self.props.setTitle('Space Fighter') base.win.requestProperties(self.props) base.setFrameRateMeter(True) FPS = 60 self.globalClock = ClockObject.getGlobalClock() if self.forceFPS: self.globalClock.setMode(ClockObject.MForced) else: self.globalClock.setMode(ClockObject.MLimited) self.globalClock.setFrameRate(FPS) self.globalTime = self.globalClock.getRealTime() render.setAntialias(AntialiasAttrib.MMultisample) def exit(self): sys.exit() def pause(self): '''Runs functions when escape is pressed''' PauseState.pause_ssm() def debugOn(self): self.playerList["Player1"].ship.ForwardSpeed = self.playerList["Player1"].ship.MaxSpeed base.acceptOnce("lshift", self.debugOff) # Leave debug mode "lshift" self.playerList["Player1"].score += 1 print "Debug mode on :)" def debugOff(self): base.acceptOnce("lshift", self.debugOn) # Enter debug mode on "lshift" print "Debug mode off :(" def addlight(self): sptLight = Spotlight("spot") sptLens = PerspectiveLens() sptLens.setFar(1000) sptLens.setFov(90) sptLight.setLens(sptLens) sptLight.setColor(Vec4(1.2, 1.2, 1.0, .2)) sptLight.setShadowCaster(True, 4096, 4096) sptNode = render.attachNewNode(sptLight) sptNode.setPos(0, 0, 1000) sptNode.setHpr(0,-90,0) sptNode.lookAt(self.level) render.setLight(sptNode) dirLight = DirectionalLight("dlight") dirLight.setSpecularColor(VBase4(0.249, 0.235, 0.207, 1)) dirLight.setDirection(Vec3(102, 100, -60)) dirLight.setShadowCaster(True, 2048, 2048) dirLight.getLens().setFilmSize(4096, 4096) dirLight.showFrustum() dLight = render.attachNewNode(dirLight) #render.setLight(dLight) alight = AmbientLight('alight') alight.setColor(VBase4(.149, .145, .135, 1)) alnp = render.attachNewNode(alight) render.setLight(alnp) render.setShaderAuto() def loadStation(self): #Loads and sets up a station self.Station = loader.loadModel('models/station.x') self.Station.reparentTo(render) self.Station.setPos(0, 0, 0) #collisions.pickerCollision(self.Station) def loadLevel(self): '''Loads and sets up a level''' shape = BulletBoxShape(Vec3(200, 200, 200)) node = BulletRigidBodyNode('Box') node.addShape(shape) np = render.attachNewNode(node) np.setPos(0, 0, -400) self.world.attachRigidBody(node) lvlmat = Material() lvlmat.setDiffuse(VBase4(0.166, 0.151, 0.119, 1)) self.level = loader.loadModel('models/level.x') self.level.reparentTo(np) self.level.setPos(0, 0, -00) self.level.setScale(200) self.level.setMaterial(lvlmat, 1) self.level.setColor(0,1,1,1) ''' lvlmat = Material() lvlmat.setDiffuse(VBase4(0.166, 0.151, 0.119, 1)) self.level = loader.loadModel('models/level.x') self.level.reparentTo(render) self.level.setPos(0, 0, -750) self.level.setScale(200) self.level.setMaterial(lvlmat, 1)''' #self.level.setR(50) #self.level.setTwoSided(True) #self.level.place() #cm = CardMaker("plane") #cm.setFrame(-1000, 1000, -1000, 1000) #self.level = render.attachNewNode(cm.generate()) #self.level.setP(270) #self.level.setPos(0,0,-10) #self.level.setTwoSided(True) def setCamera(self): '''Loads and sets up cameras''' frontCam = Camera("frontCamera") frontCamera = render.attachNewNode(frontCam) frontCamera.setName("FrontCamera") frontCamera.setPos(0, 5, 0) frontCamera.setHpr(0, 0, 0) #dr = base.camNode.getDisplayRegion(0) #dr.setActive(0) # Or leave it (dr.setActive(1)) #window = dr.getWindow() #dr1 = window.makeDisplayRegion(0, 1, 0.5, 1) #dr1.setSort(dr.getSort()) #dr2 = window.makeDisplayRegion(0.5, 1, 0, 1) #dr2.setSort(dr.getSort()) #dr1.setCamera(frontCamera) #dr2.setCamera(base.camera) def updateMenus(self, task): #Updates the menu with recent data. #self.menu.updateOptionsMenu() return task.cont def createControls(self): #Sets up the controls base.accept("escape", self.pause) # Exit game on "escape" base.acceptOnce("lshift", self.debugOn) # Enter debug mode on "lshift"
lightNP.node().getLens().setNearFar(10, 100) #lightNP.node().setShadowCaster(True) lightNP.node().setShadowCaster(True, 1024, 1024) # Use a 512x512 resolution shadow map render.setLight(lightNP) # Enable the shader generator for the receiving nodes render.setShaderAuto() # Delete zone dzone_shape = BulletBoxShape(Vec3(1, 10, 10)) dzone_ghost = BulletGhostNode('Delete Zone') dzone_ghost.addShape(dzone_shape) dzone_ghostNP = render.attachNewNode(dzone_ghost) dzone_ghostNP.setPos(5.7, 0, 0.0) dzone_ghostNP.setCollideMask(BitMask32(0x0f)) world.attachGhost(dzone_ghost) # Penalty zone 1 pzone_shape = BulletBoxShape(Vec3(1, 1, 0.5)) pzone_ghost = BulletGhostNode('Penalty Zone 1') pzone_ghost.addShape(pzone_shape) pzone_ghostNP = render.attachNewNode(pzone_ghost) pzone_ghostNP.setPos(4.2, 0, 0.86) pzone_ghostNP.setCollideMask(BitMask32(0x0f)) world.attachGhost(pzone_ghost) # Reward zone rzone_shape = BulletBoxShape(Vec3(.8, 1, 0.5)) rzone_ghost = BulletGhostNode('Penalty Zone 2') rzone_ghost.addShape(rzone_shape) rzone_ghostNP = render.attachNewNode(rzone_ghost)
class Models2(object): def __init__(self): self.setup() self.angel = 1 # Set up the environment # self.sky = loader.loadModel("models/solar_sky_sphere") self.sky.reparentTo(render) self.sky.setScale(10000) self.sky.setPos(0, 0, 0) self.sky_tex = loader.loadTexture("models/stars_1k_tex.jpg") self.sky.setTexture(self.sky_tex, 1) def setup(self): #World self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) #Ground shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.ground = BulletRigidBodyNode('Ground') self.ground.addShape(shape) self.groundNp = render.attachNewNode(self.ground) self.groundNp.setPos(0, 0, 0) self.groundNp.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.ground) #build self.shape1 = BulletBoxShape(Vec3(8, 8, 0.75)) self.node1 = BulletRigidBodyNode('Box1') self.node1.setMass(0) self.node1.addShape(self.shape1) self.np1 = render.attachNewNode(self.node1) self.np1.setPos(0, 0, 100) self.np1.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node1) self.box1 = loader.loadModel("models/box/box1") self.box1.reparentTo(render) self.box1.setScale(10, 10, 0.2) self.box1.setPos(0, 0, 100) self.shape2 = BulletBoxShape(Vec3(8, 8, 0.75)) self.node2 = BulletRigidBodyNode('Box2') self.node2.setMass(0) self.node2.addShape(self.shape2) self.np2 = render.attachNewNode(self.node2) self.np2.setPos(5, -22, 102) self.np2.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node2) self.box2 = loader.loadModel("models/box/box1") self.box2.reparentTo(render) self.box2.setScale(10, 10, 0.2) self.box2.setPos(5, -22, 102) self.shape3 = BulletBoxShape(Vec3(8, 8, 0.75)) self.node3 = BulletRigidBodyNode('Box3') self.node3.setMass(0) self.node3.addShape(self.shape3) self.np3 = render.attachNewNode(self.node3) self.np3.setPos(-5, -44, 104) self.np3.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node3) self.box3 = loader.loadModel("models/box/box1") self.box3.reparentTo(render) self.box3.setScale(10, 10, 0.2) self.box3.setPos(-5, -44, 104) self.shape4 = BulletBoxShape(Vec3(8, 8, 0.75)) self.node4 = BulletRigidBodyNode('Box4') self.node4.setMass(0) self.node4.addShape(self.shape4) self.np4 = render.attachNewNode(self.node4) self.np4.setPos(-27, -44, 104) self.np4.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node4) self.box4 = loader.loadModel("models/box/box1") self.box4.reparentTo(render) self.box4.setScale(10, 10, 0.2) self.box4.setPos(-27, -44, 104) self.shape5 = BulletBoxShape(Vec3(8, 8, 0.75)) self.node5 = BulletRigidBodyNode('Box5') self.node5.setMass(0) self.node5.addShape(self.shape5) self.np5 = render.attachNewNode(self.node5) self.np5.setPos(-27, -66, 104) self.np5.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node5) self.box5 = loader.loadModel("models/box/box1") self.box5.reparentTo(render) self.box5.setScale(10, 10, 0.2) self.box5.setPos(-27, -66, 104) self.box6 = loader.loadModel("models/box/box1") self.box6.reparentTo(render) self.box6.setScale(10, 87, 0.2) self.box6.setPos(-22, -150, 106) self.shape6 = BulletBoxShape(Vec3(8, 70, 0.75)) self.node6 = BulletRigidBodyNode('Box6') self.node6.setMass(0) self.node6.addShape(self.shape6) self.np6 = render.attachNewNode(self.node6) self.np6.setPos(-22, -150, 106) self.np6.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node6) blocks_tex6 = loader.loadTexture("models/blocks_tex6.jpg") self.Cylinder1 = loader.loadModel("models/Cylinder/Cylinder") self.Cylinder1.reparentTo(render) self.Cylinder1.setScale(8, 8, 0.2) self.Cylinder1.setPos(-22, -230, 108) self.Cylinder1.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape16 = BulletCylinderShape(radius, height, ZUp) self.node16 = BulletRigidBodyNode('Cylinder1') self.node16.setMass(0) self.node16.addShape(shape16) self.np16 = render.attachNewNode(self.node16) self.np16.setPos(-22, -230, 108) self.np16.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node16) self.Cylinder2 = loader.loadModel("models/Cylinder/Cylinder") self.Cylinder2.reparentTo(render) self.Cylinder2.setScale(8, 8, 0.2) self.Cylinder2.setPos(-15, -250, 110) self.Cylinder2.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape17 = BulletCylinderShape(radius, height, ZUp) self.node17 = BulletRigidBodyNode('Cylinder2') self.node17.setMass(0) self.node17.addShape(shape17) self.np17 = render.attachNewNode(self.node17) self.np17.setPos(-15, -250, 110) self.np17.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node17) self.Cylinder3 = loader.loadModel("models/Cylinder/Cylinder") self.Cylinder3.reparentTo(render) self.Cylinder3.setScale(8, 8, 0.2) self.Cylinder3.setPos(-25, -270, 112) self.Cylinder3.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape18 = BulletCylinderShape(radius, height, ZUp) self.node18 = BulletRigidBodyNode('Cylinder3') self.node18.setMass(0) self.node18.addShape(shape18) self.np18 = render.attachNewNode(self.node18) self.np18.setPos(-25, -270, 112) self.np18.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node18) self.Cylinder4 = loader.loadModel("models/Cylinder/Cylinder") self.Cylinder4.reparentTo(render) self.Cylinder4.setScale(8, 8, 0.2) self.Cylinder4.setPos(-30, -290, 114) self.Cylinder4.setTexture(blocks_tex6, 1) radius = 8 height = 1 shape19 = BulletCylinderShape(radius, height, ZUp) self.node19 = BulletRigidBodyNode('Cylinder4') self.node19.setMass(0) self.node19.addShape(shape19) self.np19 = render.attachNewNode(self.node19) self.np19.setPos(-30, -290, 114) self.np19.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node19) self.fire = loader.loadModel("models/stop_sign/stop_sign") self.fire.setScale(0.01) self.fire.reparentTo(render) self.fire.setPos(-30, -290, 114 + 6) self.shape7 = BulletBoxShape(Vec3(8, 8, 0.75)) self.node7 = BulletRigidBodyNode('Box7') self.node7.setMass(0) self.node7.addShape(self.shape7) self.np7 = render.attachNewNode(self.node7) self.np7.setPos(0, 0, 200) self.np7.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.node7) self.box7 = loader.loadModel("models/box/box1") self.box7.reparentTo(render) self.box7.setScale(10, 10, 0.2) self.box7.setPos(0, 0, 200) #setup the items to be collected self.setupItems() self.setupEndPoint() def setupEndPoint(self): blocks_tex8 = loader.loadTexture("models/blocks_tex8.jpg") self.endpoint = loader.loadModel( "models/Sphere_HighPoly/Sphere_HighPoly") self.endpoint.reparentTo(render) self.endpoint.setScale(.5) self.endpoint.setPos(0, 0, 202) self.endpoint.setTexture(blocks_tex8, 1) radius = 2.65 self.shapeEnd = BulletSphereShape(radius) self.nodeEnd = BulletGhostNode('EndPoint') self.nodeEnd.addShape(self.shapeEnd) self.npEnd = render.attachNewNode(self.nodeEnd) self.npEnd.setPos(0, 5, 202) self.npEnd.setCollideMask(BitMask32.allOn()) self.world.attachGhost(self.nodeEnd) def setupItems(self): #############Items######################################## self.iteamsModelsList = [0] * 50 self.iteamsNodesList = [0] * 50 self.iteamsNpsList = [0] * 50 self.index = 0 for i in range(5): x = 4 + i y = -20 + i t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(x, y, 104) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(x, y, 104) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 for i in range(5): x = -4 + i y = -42 + i t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(x, y, 106) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(x, y, 106) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 for i in range(5): x = -25 + i y = -42 + i t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(x, y, 106) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(x, y, 106) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 for i in range(5): x = -25 + i y = -64 + i t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(x, y, 106) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(x, y, 106) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 for i in range(5): x = -22 y = -120 - (i * 10) t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(x, y, 108) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(x, y, 108) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(self.Cylinder1.getX(), self.Cylinder1.getY(), self.Cylinder1.getZ() + 2) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(self.Cylinder1.getX(), self.Cylinder1.getY(), self.Cylinder1.getZ() + 2) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(self.Cylinder2.getX(), self.Cylinder2.getY(), self.Cylinder2.getZ() + 2) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(self.Cylinder2.getX(), self.Cylinder2.getY(), self.Cylinder2.getZ() + 2) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1 t1 = loader.loadModel("models/Torus/Torus") t1.reparentTo(render) t1.setScale(.6) t1.setPos(self.Cylinder3.getX(), self.Cylinder3.getY(), self.Cylinder3.getZ() + 2) t1.setHpr(0, 90, 0) radius = .8 height = .5 shape19 = BulletCylinderShape(radius, height, ZUp) nodet1 = BulletGhostNode('t1') nodet1.addShape(shape19) npt1 = render.attachNewNode(nodet1) npt1.setPos(self.Cylinder3.getX(), self.Cylinder3.getY(), self.Cylinder3.getZ() + 2) npt1.setHpr(0, 90, 0) npt1.setCollideMask(BitMask32.allOn()) self.world.attachGhost(nodet1) self.iteamsModelsList[self.index] = t1 self.iteamsNodesList[self.index] = nodet1 self.iteamsNpsList[self.index] = npt1 self.index += 1
class PhysicsManager(object): def __init__(self,gravity=(0,0,-9.81)): self.world = BulletWorld() self.world.setGravity(Vec3(gravity)) self.addShape = {} self.addShape['sphere'] = self.__addSphere self.addShape['box'] = self.__addBox self.addShape['cylinder'] = self.__addCylinder self.addShape['capsule'] = self.__addCapsule self.addShape['cone'] = self.__addCone self.addShape['hull'] = self.__addConvexHull self.addShape['trimesh'] = self.__addTriangleMesh def getRigidBodyDefaultProps(self): props = {} props['mass'] = 1. props['friction'] = .5 props['restitution'] = .0 props['adamping'] = .0 props['ldamping'] = .0 props['asleep'] = .08 props['lsleep'] = 1. props['deactivation'] = True props['kinematic'] = False return props def getRigidBody(self,name=None): return BulletRigidBodyNode(name or 'rigidbody') def createRigidBody(self,shapetype,sizeOrGeom,props={},pos=(0,0,0),hpr=(0,0,0),scale=(1,1,1),name=None): body = self.getRigidBody(name) self.addShape[shapetype](body,sizeOrGeom,pos,hpr,scale) props = dict(self.getRigidBodyDefaultProps().items() + props.items()) self.setBodyProps(body, props) self.world.attachRigidBody( body ) return body def createGhost(self,name,shape,size): ghost = BulletGhostNode( name ) self.addShape[shape]( ghost, size ) self.world.attachGhost( ghost ) return ghost def attachRigidBody(self,body,props): self.setBodyProps(body,props) self.world.attachRigidBody( body ) def __addSphere(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletSphereShape( max(size)/2 ) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addBox(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletBoxShape( size/2 ) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addCylinder(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletCylinderShape(max(size.x,size.y)/2, size.z, ZUp) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addCapsule(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): diam = max(size.x,size.y) shape = BulletCapsuleShape(diam/2, size.z-diam, ZUp) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) # def __addAdaptiveShape(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1), type='capsule'): # height = max(size.x,size.y,size.z) # diam = min(size.x,size.y,size.z) # if type == 'capsule': # shape = BulletCapsuleShape(diam/2, height-diam, ZUp) # elif type == 'cylinder': # shape = BulletCylinderShape(diam/2, height, ZUp) # vec = (0,0,0) # if size.x > size.z:vec=(0,0,90) # if size.y > size.x:vec=(0,90,0) # hpr+=vec # body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addCone(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletConeShape(max(size.x,size.y)/2, size.z, ZUp) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addConvexHull(self, body, geom, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletConvexHullShape() shape.addGeom(geom) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addTriangleMesh(self, body, geom, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1), dynamic=True): mesh = BulletTriangleMesh() mesh.addGeom(geom) shape = BulletTriangleMeshShape(mesh, dynamic=dynamic ) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def __addPlane(self, body, size, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ): shape = BulletPlaneShape(size, 1) body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) ) def setBodyProps(self,body,props): body.setMass(props['mass']) body.setFriction(props['friction']) body.setRestitution(props['restitution']) body.setAngularDamping(props['adamping']) body.setLinearDamping(props['ldamping']) body.setAngularSleepThreshold(props['asleep']) body.setLinearSleepThreshold(props['lsleep']) if not props['deactivation']: body.setDeactivationEnabled(False) body.setKinematic(props['kinematic']) def characterController(self,name, height, mass, radius, step_height): shape = BulletCapsuleShape(radius, height - 2*radius, ZUp) body = BulletRigidBodyNode(name) body.setMass(mass) body.addShape(shape) return BulletCharacterControllerNode(shape, step_height, name) def debug(self): from panda3d.bullet import BulletDebugNode debugNP = render.attachNewNode(BulletDebugNode('Debug')) debugNP.show() debugNP.node().showWireframe(True) debugNP.node().showConstraints(True) debugNP.node().showBoundingBoxes(False) debugNP.node().showNormals(False) self.world.setDebugNode(debugNP.node()) return debugNP def __log(self,props,body): #print 'Name:'+props['name'], 'Class:'+props['class'] print 'mass',body.getMass() print 'friction',body.getFriction() print 'restitution',body.getRestitution() print 'lsleep',body.getLinearSleepThreshold() print 'asleep',body.getAngularSleepThreshold() print 'ldamping',body.getLinearDamping() print 'adamping',body.getAngularDamping() #print 'kinematic',body.getKinematic() print '-------------------------------------------------------'
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) 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') # ____TASK___ def processInput(self, dt): force = Vec3(0, 0, 0) torque = Vec3(0, 0, 0) if inputState.isSet('forward'): force.setY( 1.0) if inputState.isSet('reverse'): force.setY(-1.0) if inputState.isSet('left'): force.setX(-1.0) if inputState.isSet('right'): force.setX( 1.0) if inputState.isSet('turnLeft'): torque.setZ( 1.0) if inputState.isSet('turnRight'): torque.setZ(-1.0) force *= 30.0 torque *= 10.0 self.boxNP.node().setActive(True) self.boxNP.node().applyCentralForce(force) self.boxNP.node().applyTorque(torque) def update(self, task): dt = globalClock.getDt() self.processInput(dt) self.world.doPhysics(dt) # Get nodes overlapping with the ghost object if self.ghostNP.node().getNumOverlappingNodes() > 0: print self.ghostNP.node().getNumOverlappingNodes(), \ self.ghostNP.node().getOverlappingNodes() 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) node = BulletRigidBodyNode('Ground') np = self.worldNP.attachNewNode(node) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32(0x0f)) self.world.attachRigidBody(np.node()) # Box shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Box')) np.node().setMass(1.0) np.node().addShape(shape) np.setPos(0, 0, 4) np.setCollideMask(BitMask32(0x0f)) self.world.attachRigidBody(np.node()) self.boxNP = np visualNP = loader.loadModel('models/box.egg') visualNP.reparentTo(self.boxNP) # Trigger shape = BulletBoxShape(Vec3(1, 1, 2)) np = self.worldNP.attachNewNode(BulletGhostNode('Ghost')) np.node().addShape(shape) np.setPos(3, 0, 0) np.setCollideMask(BitMask32(0x0f)) self.world.attachGhost(np.node()) self.ghostNP = np
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 GameMap(ShowBase): def __init__(self): ShowBase.__init__(self) self.springs = [] def setupMap(self): base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) # setup debugNode self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug')) # self.debugNP.show() # created Bullet Physics World self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) # add debugNode to the world self.world.setDebugNode(self.debugNP.node()) # other setups self.addLights() self.addSky() self.addGround() self.addWalls() self.addStages() self.addSpings() def addSky(self): self.blue_sky_sphere = self.loader.loadModel( "models/blue_sky_sphere/blue_sky_sphere.egg") self.blue_sky_sphere.reparentTo(self.render) self.blue_sky_sphere.setScale(0.04, 0.04, 0.04) self.blue_sky_sphere.setPos(0, 0, 0) def addGround(self): self.garden = self.loader.loadModel("models/garden/garden.egg") self.garden.reparentTo(self.render) self.garden.setScale(2, 2, 2) self.garden.setPos(0, 0, 0) shape = BulletPlaneShape(Vec3(0, 0, 1), 0) floorNP = self.render.attachNewNode(BulletRigidBodyNode('Ground')) floorNP.node().addShape(shape) floorNP.setPos(0, 0, 0) floorNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(floorNP.node()) def addWalls(self): def addWall(size, posX, posY): shape = BulletBoxShape(size) wallNP = self.render.attachNewNode(BulletRigidBodyNode('wall')) wallNP.node().addShape(shape) wallNP.setPos(posX, posY, size.getZ()) wallNP.setCollideMask(BitMask32.allOn()) if (posY is 0): left = -(size.getY()) right = -left pos = left - 5 while pos <= right: wallModel = loader.loadModel('models/fence.egg') wallModel.reparentTo(wallNP) wallModel.setPos(0, pos, -(size.getZ())) wallModel.setScale(1, 1, 1) wallModel.setH(90) pos += 13.5 else: left = -(size.getX()) right = -left pos = left - 5 while pos <= right: wallModel = loader.loadModel('models/fence.egg') wallModel.reparentTo(wallNP) wallModel.setPos(pos, 0, -(size.getZ())) wallModel.setScale(1, 1, 1) pos += 13.5 self.world.attachRigidBody(wallNP.node()) addWall(Vec3(1, 90, 5), 80, 0) addWall(Vec3(1, 90, 5), -80, 0) addWall(Vec3(100, 1, 5), 0, 100) addWall(Vec3(100, 1, 5), 0, -100) def addSpings(self): for pos in SPRING_LIST: print "add spring #{} at: {}".format(len(self.springs), pos) shape = BulletBoxShape(Vec3(0.3, 0.3, 0.8)) node = BulletGhostNode('Spring' + str(len(self.springs))) node.addShape(shape) springNP = self.render.attachNewNode(node) springNP.setCollideMask(BitMask32.allOff()) springNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 3.4) modelNP = loader.loadModel('models/spring/spring.egg') modelNP.reparentTo(springNP) modelNP.setScale(1, 1, 1) modelNP.setPos(0, 0, -1) self.world.attachGhost(node) self.springs.append(springNP) def addStages(self): for stage in STAGE_POS_LIST: boxSize = stage[0] pos = stage[1] name = stage[2] # create a BodyNode and attach to render become a NodePath objNP = self.render.attachNewNode(BulletRigidBodyNode(name)) # attach the BodyNode inside the NodePath to physics world self.world.attachRigidBody(objNP.node()) # set the properties of the NodePath # - shape shape = BulletBoxShape(boxSize) objNP.node().addShape(shape) # - position objNP.setPos(pos.getX(), pos.getY(), pos.getZ()) # - collideMask objNP.setCollideMask(BitMask32.allOn()) # - model objModel = self.loader.loadModel("models/brick-cube/brick.egg") objModel.setScale(boxSize.getX() * 2, boxSize.getY() * 2, boxSize.getZ() * 2) objModel.setPos(0, 0, boxSize.getZ() / -1) objModel.reparentTo(objNP) # - texture ts = TextureStage.getDefault() texture = objModel.getTexture() objModel.setTexOffset(ts, -0.5, -0.5) objModel.setTexScale(ts, boxSize.getX() / 2.0, boxSize.getY() / 2.0, boxSize.getZ() / 2.0) def addLights(self): 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) print "Done Setup Light"