class TestApplication: def __init__(self): self.setupPhysics() self.clock_ = ClockObject() def sim(self): while True: try: time.sleep(LOOP_DELAY) self.clock_.tick() self.physics_world_.doPhysics(self.clock_.getDt(), 5, 1.0/180.0) # printing location of first box print "Box 0: %s"%(str(self.boxes_[0].getPos())) except KeyboardInterrupt: print "Simulation finished" sys.exit() def setupPhysics(self): # setting up physics world and parent node path self.physics_world_ = BulletWorld() self.world_node_ = NodePath() self.physics_world_.setGravity(Vec3(0, 0, -9.81)) # setting up ground self.ground_ = self.world_node_.attachNewNode(BulletRigidBodyNode('Ground')) self.ground_.node().addShape(BulletPlaneShape(Vec3(0, 0, 1), 0)) self.ground_.setPos(0,0,0) self.ground_.setCollideMask(BitMask32.allOn()) self.physics_world_.attachRigidBody(self.ground_.node()) self.boxes_ = [] num_boxes = 20 side_length = 0.2 size = Vec3(side_length,side_length,side_length) start_pos = Vec3(-num_boxes*side_length,0,10) for i in range(0,20): self.addBox("name %i"%(i),size,start_pos + Vec3(i*2*side_length,0,0)) def addBox(self,name,size,pos): # Box (dynamic) box = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) box.node().setMass(1.0) box.node().addShape(BulletBoxShape(size)) box.setPos(pos) box.setCollideMask(BitMask32.allOn()) self.physics_world_.attachRigidBody(box.node()) self.boxes_.append(box)
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) self.setBackgroundColor(0.2,0.2,0.2) self.accept("escape", self.taskMgr.stop) #self.accept("mouse1", self.onClick) #self.accept("mouse2", self.onClick2) self.globalClock = ClockObject() self.addLight() self.liner = LineDrawer(self) self.taskMgr.add(self.update, "update") def update(self, task): self.globalClock.tick() t = self.globalClock.getFrameTime() #print t dt = self.globalClock.getDt() return task.cont def addLight(self): self.render.clearLight() self.lightCenter = self.render.attachNewNode(PandaNode("center")) #self.lightCenter.setCompass() # ambient light self.ambientLight = AmbientLight('ambientLight') self.ambientLight.setColor(Vec4(0.5,0.5,0.5, 1)) self.alight = self.lightCenter.attachNewNode(self.ambientLight) self.render.setLight(self.alight) # point light self.pointlight = PointLight("pLight") self.light = self.lightCenter.attachNewNode(self.pointlight) self.pointlight.setColor(Vec4(0.8,0.8,0.8,1)) self.light.setPos(0,0,2) self.render.setLight(self.light) # directional light self.dirlight = DirectionalLight("dLight") self.dlight = self.lightCenter.attachNewNode(self.dirlight) self.dirlight.setColor(Vec4(0.8,0.8,0.8,1)) self.dirlight.setShadowCaster(True) self.dlight.setPos(0,0,5) self.dlight.lookAt(5,10,0) self.render.setLight(self.dlight) self.render.setShaderAuto()
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) self.setBackgroundColor(0.2, 0.2, 0.2) self.accept("escape", self.taskMgr.stop) #self.accept("mouse1", self.onClick) #self.accept("mouse2", self.onClick2) self.globalClock = ClockObject() self.addLight() self.liner = LineDrawer(self) self.taskMgr.add(self.update, "update") def update(self, task): self.globalClock.tick() t = self.globalClock.getFrameTime() #print t dt = self.globalClock.getDt() return task.cont def addLight(self): self.render.clearLight() self.lightCenter = self.render.attachNewNode(PandaNode("center")) #self.lightCenter.setCompass() # ambient light self.ambientLight = AmbientLight('ambientLight') self.ambientLight.setColor(Vec4(0.5, 0.5, 0.5, 1)) self.alight = self.lightCenter.attachNewNode(self.ambientLight) self.render.setLight(self.alight) # point light self.pointlight = PointLight("pLight") self.light = self.lightCenter.attachNewNode(self.pointlight) self.pointlight.setColor(Vec4(0.8, 0.8, 0.8, 1)) self.light.setPos(0, 0, 2) self.render.setLight(self.light) # directional light self.dirlight = DirectionalLight("dLight") self.dlight = self.lightCenter.attachNewNode(self.dirlight) self.dirlight.setColor(Vec4(0.8, 0.8, 0.8, 1)) self.dirlight.setShadowCaster(True) self.dlight.setPos(0, 0, 5) self.dlight.lookAt(5, 10, 0) self.render.setLight(self.dlight) self.render.setShaderAuto()
class TestApplication(ShowBase): def __init__(self): ShowBase.__init__(self) # game objects self.controlled_obj_index_ = 0 self.level_sectors_ = [] self.controlled_objects_ = [] # active objects self.active_sector_ = None self.setupRendering() self.setupControls() self.setupPhysics() self.clock_ = ClockObject() self.kinematic_mode_ = False # Task logging.info("TestSectors demo started") taskMgr.add(self.update, 'updateWorld') def setupRendering(self): self.setBackgroundColor(0.1, 0.1, 0.8, 1) self.setFrameRateMeter(True) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) self.setupBackgroundImage() def setupBackgroundImage(self): image_file = Filename(rospack.RosPack().get_path(BACKGROUND_IMAGE_PACKAGE) + '/resources/backgrounds/' + BACKGROUND_IMAGE_PATH) # check if image can be loaded img_head = PNMImageHeader() if not img_head.readHeader(image_file ): raise IOError, "PNMImageHeader could not read file %s. Try using absolute filepaths"%(image_file.c_str()) sys.exit() # Load the image with a PNMImage w = img_head.getXSize() h = img_head.getYSize() img = PNMImage(w,h) #img.alphaFill(0) img.read(image_file) texture = Texture() texture.setXSize(w) texture.setYSize(h) texture.setZSize(1) texture.load(img) texture.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image texture.setWrapV(Texture.WM_border_color) texture.setBorderColor(LColor(0,0,0,0)) # creating CardMaker to hold the texture cm = CardMaker('background') cm.setFrame(-0.5*w,0.5*w,-0.5*h,0.5*h) # This configuration places the image's topleft corner at the origin (left, right, bottom, top) background_np = NodePath(cm.generate()) background_np.setTexture(texture) background_np.reparentTo(self.render) background_np.setPos(BACKGROUND_POSITION) background_np.setScale(BACKGROUND_IMAGE_SCALE) def setupControls(self): # Input (Events) self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('n', self.selectNextControlledObject) self.accept('k', self.toggleKinematicMode) # Inputs (Polling) self.input_state_ = InputState() self.input_state_.watchWithModifiers("right","arrow_right") self.input_state_.watchWithModifiers('left', 'arrow_left') self.input_state_.watchWithModifiers('jump', 'arrow_up') self.input_state_.watchWithModifiers('stop', 'arrow_down') self.input_state_.watchWithModifiers('roll_right', 'c') self.input_state_.watchWithModifiers('roll_left', 'z') self.input_state_.watchWithModifiers('roll_stop', 'x') self.title = addTitle("Panda3D: Kinematic Objects") self.inst1 = addInstructions(0.06, "ESC: Quit") self.inst2 = addInstructions(0.12, "Up/Down: Jump/Stop") self.inst3 = addInstructions(0.18, "Left/Right: Move Left / Move Rigth") self.inst4 = addInstructions(0.24, "z/x/c : Rotate Left/ Rotate Stop / Rotate Right") self.inst5 = addInstructions(0.30, "n: Select Next Character") self.inst6 = addInstructions(0.36, "k: Toggle Kinematic Mode") self.inst7 = addInstructions(0.42, "f1: Toggle Wireframe") self.inst8 = addInstructions(0.48, "f2: Toggle Texture") self.inst9 = addInstructions(0.54, "f3: Toggle BulletDebug") self.inst10 = addInstructions(0.60, "f5: Capture Screenshot") def processCollisions(self): contact_manifolds = self.physics_world_.getManifolds() for cm in contact_manifolds: node0 = cm.getNode0() node1 = cm.getNode1() col_mask1 = node0.getIntoCollideMask() col_mask2 = node1.getIntoCollideMask() if (col_mask1 == col_mask2) and \ (col_mask1 == SECTOR_ENTERED_BITMASK) and \ self.active_sector_.getSectorPlaneNode().getName() != node0.getName(): logging.info('Collision between %s and %s'%(node0.getName(),node1.getName())) sector = [s for s in self.level_sectors_ if s.getSectorPlaneNode().getName() == node0.getName()] sector = [s for s in self.level_sectors_ if s.getSectorPlaneNode().getName() == node1.getName()] + sector self.switchToSector(sector[0]) logging.info("Sector %s entered"%(self.active_sector_.getName())) def switchToSector(self,sector): obj_index = self.controlled_obj_index_ character_obj = self.controlled_objects_[obj_index] if self.active_sector_ is not None: self.active_sector_.releaseCharacter() character_obj.setY(sector,0) character_obj.setH(sector,0) self.active_sector_ = sector self.active_sector_.constrainCharacter(character_obj) self.active_sector_.enableDetection(False) sectors = [s for s in self.level_sectors_ if s != self.active_sector_] for s in sectors: s.enableDetection(True) def setupPhysics(self): # setting up physics world and parent node path self.physics_world_ = BulletWorld() self.world_node_ = self.render.attachNewNode('world') self.cam.reparentTo(self.world_node_) self.physics_world_.setGravity(Vec3(0, 0, -9.81)) self.debug_node_ = self.world_node_.attachNewNode(BulletDebugNode('Debug')) self.debug_node_.node().showWireframe(True) self.debug_node_.node().showConstraints(True) self.debug_node_.node().showBoundingBoxes(True) self.debug_node_.node().showNormals(True) self.physics_world_.setDebugNode(self.debug_node_.node()) self.debug_node_.hide() # setting up collision groups self.physics_world_.setGroupCollisionFlag(GAME_OBJECT_BITMASK.getLowestOnBit(),GAME_OBJECT_BITMASK.getLowestOnBit(),True) self.physics_world_.setGroupCollisionFlag(SECTOR_ENTERED_BITMASK.getLowestOnBit(),SECTOR_ENTERED_BITMASK.getLowestOnBit(),True) self.physics_world_.setGroupCollisionFlag(GAME_OBJECT_BITMASK.getLowestOnBit(),SECTOR_ENTERED_BITMASK.getLowestOnBit(),False) # setting up ground self.ground_ = self.world_node_.attachNewNode(BulletRigidBodyNode('Ground')) self.ground_.node().addShape(BulletPlaneShape(Vec3(0, 0, 1), 0)) self.ground_.setPos(0,0,0) self.ground_.setCollideMask(GAME_OBJECT_BITMASK) self.physics_world_.attachRigidBody(self.ground_.node()) # creating level objects self.setupLevelSectors() # creating controlled objects diameter = 0.4 sphere_visual = loader.loadModel('models/ball.egg') bounds = sphere_visual.getTightBounds() # start of model scaling extents = Vec3(bounds[1] - bounds[0]) scale_factor = diameter/max([extents.getX(),extents.getY(),extents.getZ()]) sphere_visual.clearModelNodes() sphere_visual.setScale(scale_factor,scale_factor,scale_factor) # end of model scaling sphere_visual.setTexture(loader.loadTexture('models/bowl.jpg'),1) sphere = NodePath(BulletRigidBodyNode('Sphere')) sphere.node().addShape(BulletSphereShape(0.5*diameter)) sphere.node().setMass(1.0) #sphere.node().setLinearFactor((1,0,1)) #sphere.node().setAngularFactor((0,1,0)) sphere.setCollideMask(GAME_OBJECT_BITMASK) sphere_visual.instanceTo(sphere) self.physics_world_.attachRigidBody(sphere.node()) self.controlled_objects_.append(sphere) sphere.reparentTo(self.world_node_) sphere.setPos(self.level_sectors_[0],Vec3(0,0,diameter+10)) sphere.setHpr(self.level_sectors_[0],Vec3(0,0,0)) # creating bullet ghost for detecting entry into other sectors player_ghost = sphere.attachNewNode(BulletGhostNode('player-ghost-node')) ghost_box_shape = BulletSphereShape(PLAYER_GHOST_DIAMETER/2) ghost_box_shape.setMargin(SECTOR_COLLISION_MARGIN) ghost_sphere_shape = BulletSphereShape(PLAYER_GHOST_DIAMETER*0.5) ghost_sphere_shape.setMargin(SECTOR_COLLISION_MARGIN) player_ghost.node().addShape(ghost_box_shape) player_ghost.setPos(sphere,Vec3(0,0,0)) player_ghost.node().setIntoCollideMask(SECTOR_ENTERED_BITMASK) self.physics_world_.attach(player_ghost.node()) # creating mobile box size = Vec3(0.2,0.2,0.4) mbox_visual = loader.loadModel('models/box.egg') bounds = mbox_visual.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = 1/max([extents.getX(),extents.getY(),extents.getZ()]) mbox_visual.setScale(size.getX()*scale_factor,size.getY()*scale_factor,size.getZ()*scale_factor) mbox = NodePath(BulletRigidBodyNode('MobileBox')) mbox.node().addShape(BulletBoxShape(size/2)) mbox.node().setMass(1.0) #mbox.node().setLinearFactor((1,0,1)) #mbox.node().setAngularFactor((0,1,0)) mbox.setCollideMask(GAME_OBJECT_BITMASK) mbox_visual.instanceTo(mbox) self.physics_world_.attachRigidBody(mbox.node()) self.controlled_objects_.append(mbox) mbox.reparentTo(self.level_sectors_[0]) mbox.setPos(Vec3(1,0,size.getZ()+1)) # switching to sector 1 self.switchToSector(self.level_sectors_[0]) def setupLevelSectors(self): start_pos = Vec3(0,-20,0) for i in range(0,4): sector = Sector('sector' + str(i),self.physics_world_) sector.reparentTo(self.world_node_) #sector.setHpr(Vec3(60*(i+1),0,0)) sector.setHpr(Vec3(90*i,0,0)) sector.setPos(sector,Vec3(0,-20,i*4)) self.level_sectors_.append(sector) sector.setup() def update(self, task): self.clock_.tick() dt = self.clock_.getDt() self.processInput(dt) self.physics_world_.doPhysics(dt, 5, 1.0/180.0) self.processCollisions() self.updateCamera() return task.cont def processInput(self,dt): activate = False obj = self.controlled_objects_[self.controlled_obj_index_] if self.kinematic_mode_: obj.node().setKinematic(True) return else: obj.node().setKinematic(False) vel = self.active_sector_.getRelativeVector(self.world_node_,obj.node().getLinearVelocity()) w = self.active_sector_.getRelativeVector(self.world_node_, obj.node().getAngularVelocity()) vel.setY(0) #w.setX(0) #w.setZ(0) if self.input_state_.isSet('right'): vel.setX(2) activate = True if self.input_state_.isSet('left'): vel.setX(-2) activate = True if self.input_state_.isSet('jump'): vel.setZ(4) activate = True if self.input_state_.isSet('stop'): vel.setX(0) if self.input_state_.isSet('roll_right'): w.setY(ROTATIONAl_SPEED) activate = True if self.input_state_.isSet('roll_left'): w.setY(-ROTATIONAl_SPEED) activate = True if self.input_state_.isSet('roll_stop'): w.setY(0) if activate : obj.node().setActive(True,True) vel = self.world_node_.getRelativeVector(self.active_sector_,vel) w = self.world_node_.getRelativeVector(self.active_sector_,w) obj.node().setLinearVelocity(vel) obj.node().setAngularVelocity(w) #logging.info("Linear Velocity: %s"%(str(vel))) def updateCamera(self): if len(self.controlled_objects_) > 0: obj = self.controlled_objects_[self.controlled_obj_index_] self.cam.setPos(self.active_sector_,obj.getPos(self.active_sector_)) self.cam.setY(self.active_sector_,-CAM_DISTANCE/1) self.cam.lookAt(obj.getParent(),obj.getPos()) def cleanup(self): for i in range(0,len(self.controlled_objects_)): rb = self.controlled_objects_[i] self.physics_world_.removeRigidBody(rb.node()) rb.removeNode() self.object_nodes_ = [] self.controlled_objects_ = [] self.physics_world_.removeRigidBody(self.ground_.node()) self.ground_ = None self.physics_world_ = None self.debug_node_ = None self.cam.reparentTo(self.render) self.world_node_.removeNode() self.world_node_ = None # _____HANDLER_____ def toggleKinematicMode(self): self.kinematic_mode_ = not self.kinematic_mode_ print "Kinematic Mode %s"%('ON' if self.kinematic_mode_ else 'OFF') def selectNextControlledObject(self): self.controlled_obj_index_+=1 if self.controlled_obj_index_ >= len(self.controlled_objects_): self.controlled_obj_index_ = 0 # reset def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setupPhysics() def toggleDebug(self): if self.debug_node_.isHidden(): self.debug_node_.show() else: self.debug_node_.hide() def doScreenshot(self): self.screenshot('Bullet')
class TestGameBase(ShowBase): __CAM_ZOOM__ = 1 __CAM_STEP__ = 0.2 __CAM_ORIENT_STEP__ = 4.0 __BACKGROUND_IMAGE_PACKAGE__ = 'platformer_core' __BACKGROUND_IMAGE_PATH__ = rospack.RosPack().get_path(__BACKGROUND_IMAGE_PACKAGE__) + '/resources/backgrounds/' + 'sky02.png' __BACKGROUND_POSITION__ = Vec3(0,100,0) __BACKGROUND_SCALE__ = 0.2 __DESIRED_FRAME_RATE__ = 1.0/60.0 def __init__(self,name ='TestGameBase'): # configure to use group-mask collision filtering mode in the bullet physics world loadPrcFileData('', 'bullet-filter-algorithm groups-mask') ShowBase.__init__(self) self.name_ = name self.setupRendering() self.setupResources() self.setupControls() self.setupScene() self.clock_ = ClockObject() self.delta_time_accumulator_ = 0.0 # Used to keep simulation time consistent (See https://www.panda3d.org/manual/index.php/Simulating_the_Physics_World) self.desired_frame_rate_ = TestGameBase.__DESIRED_FRAME_RATE__ # Task taskMgr.add(self.update, 'updateWorld') def setupRendering(self): self.setBackgroundColor(0.1, 0.1, 0.8, 1) self.setFrameRateMeter(True) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) self.setupBackgroundImage() def setupBackgroundImage(self): image_file = Filename(TestGameBase.__BACKGROUND_IMAGE_PATH__) # check if image can be loaded img_head = PNMImageHeader() if not img_head.readHeader(image_file ): raise IOError("PNMImageHeader could not read file %s. Try using absolute filepaths"%(image_file.c_str())) sys.exit() # Load the image with a PNMImage w = img_head.getXSize() h = img_head.getYSize() img = PNMImage(w,h) #img.alphaFill(0) img.read(image_file) texture = Texture() texture.setXSize(w) texture.setYSize(h) texture.setZSize(1) texture.load(img) texture.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image texture.setWrapV(Texture.WM_border_color) texture.setBorderColor(LColor(0,0,0,0)) # creating CardMaker to hold the texture cm = CardMaker('background') cm.setFrame(-0.5*w,0.5*w,-0.5*h,0.5*h) # This configuration places the image's topleft corner at the origin (left, right, bottom, top) background_np = NodePath(cm.generate()) background_np.setTexture(texture) background_np.reparentTo(self.render) background_np.setPos(TestGameBase.__BACKGROUND_POSITION__) background_np.setScale(TestGameBase.__BACKGROUND_SCALE__) def setupControls(self): # Input (Events) self.accept('escape', self.exit) self.accept('r', self.doReset) self.accept('f1', self.toggleDebug) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleWireframe) self.accept('f5', self.doScreenshot) self.input_state_ = InputState() button_map = {'a' : KeyboardButtons.KEY_A , 'q' : KeyboardButtons.KEY_Q,'escape' : KeyboardButtons.KEY_ESC, 'f1' : KeyboardButtons.KEY_F1, 'e': KeyboardButtons.KEY_E,'w': KeyboardButtons.KEY_W} self.input_manager_ = KeyboardController(self.input_state_, button_map) # Creating directional moves self.input_manager_.addMove(Move('UP',[KeyboardButtons.DPAD_UP],False,lambda : self.moveCamUp())) self.input_manager_.addMove(Move('DOWN',[KeyboardButtons.DPAD_DOWN],False,lambda : self.moveCamDown())) self.input_manager_.addMove(Move('LEFT',[KeyboardButtons.DPAD_LEFT],False,lambda : self.moveCamLeft())) self.input_manager_.addMove(Move('RIGHT',[KeyboardButtons.DPAD_RIGHT],False,lambda : self.moveCamRight())) self.input_manager_.addMove(Move('ROTATE_LEFT',[KeyboardButtons.KEY_E],False,lambda : self.rotateCamZCounterClockwise())) self.input_manager_.addMove(Move('ROTATE_RIGHT',[KeyboardButtons.KEY_W],False,lambda : self.rotateCamZClockwise())) self.input_manager_.addMove(Move('ZoomIn',[KeyboardButtons.KEY_Q],False,lambda : self.zoomIn())) self.input_manager_.addMove(Move('ZoomOut',[KeyboardButtons.KEY_A],False,lambda : self.zoomOut())) self.title = self.createTitle("Panda3D: " + self.name_) self.instructions_ = [ self.createInstruction(0.06, "ESC: Quit"), self.createInstruction(0.12, "Up/Down: Move Camera Up/Down"), self.createInstruction(0.18, "Left/Right: Move Camera Left / Rigth"), self.createInstruction(0.24, "q/a: Zoom in / Zoom out"), self.createInstruction(0.30, "F1: Toggle Debug"), self.createInstruction(0.36, "F2: Toggle Texture"), self.createInstruction(0.42, "F3: Toggle Wireframe"), self.createInstruction(0.48, "F5: Screenshot") ] def setupScene(self): self.level_ = TestLevel('ground-zero') self.level_.reparentTo(self.render) # enable debug visuals self.debug_node_ = self.level_.attachNewNode(BulletDebugNode('Debug')) self.debug_node_.node().showWireframe(True) self.debug_node_.node().showConstraints(True) self.debug_node_.node().showBoundingBoxes(False) self.debug_node_.node().showNormals(True) self.level_.getPhysicsWorld().setDebugNode(self.debug_node_.node()) self.debug_node_.hide() self.cam.reparentTo(self.level_) self.cam.setPos(self.level_,0, -TestGameBase.__CAM_ZOOM__*24, TestGameBase.__CAM_STEP__*25) self.camera_controller_ = CameraController(self.cam) def setupResources(self): pass def cleanup(self): self.level_.detachNode() self.level_ = None self.input_manager_ = None def update(self,task): self.clock_.tick() dt = self.clock_.getDt() self.delta_time_accumulator_ += dt while self.delta_time_accumulator_ > self.desired_frame_rate_: self.delta_time_accumulator_ -= self.desired_frame_rate_ self.level_.update(self.desired_frame_rate_) self.input_manager_.update(self.desired_frame_rate_) self.camera_controller_.update(self.desired_frame_rate_) StateMachine.processEvents() return task.cont # __ CAM_METHODS __ def moveCamUp(self): self.cam.setPos(self.cam.getPos() + Vec3(0, 0,TestGameBase.__CAM_STEP__)) def moveCamDown(self): self.cam.setPos(self.cam.getPos() + Vec3(0, 0,-TestGameBase.__CAM_STEP__)) def moveCamRight(self): self.cam.setPos(self.cam.getPos() + Vec3(TestGameBase.__CAM_STEP__,0,0)) def moveCamLeft(self): self.cam.setPos(self.cam.getPos() + Vec3(-TestGameBase.__CAM_STEP__,0,0)) def rotateCamZClockwise(self): self.cam.setH(self.cam.getH() + TestGameBase.__CAM_ORIENT_STEP__) def rotateCamZCounterClockwise(self): self.cam.setH(self.cam.getH() + -TestGameBase.__CAM_ORIENT_STEP__) def zoomIn(self): self.cam.setY(self.cam.getY()+TestGameBase.__CAM_ZOOM__) def zoomOut(self): self.cam.setY(self.cam.getY()-TestGameBase.__CAM_ZOOM__) def toggleDebug(self): if self.debug_node_.isHidden(): self.debug_node_.show() else: self.debug_node_.hide() def doReset(self): logging.warn("Reset Not implemented") pass def doScreenshot(self): self.screenshot('Pand3d') # __ END OF CAM METHODS __ # SUPPORT METHODS def createInstruction(self,pos, msg): return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05, shadow=(0, 0, 0, 1), parent=base.a2dTopLeft, pos=(0.08, -pos - 0.04), align=TextNode.ALeft) # Function to put title on the screen. def createTitle(self,text): return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=.08, parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-0.1, 0.09), shadow=(0, 0, 0, 1)) def exit(self): self.cleanup() sys.exit(1)
class TestApplication(ShowBase): def __init__(self): ShowBase.__init__(self) self.setupRendering() self.setupControls() self.setupPhysics() self.clock_ = ClockObject() self.controlled_obj_index_ = 0 self.kinematic_mode_ = False # Task taskMgr.add(self.update, 'updateWorld') def setupRendering(self): self.setBackgroundColor(0.1, 0.1, 0.8, 1) self.setFrameRateMeter(True) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) def setupControls(self): # Input (Events) self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('n', self.selectNextControlledObject) self.accept('k',self.toggleKinematicMode) self.accept('p',self.printInfo) self.accept('q',self.zoomIn) self.accept('a',self.zoomOut) self.accept('s',self.toggleRightLeft) # Inputs (Polling) self.input_state_ = InputState() self.input_state_.watchWithModifiers("right","arrow_right") self.input_state_.watchWithModifiers('left', 'arrow_left') self.input_state_.watchWithModifiers('jump', 'arrow_up') self.input_state_.watchWithModifiers('stop', 'arrow_down') self.input_state_.watchWithModifiers('roll_right', 'c') self.input_state_.watchWithModifiers('roll_left', 'z') self.input_state_.watchWithModifiers('roll_stop', 'x') self.title = addTitle("Panda3D: Sprite Animation") self.inst1 = addInstructions(0.06, "ESC: Quit") self.inst2 = addInstructions(0.12, "Up/Down: Jump/Stop") self.inst3 = addInstructions(0.18, "Left/Right: Move Left / Move Rigth") self.inst4 = addInstructions(0.24, "z/x/c : Rotate Left/ Rotate Stop / Rotate Right") self.inst5 = addInstructions(0.30, "n: Select Next Character") self.inst6 = addInstructions(0.36, "k: Toggle Kinematic Mode") self.inst7 = addInstructions(0.42, "q/a: Zoom in / Zoom out") self.inst7 = addInstructions(0.48, "s: Toggle Rigth|Left ") self.inst7 = addInstructions(0.54, "p: Print Info") def printInfo(self): self.sprt_animator_.printInfo() def setupPhysics(self): # setting up physics world and parent node path self.physics_world_ = BulletWorld() self.world_node_ = self.render.attachNewNode('world') self.cam.reparentTo(self.world_node_) self.physics_world_.setGravity(Vec3(0, 0, -9.81)) self.debug_node_ = self.world_node_.attachNewNode(BulletDebugNode('Debug')) self.debug_node_.show() self.debug_node_.node().showWireframe(True) self.debug_node_.node().showConstraints(True) self.debug_node_.node().showBoundingBoxes(False) self.debug_node_.node().showNormals(True) # setting up ground self.ground_ = self.world_node_.attachNewNode(BulletRigidBodyNode('Ground')) self.ground_.node().addShape(BulletPlaneShape(Vec3(0, 0, 1), 0)) self.ground_.setPos(0,0,0) self.ground_.setCollideMask(BitMask32.allOn()) self.physics_world_.attachRigidBody(self.ground_.node()) self.object_nodes_ = [] self.controlled_objects_=[] num_boxes = 20 side_length = 0.2 size = Vec3(0.5*side_length,0.5*side_length,0.5*side_length) start_pos = Vec3(-num_boxes*side_length,0,6) """ # creating boxes box_visual = loader.loadModel('models/box.egg') box_visual.clearModelNodes() box_visual.setTexture(loader.loadTexture('models/wood.png')) bounds = box_visual.getTightBounds() # start of box model scaling extents = Vec3(bounds[1] - bounds[0]) scale_factor = side_length/max([extents.getX(),extents.getY(),extents.getZ()]) box_visual.setScale((scale_factor,scale_factor ,scale_factor)) # end of box model scaling for i in range(0,20): self.addBox("name %i"%(i),size,start_pos + Vec3(i*side_length,0,0),box_visual) start_pos = Vec3(-num_boxes*side_length,0,8) for i in range(0,20): self.addBox("name %i"%(i),size,start_pos + Vec3(i*2*side_length,0,0),box_visual) """ # creating sprite animator sprt_animator = SpriteAnimator('hiei_run') if not sprt_animator.loadImage(SPRITE_IMAGE_DETAILS[0], # file path SPRITE_IMAGE_DETAILS[1], # columns SPRITE_IMAGE_DETAILS[2], # rows SPRITE_IMAGE_DETAILS[3], # scale x SPRITE_IMAGE_DETAILS[4], # scale y SPRITE_IMAGE_DETAILS[5]): # frame rate print "Error loading image %s"%(SPRITE_IMAGE_DETAILS[0]) sys.exit(1) self.sprt_animator_ = sprt_animator # creating Mobile Character Box size = Vec3(0.5,0.2,1) mbox_visual = loader.loadModel('models/box.egg') bounds = mbox_visual.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = 1/max([extents.getX(),extents.getY(),extents.getZ()]) mbox_visual.setScale(size.getX()*scale_factor,size.getY()*scale_factor,size.getZ()*scale_factor) mbox = self.world_node_.attachNewNode(BulletRigidBodyNode('CharacterBox')) mbox.node().addShape(BulletBoxShape(size/2)) mbox.node().setMass(1.0) mbox.node().setLinearFactor((1,0,1)) mbox.node().setAngularFactor((0,1,0)) mbox.setCollideMask(BitMask32.allOn()) mbox_visual.instanceTo(mbox) mbox_visual.hide() mbox.setPos(Vec3(1,0,size.getZ()+1)) bounds = sprt_animator.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = size.getZ()/extents.getZ() sprt_animator.setScale(scale_factor,1,scale_factor) sprt_animator.reparentTo(mbox) bounds = sprt_animator.getTightBounds() print "Sprite Animator bounds %s , %s"%(str(bounds[1]),str(bounds[0])) self.physics_world_.attachRigidBody(mbox.node()) self.object_nodes_.append(mbox) self.controlled_objects_.append(mbox) # creating sphere diameter = 0.4 sphere_visual = loader.loadModel('models/ball.egg') bounds = sphere_visual.getTightBounds() # start of model scaling extents = Vec3(bounds[1] - bounds[0]) scale_factor = diameter/max([extents.getX(),extents.getY(),extents.getZ()]) sphere_visual.clearModelNodes() sphere_visual.setScale(scale_factor,scale_factor,scale_factor) # end of model scaling sphere_visual.setTexture(loader.loadTexture('models/bowl.jpg')) sphere = self.world_node_.attachNewNode(BulletRigidBodyNode('Sphere')) sphere.node().addShape(BulletSphereShape(0.5*diameter)) sphere.node().setMass(1.0) sphere.node().setLinearFactor((1,0,1)) sphere.node().setAngularFactor((0,1,0)) sphere.setCollideMask(BitMask32.allOn()) sphere_visual.instanceTo(sphere) sphere.setPos(Vec3(0,0,size.getZ()+1)) self.physics_world_.attachRigidBody(sphere.node()) self.object_nodes_.append(sphere) self.controlled_objects_.append(sphere) self.setupLevel() def addBox(self,name,size,pos,visual): # Box (dynamic) box = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) box.node().setMass(1.0) box.node().addShape(BulletBoxShape(size)) box.setPos(pos) box.setCollideMask(BitMask32.allOn()) box.node().setLinearFactor((1,0,1)) box.node().setAngularFactor((0,1,0)) visual.instanceTo(box) self.physics_world_.attachRigidBody(box.node()) self.object_nodes_.append(box) def setupLevel(self): # (left, top, length ,depth(y) ,height) platform_details =[ (-20, 4, 20, 4, 1 ), (-2, 5, 10, 4, 1 ), ( 4 , 2 , 16, 4, 1.4), (-4 , 1, 10, 4, 1), ( 16, 6, 30, 4, 1) ] for i in range(0,len(platform_details)): p = platform_details[i] topleft = (p[0],p[1]) size = Vec3(p[2],p[3],p[4]) self.addPlatform(topleft, size,'Platform%i'%(i)) def addPlatform(self,topleft,size,name): # Visual visual = loader.loadModel('models/box.egg') visual.setTexture(loader.loadTexture('models/iron.jpg')) bounds = visual.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = 1/max([extents.getX(),extents.getY(),extents.getZ()]) visual.setScale(size.getX()*scale_factor,size.getY()*scale_factor,size.getZ()*scale_factor) # Box (static) platform = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) platform.node().setMass(0) platform.node().addShape(BulletBoxShape(size/2)) platform.setPos(Vec3(topleft[0] + 0.5*size.getX(),0,topleft[1]-0.5*size.getZ())) platform.setCollideMask(BitMask32.allOn()) visual.instanceTo(platform) self.physics_world_.attachRigidBody(platform.node()) self.object_nodes_.append(platform) def update(self, task): self.clock_.tick() dt = self.clock_.getDt() self.processInput(dt) self.physics_world_.doPhysics(dt, 5, 1.0/180.0) self.updateCamera() return task.cont def processInput(self,dt): activate = False obj = self.controlled_objects_[self.controlled_obj_index_] if self.kinematic_mode_: obj.node().setKinematic(True) return else: obj.node().setKinematic(False) vel = obj.node().getLinearVelocity() w = obj.node().getAngularVelocity() if self.input_state_.isSet('right'): vel.setX(2) activate = True if self.input_state_.isSet('left'): vel.setX(-2) activate = True if self.input_state_.isSet('jump'): vel.setZ(4) activate = True if self.input_state_.isSet('stop'): vel.setX(0) if self.input_state_.isSet('roll_right'): w.setY(ROTATIONAl_SPEED) activate = True if self.input_state_.isSet('roll_left'): w.setY(-ROTATIONAl_SPEED) activate = True if self.input_state_.isSet('roll_stop'): w.setY(0) if activate : obj.node().setActive(True,True) obj.node().setLinearVelocity(vel) obj.node().setAngularVelocity(w) def updateCamera(self): if len(self.controlled_objects_) > 0: obj = self.controlled_objects_[self.controlled_obj_index_] self.cam.setPos(obj,0, -CAM_DISTANCE, 0) self.cam.lookAt(obj.getPos()) def cleanup(self): for i in range(0,len(self.object_nodes_)): rb = self.object_nodes_[i] self.physics_world_.removeRigidBody(rb.node()) self.object_nodes_ = [] self.controlled_objects_ = [] self.physics_world_.removeRigidBody(self.ground_.node()) self.ground_ = None self.physics_world_ = None self.debug_node_ = None self.sprt_animator_ = None self.cam.reparentTo(self.render) self.world_node_.removeNode() self.world_node_ = None # _____HANDLER_____ def zoomIn(self): global CAM_DISTANCE CAM_DISTANCE-=4 def zoomOut(self): global CAM_DISTANCE CAM_DISTANCE+=4 def toggleKinematicMode(self): self.kinematic_mode_ = not self.kinematic_mode_ print "Kinematic Mode %s"%('ON' if self.kinematic_mode_ else 'OFF') def toggleRightLeft(self): self.sprt_animator_.faceRight(not self.sprt_animator_.facing_right_) def selectNextControlledObject(self): self.controlled_obj_index_+=1 if self.controlled_obj_index_ >= len(self.controlled_objects_): self.controlled_obj_index_ = 0 # reset def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setupPhysics() def toggleDebug(self): if self.debug_node_.isHidden(): self.debug_node_.show() else: self.debug_node_.hide() def doScreenshot(self): self.screenshot('Bullet')
class TestApplication(ShowBase): def __init__(self): ShowBase.__init__(self) self.setupRendering() self.setupControls() self.setupPhysics() #self.cam.reparentTo(self.world_node_) self.clock_ = ClockObject() self.controlled_obj_index_ = 0 self.kinematic_mode_ = False # Task taskMgr.add(self.update, 'updateWorld') def setupRendering(self): self.setBackgroundColor(0.1, 0.1, 0.8, 1) self.setFrameRateMeter(True) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) self.setupBackgroundImage() def setupBackgroundImage(self): image_file = Filename(rospack.RosPack().get_path(BACKGROUND_IMAGE_PACKAGE) + '/resources/backgrounds/' + BACKGROUND_IMAGE_PATH) # check if image can be loaded img_head = PNMImageHeader() if not img_head.readHeader(image_file ): raise IOError, "PNMImageHeader could not read file %s. Try using absolute filepaths"%(image_file.c_str()) sys.exit() # Load the image with a PNMImage w = img_head.getXSize() h = img_head.getYSize() img = PNMImage(w,h) #img.alphaFill(0) img.read(image_file) texture = Texture() texture.setXSize(w) texture.setYSize(h) texture.setZSize(1) texture.load(img) texture.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image texture.setWrapV(Texture.WM_border_color) texture.setBorderColor(LColor(0,0,0,0)) # creating CardMaker to hold the texture cm = CardMaker('background') cm.setFrame(-0.5*w,0.5*w,-0.5*h,0.5*h) # This configuration places the image's topleft corner at the origin (left, right, bottom, top) background_np = NodePath(cm.generate()) background_np.setTexture(texture) background_np.reparentTo(self.render) background_np.setPos(BACKGROUND_POSITION) background_np.setScale(BACKGROUND_IMAGE_SCALE) def setupControls(self): # Input (Events) self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('n', self.selectNextControlledObject) self.accept('k', self.toggleKinematicMode) # Inputs (Polling) self.input_state_ = InputState() self.input_state_.watchWithModifiers("right","arrow_right") self.input_state_.watchWithModifiers('left', 'arrow_left') self.input_state_.watchWithModifiers('jump', 'arrow_up') self.input_state_.watchWithModifiers('stop', 'arrow_down') self.input_state_.watchWithModifiers('roll_right', 'c') self.input_state_.watchWithModifiers('roll_left', 'z') self.input_state_.watchWithModifiers('roll_stop', 'x') self.title = addTitle("Panda3D: Kinematic Objects") self.inst1 = addInstructions(0.06, "ESC: Quit") self.inst2 = addInstructions(0.12, "Up/Down: Jump/Stop") self.inst3 = addInstructions(0.18, "Left/Right: Move Left / Move Rigth") self.inst4 = addInstructions(0.24, "z/x/c : Rotate Left/ Rotate Stop / Rotate Right") self.inst5 = addInstructions(0.30, "n: Select Next Character") self.inst6 = addInstructions(0.36, "k: Toggle Kinematic Mode") self.inst7 = addInstructions(0.42, "f1: Toggle Wireframe") self.inst8 = addInstructions(0.48, "f2: Toggle Texture") self.inst9 = addInstructions(0.54, "f3: Toggle BulletDebug") self.inst10 = addInstructions(0.60, "f5: Capture Screenshot") def setupPhysics(self): # setting up physics world and parent node path self.physics_world_ = BulletWorld() self.world_node_ = self.render.attachNewNode('world') self.cam.reparentTo(self.world_node_) self.physics_world_.setGravity(Vec3(0, 0, -9.81)) self.debug_node_ = self.world_node_.attachNewNode(BulletDebugNode('Debug')) self.debug_node_.node().showWireframe(True) self.debug_node_.node().showConstraints(True) self.debug_node_.node().showBoundingBoxes(True) self.debug_node_.node().showNormals(True) self.physics_world_.setDebugNode(self.debug_node_.node()) self.debug_node_.hide() # setting up ground self.ground_ = self.world_node_.attachNewNode(BulletRigidBodyNode('Ground')) self.ground_.node().addShape(BulletPlaneShape(Vec3(0, 0, 1), 0)) self.ground_.setPos(0,0,0) self.ground_.setCollideMask(BitMask32.allOn()) self.physics_world_.attachRigidBody(self.ground_.node()) self.object_nodes_ = [] self.controlled_objects_=[] num_boxes = 20 side_length = 0.2 size = Vec3(0.5*side_length,0.5*side_length,0.5*side_length) start_pos = Vec3(-num_boxes*side_length,0,6) # creating boxes box_visual = loader.loadModel('models/box.egg') box_visual.clearModelNodes() box_visual.setTexture(loader.loadTexture('models/wood.png')) #box_visual.setRenderModeWireframe() bounds = box_visual.getTightBounds() # start of box model scaling extents = Vec3(bounds[1] - bounds[0]) scale_factor = side_length/max([extents.getX(),extents.getY(),extents.getZ()]) box_visual.setScale((scale_factor,scale_factor ,scale_factor)) # end of box model scaling for i in range(0,20): self.addBox("name %i"%(i),size,start_pos + Vec3(i*side_length,0,0),box_visual) start_pos = Vec3(-num_boxes*side_length,0,8) for i in range(0,20): self.addBox("name %i"%(i),size,start_pos + Vec3(i*2*side_length,0,0),box_visual) # creating sphere diameter = 0.4 sphere_visual = loader.loadModel('models/ball.egg') bounds = sphere_visual.getTightBounds() # start of model scaling extents = Vec3(bounds[1] - bounds[0]) scale_factor = diameter/max([extents.getX(),extents.getY(),extents.getZ()]) sphere_visual.clearModelNodes() sphere_visual.setScale(scale_factor,scale_factor,scale_factor) # end of model scaling sphere_visual.setTexture(loader.loadTexture('models/bowl.jpg')) sphere = self.world_node_.attachNewNode(BulletRigidBodyNode('Sphere')) sphere.node().addShape(BulletSphereShape(0.5*diameter)) sphere.node().setMass(1.0) sphere.node().setLinearFactor((1,0,1)) sphere.node().setAngularFactor((0,1,0)) sphere.setCollideMask(BitMask32.allOn()) sphere_visual.instanceTo(sphere) sphere.setPos(Vec3(0,0,size.getZ()+1)) self.physics_world_.attachRigidBody(sphere.node()) self.object_nodes_.append(sphere) self.controlled_objects_.append(sphere) # creating mobile box size = Vec3(0.2,0.2,0.4) mbox_visual = loader.loadModel('models/box.egg') bounds = mbox_visual.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = 1/max([extents.getX(),extents.getY(),extents.getZ()]) mbox_visual.setScale(size.getX()*scale_factor,size.getY()*scale_factor,size.getZ()*scale_factor) mbox = self.world_node_.attachNewNode(BulletRigidBodyNode('MobileBox')) mbox.node().addShape(BulletBoxShape(size/2)) mbox.node().setMass(1.0) mbox.node().setLinearFactor((1,0,1)) mbox.node().setAngularFactor((0,1,0)) mbox.setCollideMask(BitMask32.allOn()) mbox_visual.instanceTo(mbox) mbox.setPos(Vec3(1,0,size.getZ()+1)) self.physics_world_.attachRigidBody(mbox.node()) self.object_nodes_.append(mbox) self.controlled_objects_.append(mbox) self.setupLevel() # Nodepath test np = NodePath('testnode0') print('Created Nodepath to node %s'%(np.getName())) np.clear() #np.attachNewNode(PandaNode('testnode1')) np.__init__(PandaNode('testnode1')) print('Attached new node %s to empty Nodepath'%(np.getName())) def addBox(self,name,size,pos,visual): # Box (dynamic) box = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) box.node().setMass(1.0) box.node().addShape(BulletBoxShape(size)) box.setPos(pos) box.setCollideMask(BitMask32.allOn()) box.node().setLinearFactor((1,0,1)) box.node().setAngularFactor((0,1,0)) visual.instanceTo(box) self.physics_world_.attachRigidBody(box.node()) self.object_nodes_.append(box) def setupLevel(self): # (left, top, length ,depth(y) ,height) platform_details =[ (-20, 4, 20, 4, 1 ), (-2, 5, 10, 4, 1 ), ( 4 , 2 , 16, 4, 1.4), (-4 , 1, 10, 4, 1), ( 16, 6, 30, 4, 1) ] # Platform Visuals visual = loader.loadModel('models/box.egg') visual.setTexture(loader.loadTexture('models/iron.jpg')) for i in range(0,len(platform_details)): p = platform_details[i] topleft = (p[0],p[1]) size = Vec3(p[2],p[3],p[4]) self.addPlatform(topleft, size,'Platform%i'%(i),visual) def addPlatform(self,topleft,size,name,visual): # Box (static) platform = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) platform.node().setMass(0) platform.node().addShape(BulletBoxShape(size/2)) platform.setPos(Vec3(topleft[0] + 0.5*size.getX(),0,topleft[1]-0.5*size.getZ())) platform.setCollideMask(BitMask32.allOn()) local_visual = visual.instanceUnderNode(platform,name + '_visual') # Visual scaling bounds = local_visual.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = 1/max([extents.getX(),extents.getY(),extents.getZ()]) local_visual.setScale(size.getX()*scale_factor,size.getY()*scale_factor,size.getZ()*scale_factor) self.physics_world_.attachRigidBody(platform.node()) self.object_nodes_.append(platform) def update(self, task): self.clock_.tick() dt = self.clock_.getDt() self.processInput(dt) self.physics_world_.doPhysics(dt, 5, 1.0/180.0) self.updateCamera() return task.cont def processInput(self,dt): activate = False obj = self.controlled_objects_[self.controlled_obj_index_] if self.kinematic_mode_: obj.node().setKinematic(True) return else: obj.node().setKinematic(False) vel = obj.node().getLinearVelocity() w = obj.node().getAngularVelocity() if self.input_state_.isSet('right'): vel.setX(2) activate = True if self.input_state_.isSet('left'): vel.setX(-2) activate = True if self.input_state_.isSet('jump'): vel.setZ(4) activate = True if self.input_state_.isSet('stop'): vel.setX(0) if self.input_state_.isSet('roll_right'): w.setY(ROTATIONAl_SPEED) activate = True if self.input_state_.isSet('roll_left'): w.setY(-ROTATIONAl_SPEED) activate = True if self.input_state_.isSet('roll_stop'): w.setY(0) if activate : obj.node().setActive(True,True) obj.node().setLinearVelocity(vel) obj.node().setAngularVelocity(w) def updateCamera(self): if len(self.controlled_objects_) > 0: obj = self.controlled_objects_[self.controlled_obj_index_] self.cam.setPos(obj,0, -CAM_DISTANCE, 0) self.cam.lookAt(obj.getPos()) def cleanup(self): for i in range(0,len(self.object_nodes_)): rb = self.object_nodes_[i] self.physics_world_.removeRigidBody(rb.node()) self.object_nodes_ = [] self.controlled_objects_ = [] self.physics_world_.removeRigidBody(self.ground_.node()) self.ground_ = None self.physics_world_ = None self.debug_node_ = None self.cam.reparentTo(self.render) self.world_node_.removeNode() self.world_node_ = None # _____HANDLER_____ def toggleKinematicMode(self): self.kinematic_mode_ = not self.kinematic_mode_ print "Kinematic Mode %s"%('ON' if self.kinematic_mode_ else 'OFF') def selectNextControlledObject(self): self.controlled_obj_index_+=1 if self.controlled_obj_index_ >= len(self.controlled_objects_): self.controlled_obj_index_ = 0 # reset def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setupPhysics() def toggleDebug(self): if self.debug_node_.isHidden(): self.debug_node_.show() else: self.debug_node_.hide() def doScreenshot(self): self.screenshot('Bullet')
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) """ SETUP CONFIG VARS """ # self.render.setShaderAuto() self.globalClock = ClockObject().getGlobalClock() self.bullet_world = BulletWorld() self.bullet_world.setGravity((0, 0, -9.81)) """ PLAYER SETUP """ # player camera self.ref_node = self.render.attachNewNode('camparent') self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.player_body_geom = make_cube_geom(geom_color=(1, 0, 0, 1)) player_body_geom_node = GeomNode('player') player_body_geom_node.addGeom(self.player_body_geom) self.player_body_geom_np = self.render.attachNewNode(player_body_geom_node) # Box shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) self.box_np = self.render.attachNewNode(BulletRigidBodyNode('Box')) self.box_np.node().setMass(1.0) self.box_np.node().addShape(shape) self.box_np.node().setDeactivationEnabled(False) self.player_body_geom_np.reparentTo(self.box_np) self.box_np.setPos(10, 10, 10) self.box_np.setCollideMask(BitMask32.allOn()) self.bullet_world.attachRigidBody(self.box_np.node()) # TODO: move player stuff to a new class # TODO: add cross hairs on player hud self.player_ray_end = NodePath('player-ray') self.player_ray_end.reparentTo(self.render) self.player_ray_end.reparentTo(self.ref_node) self.player_ray_end.setY(+10) # put this in front of the player self.ref_node.lookAt(self.player_ray_end) """ SETUP VARS AND USE UTIL CLASSES """ self.map_scale = 10 self.map_size = 100 self.camLens.setFov(90) total_size = 32 * 8 PlayerMovement(self) World(self, n_grids=32) # self.ref_node.reparentTo(self.box_np) """ SKY BOX SETUP """ skybox = GeomNode('skybox') skybox.addGeom(make_cube_geom(pos=(0, 0, 0), geom_color=(0.2, 0.2, 0.7, 1))) skybox_np = self.render.attachNewNode(skybox) skybox_np.reparentTo(self.ref_node) skybox_np.setPos((0, 1200, 0)) skybox_np.setScale(1200) """ ADD LIGHTS """ # ambient light ambientLight = AmbientLight('ambientLight') ambientLight.setColor((0.2, 0.2, 0.2, 1)) ambientLightNP = self.render.attachNewNode(ambientLight) self.render.setLight(ambientLightNP) # a geom to represent the sun sun_geom_node = GeomNode('sun') sun_geom_node.addGeom(make_cube_geom(geom_color=(0.5, 0.5, 0.3, 1))) sun_geom_node_path = self.render.attachNewNode(sun_geom_node) sun_geom_node_path.setScale(10) # sun sun = PointLight('sun') sun.setColor((0.4, 0.3, 0.27, 1)) sun.setAttenuation((0.1, 0, 0)) sun_np = self.render.attachNewNode(sun) sun_geom_node_path.reparentTo(sun_np) self.render.setLight(sun_np) sun_np.setPos(total_size / 2, total_size / 2, 200) """ SETUP FOR ONSCREEN TEXT """ # TODO: add chunk coords to display self.text = OnscreenText(text='fps', pos=(-1, -0.95), fg=(0, 1, 0, 1), align=TextNode.ALeft, scale=0.1) self.location_text = OnscreenText(text='location', pos=(-1, 0.8), fg=(0, 1, 0, 1), align=TextNode.ALeft, scale=0.1) self.previous_time = time.time() self.taskMgr.add(self.update_text, 'fps') self.taskMgr.add(self.update, 'physics') def update_text(self, task): time_since_last_called = time.time() - self.previous_time self.text.setText('fps: ' + str(round(1 / time_since_last_called))) self.previous_time = time.time() x, y, z = self.ref_node.getPos() self.location_text.setText(f'Player location x: {round(x)}, y: {round(y)}, z: {round(z)},') return task.cont def update(self, task): dt = self.globalClock.getDt() self.bullet_world.doPhysics(dt, 10, 0.008) return task.cont
class TestKeyboardController(ShowBase): def __init__(self): ShowBase.__init__(self) self.clock_ = ClockObject() self.setupInput() taskMgr.add(self.update,"update") def update(self,task): self.clock_.tick() dt = self.clock_.getDt() self.input_manager_.update(dt) return task.cont def exitCallback(self): sys.exit(0) def setupInput(self): self.input_state_ = InputState() # Creating button map button_map = {'a' : KeyboardButtons.KEY_A , 'q' : KeyboardButtons.KEY_Q, 's' : KeyboardButtons.KEY_S , 'w' : KeyboardButtons.KEY_W, 'd' : KeyboardButtons.KEY_D , 'e' : KeyboardButtons.KEY_E, 'x' : KeyboardButtons.KEY_X , 'c' : KeyboardButtons.KEY_C, 'space' : KeyboardButtons.KEY_SPACE , 'shift' : KeyboardButtons.KEY_SHIFT, 'escape' : KeyboardButtons.KEY_ESC} self.input_manager_ = KeyboardController(self.input_state_, button_map) # Creating directional moves self.input_manager_.addMove(Move('UP',[KeyboardButtons.DPAD_UP],True)) self.input_manager_.addMove(Move('DOWN',[KeyboardButtons.DPAD_DOWN],True)) self.input_manager_.addMove(Move('LEFT',[KeyboardButtons.DPAD_LEFT],True)) self.input_manager_.addMove(Move('RIGHT',[KeyboardButtons.DPAD_RIGHT],True)) self.input_manager_.addMove(Move('DOWN_RIGHT',[KeyboardButtons.DPAD_DOWNRIGHT],True)) self.input_manager_.addMove(Move('DOWN_LEFT',[KeyboardButtons.DPAD_DOWNLEFT],True)) self.input_manager_.addMove(Move('UP_LEFT',[KeyboardButtons.DPAD_UPLEFT],True)) self.input_manager_.addMove(Move('UP_RIGHT',[KeyboardButtons.DPAD_UPRIGHT],True)) # Creating action moves self.input_manager_.addMove(Move('JUMP',[KeyboardButtons.KEY_A],True)) self.input_manager_.addMove(Move('DASH',[KeyboardButtons.KEY_S],True)) self.input_manager_.addMove(Move('LIGHT ATTACK',[KeyboardButtons.KEY_D],True)) self.input_manager_.addMove(Move('FUERTE ATTACK',[KeyboardButtons.KEY_E],True)) # released moves self.input_manager_.addMove(Move('RELEASE_UP',[KeyboardButtons.DPAD_UP],True),False) self.input_manager_.addMove(Move('RELEASE_DOWN',[KeyboardButtons.DPAD_DOWN],True),False) self.input_manager_.addMove(Move('RELEASE_LEFT',[KeyboardButtons.DPAD_LEFT],True),False) self.input_manager_.addMove(Move('RELEASE_RIGHT',[KeyboardButtons.DPAD_RIGHT],True),False) self.input_manager_.addMove(Move('RELEASE FUERTE ATTACK',[KeyboardButtons.KEY_E],True),False) self.input_manager_.addMove(Move('RELEASE LIGHT ATTACK',[KeyboardButtons.KEY_D],True),False) # exit self.input_manager_.addMove(Move('SPECIAL ATTACK',[KeyboardButtons.KEY_D, KeyboardButtons.KEY_E],False,lambda : self.exitCallback())) # Creating special moves self.input_manager_.addMove(Move('EXIT',[KeyboardButtons.KEY_ESC],False,lambda : self.exitCallback())) self.input_manager_.addMove(Move('RIGHT ABUKE PRO',[KeyboardButtons.DPAD_DOWN, KeyboardButtons.DPAD_DOWNRIGHT, KeyboardButtons.DPAD_RIGHT, KeyboardButtons.DPAD_RIGHT | KeyboardButtons.KEY_D],False, lambda : sys.stdout.write("-----> RIGHT ABUKE\n"))) self.input_manager_.addMove(Move('LEFT ABUKE PRO',[KeyboardButtons.DPAD_DOWN, KeyboardButtons.DPAD_DOWNLEFT, KeyboardButtons.DPAD_LEFT, KeyboardButtons.DPAD_LEFT | KeyboardButtons.KEY_D],False, lambda : sys.stdout.write("-----> LEFT ABUKE \n")))
class TestJoystickController(ShowBase): def __init__(self): ShowBase.__init__(self) self.clock_ = ClockObject() self.setupInput() taskMgr.add(self.update,"update") def update(self,task): self.clock_.tick() dt = self.clock_.getDt() pygame.event.get() self.joystick_manager_.update(dt) return task.cont def exitCallback(self): sys.exit(0) def setupInput(self): # Creating button map button_map = {0 : JoystickButtons.BUTTON_X , 3 : JoystickButtons.BUTTON_Y, 1 : JoystickButtons.BUTTON_A , 2 : JoystickButtons.BUTTON_B, 7 : JoystickButtons.TRIGGER_R1 , 5 : JoystickButtons.TRIGGER_R2, 6 : JoystickButtons.TRIGGER_L1 , 4 : JoystickButtons.TRIGGER_L2, 9 : JoystickButtons.BUTTON_START , 8 : JoystickButtons.BUTTON_SELECT, 10: JoystickButtons.TRIGGER_L3 , 11: JoystickButtons.TRIGGER_R3} if pygame.joystick.get_count() <= 0: logging.error("No Joysticks were found, exiting") sys.exit(-1) joystick = None for j in range(0,pygame.joystick.get_count()): joystick = pygame.joystick.Joystick(j) if joystick.init() and joystick.get_numbuttons() > 0: break; self.joystick_manager_ = JoystickController(button_map,joystick, JoystickController.JoystickAxes(),0.2) # Creating directional moves self.joystick_manager_.addMove(Move('UP',[JoystickButtons.DPAD_UP],True)) self.joystick_manager_.addMove(Move('DOWN',[JoystickButtons.DPAD_DOWN],True)) self.joystick_manager_.addMove(Move('LEFT',[JoystickButtons.DPAD_LEFT],True)) self.joystick_manager_.addMove(Move('RIGHT',[JoystickButtons.DPAD_RIGHT],True)) self.joystick_manager_.addMove(Move('DOWN_RIGHT',[JoystickButtons.DPAD_DOWNRIGHT],True)) self.joystick_manager_.addMove(Move('DOWN_LEFT',[JoystickButtons.DPAD_DOWNLEFT],True)) self.joystick_manager_.addMove(Move('UP_LEFT',[JoystickButtons.DPAD_UPLEFT],True)) self.joystick_manager_.addMove(Move('UP_RIGHT',[JoystickButtons.DPAD_UPRIGHT],True)) # Creating action moves self.joystick_manager_.addMove(Move('JUMP',[JoystickButtons.BUTTON_B],True)) self.joystick_manager_.addMove(Move('DASH',[JoystickButtons.BUTTON_A],True)) self.joystick_manager_.addMove(Move('LIGHT ATTACK',[JoystickButtons.BUTTON_Y],True)) self.joystick_manager_.addMove(Move('FUERTE ATTACK',[JoystickButtons.BUTTON_X],True)) # Creating release moves self.joystick_manager_.addMove(Move('UP_RELEASE',[JoystickButtons.DPAD_UP],True),False) self.joystick_manager_.addMove(Move('DOWN_RELEASE',[JoystickButtons.DPAD_DOWN],True),False) self.joystick_manager_.addMove(Move('LEFT_RELEASE',[JoystickButtons.DPAD_LEFT],True),False) self.joystick_manager_.addMove(Move('RIGHT_RELEASE',[JoystickButtons.DPAD_RIGHT],True),False) self.joystick_manager_.addMove(Move('JUMP_RELEASE',[JoystickButtons.BUTTON_B],True),False) self.joystick_manager_.addMove(Move('DASH_RELEASE',[JoystickButtons.BUTTON_A],True),False) self.joystick_manager_.addMove(Move('LIGHT ATTACK_RELEASE',[JoystickButtons.BUTTON_Y],True),False) self.joystick_manager_.addMove(Move('FUERTE ATTACK_RELEASE',[JoystickButtons.BUTTON_X],True),False) # Creating special moves self.joystick_manager_.addMove(Move('RIGHT ABUKE PRO',[JoystickButtons.DPAD_DOWN, JoystickButtons.DPAD_DOWNRIGHT, JoystickButtons.DPAD_RIGHT, #JoystickButtons.DPAD_RIGHT | JoystickButtons.BUTTON_Y],False, JoystickButtons.BUTTON_Y],False, lambda : sys.stdout.write("<-----> RIGHT ABUKE\n"))) self.joystick_manager_.addMove(Move('LEFT ABUKE PRO',[JoystickButtons.DPAD_DOWN, JoystickButtons.DPAD_DOWNLEFT, JoystickButtons.DPAD_LEFT, #JoystickButtons.DPAD_LEFT | JoystickButtons.BUTTON_Y],False, JoystickButtons.BUTTON_Y],False, lambda : sys.stdout.write("<-----> LEFT ABUKE \n"))) self.joystick_manager_.addMove(Move('FOCUS ATTACK',[ JoystickButtons.BUTTON_X | JoystickButtons.BUTTON_Y],False, #JoystickButtons.BUTTON_Y],False, lambda : sys.stdout.write("<-----> FOCUS ATTACK \n")))
class TestApplication(ShowBase): def __init__(self,name = 'TestApplication', cam_step = 0.05, cam_zoom = 4): ShowBase.__init__(self) self.cam_step_ = cam_step self.cam_zoom_ = cam_zoom self.name_ = name self.setupRendering() self.setupResources() self.setupControls() self.setupPhysics() self.clock_ = ClockObject() # Task taskMgr.add(self.update, 'updateWorld') # Function to put instructions on the screen. def addInstructions(self,pos, msg): return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05, shadow=(0, 0, 0, 1), parent=base.a2dTopLeft, pos=(0.08, -pos - 0.04), align=TextNode.ALeft) # Function to put title on the screen. def addTitle(self,text): return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=.08, parent=base.a2dBottomRight, align=TextNode.ARight, pos=(-0.1, 0.09), shadow=(0, 0, 0, 1)) def setupResources(self): pass def setupRendering(self): self.setBackgroundColor(0.1, 0.1, 0.8, 1) self.setFrameRateMeter(True) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) def setupControls(self): # Input (Events) self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('q',self.zoomIn) self.accept('a',self.zoomOut) # Inputs (Polling) self.input_state_ = InputState() self.input_state_.watchWithModifiers("right","arrow_right") self.input_state_.watchWithModifiers('left', 'arrow_left') self.input_state_.watchWithModifiers('up', 'arrow_up') self.input_state_.watchWithModifiers('down', 'arrow_down') self.title = self.addTitle("Panda3D: " + self.name_) self.instructions_ = [ self.addInstructions(0.06, "ESC: Quit"), self.addInstructions(0.12, "Up/Down: Jump/Stop"), self.addInstructions(0.18, "Left/Right: Move Left / Move Rigth"), self.addInstructions(0.24, "z/x/c : Rotate Left/ Rotate Stop / Rotate Right"), self.addInstructions(0.30, "q/a: Zoom in / Zoom out") ] def setupPhysics(self, use_default_objs = True): # setting up physics world and parent node path self.physics_world_ = BulletWorld() self.world_node_ = self.render.attachNewNode('world') self.cam.reparentTo(self.world_node_) self.cam.setPos(self.world_node_,0, -self.cam_zoom_*6, self.cam_step_*25) self.physics_world_.setGravity(Vec3(0, 0, -9.81)) self.debug_node_ = self.world_node_.attachNewNode(BulletDebugNode('Debug')) self.debug_node_.show() self.debug_node_.node().showWireframe(True) self.debug_node_.node().showConstraints(True) self.debug_node_.node().showBoundingBoxes(False) self.debug_node_.node().showNormals(True) self.physics_world_.setDebugNode(self.debug_node_.node()) self.debug_node_.hide() self.object_nodes_ = [] self.controlled_objects_ = [] self.ground_ = None if use_default_objs: # setting up ground self.ground_ = self.world_node_.attachNewNode(BulletRigidBodyNode('Ground')) self.ground_.node().addShape(BulletPlaneShape(Vec3(0, 0, 1), 0)) self.ground_.setPos(0,0,0) self.ground_.setCollideMask(BitMask32.allOn()) self.physics_world_.attachRigidBody(self.ground_.node()) self.setupLevel() def addBox(self,name,size,pos,visual): # Box (dynamic) box = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) box.node().setMass(1.0) box.node().addShape(BulletBoxShape(size)) box.setPos(pos) box.setCollideMask(BitMask32.allOn()) box.node().setLinearFactor((1,0,1)) box.node().setAngularFactor((0,1,0)) visual.instanceTo(box) self.physics_world_.attachRigidBody(box.node()) self.object_nodes_.append(box) def setupLevel(self): # (left, top, length ,depth(y) ,height) platform_details =[ (-20, 4, 20, 4, 1 ), (-2, 5, 10, 4, 1 ), ( 4 , 2 , 16, 4, 1), (-4 , 1, 10, 4, 1), ( 16, 6, 30, 4, 1) ] for i in range(0,len(platform_details)): p = platform_details[i] topleft = (p[0],p[1]) size = Vec3(p[2],p[3],p[4]) self.addPlatform(topleft, size,'Platform%i'%(i)) def addPlatform(self,topleft,size,name): # Visual visual = loader.loadModel(RESOURCES_DIR + '/models/box.egg') visual.clearModelNodes() visual.setTexture(loader.loadTexture(RESOURCES_DIR + '/models/iron.jpg'),1) bounds = visual.getTightBounds() extents = Vec3(bounds[1] - bounds[0]) scale_factor = 1/max([extents.getX(),extents.getY(),extents.getZ()]) visual.setScale(size.getX()*scale_factor,size.getY()*scale_factor,size.getZ()*scale_factor) # Box (static) platform = self.world_node_.attachNewNode(BulletRigidBodyNode(name)) platform.node().setMass(0) platform.node().addShape(BulletBoxShape(size/2)) platform.setPos(Vec3(topleft[0] + 0.5*size.getX(),0,topleft[1]-0.5*size.getZ())) platform.setCollideMask(BitMask32.allOn()) visual.instanceTo(platform) self.physics_world_.attachRigidBody(platform.node()) self.object_nodes_.append(platform) def update(self, task): self.clock_.tick() dt = self.clock_.getDt() self.processInput(dt) self.physics_world_.doPhysics(dt, 5, 1.0/180.0) #self.updateCamera() return task.cont def processInput(self,dt): if self.input_state_.isSet('right'): self.moveRight() if self.input_state_.isSet('left'): self.moveLeft() if self.input_state_.isSet('up'): self.moveUp() if self.input_state_.isSet('down'): self.moveDown() def updateCamera(self): #self.cam.setY(-self.cam_zoom_) pass def cleanup(self): for i in range(0,len(self.object_nodes_)): rb = self.object_nodes_[i] self.physics_world_.removeRigidBody(rb.node()) self.object_nodes_ = [] if self.ground_ is not None: self.physics_world_.removeRigidBody(self.ground_.node()) self.ground_ = None self.physics_world_ = None self.debug_node_ = None self.cam.reparentTo(self.render) self.world_node_.removeNode() self.world_node_ = None # _____MOVE_METHODS____ def moveUp(self): self.cam.setPos(self.cam.getPos() + Vec3(0, 0,self.cam_step_)) def moveDown(self): self.cam.setPos(self.cam.getPos() + Vec3(0, 0,-self.cam_step_)) def moveRight(self): self.cam.setPos(self.cam.getPos() + Vec3(self.cam_step_,0,0)) def moveLeft(self): self.cam.setPos(self.cam.getPos() + Vec3(-self.cam_step_,0,0)) # _____HANDLER_____ def zoomIn(self): #global self.cam_zoom_ self.cam.setY(self.cam.getY()+self.cam_zoom_) def zoomOut(self): #global self.cam_zoom_ self.cam.setY(self.cam.getY()-self.cam_zoom_) def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setupPhysics() def toggleDebug(self): if self.debug_node_.isHidden(): self.debug_node_.show() else: self.debug_node_.hide() def doScreenshot(self): self.screenshot('Pand3d')