def set_controls(self): """Configure common game controls. Configure major keys, collisions system and controls to manipulate characters. """ base.accept("f1", self._show_keys) # noqa: F821 base.accept("escape", base.main_menu.show) # noqa: F821 base.accept("r", self._show_char_relations) # noqa: F821 base.accept("m", base.world.rails_scheme.show) # noqa: F821 base.accept("j", base.journal.show) # noqa: F821 # configure mouse collisions col_node = CollisionNode("mouse_ray") col_node.setIntoCollideMask(NO_MASK) col_node.setFromCollideMask(MOUSE_MASK) self._mouse_ray = CollisionRay() col_node.addSolid(self._mouse_ray) # set common collisions handler handler = CollisionHandlerEvent() handler.addInPattern("%fn-into") handler.addAgainPattern("%fn-again") handler.addOutPattern("%fn-out") self.traverser = CollisionTraverser("traverser") self.traverser.addCollider( base.cam.attachNewNode(col_node), handler # noqa: F821 ) self.set_mouse_events() taskMgr.doMethodLater(0.03, self._collide_mouse, "collide_mouse") # noqa: F821 taskMgr.doMethodLater(0.04, self._traverse, name="main_traverse") # noqa: F821
class CollisionBase(ShowBase): def __init__(self): self.cTrav = CollisionTraverser() self.mchandler = CollisionHandlerEvent() self.mchandler.addInPattern('into-%in') self.mchandler.addAgainPattern('%fn-again-%in') self.mchandler.addOutPattern('out-%in')
def __init__(self, model = "cube_nocol", texture = "lava", pos = (0,0,0), scale = (1,1,1), cubetype = "A"): super(LavaCube, self).__init__(model, texture, pos, scale) cn = CollisionNode('lava') cn.setFromCollideMask(COLLISIONMASKS['lava']) cn.setIntoCollideMask(BitMask32.allOff()) np = self.node.attachNewNode(cn) cn.addSolid(CollisionSphere(0,0,0,1.1)) h = CollisionHandlerEvent() h.addInPattern('%fn-into-%in') h.addOutPattern('%fn-outof-%in') base.cTrav.addCollider(np, h)
def __init__(self, model = "models/sphere", texture = "exit", pos = (0,0,0), scale = (1,1,1), cubetype = "A"): super(LevelExit, self).__init__(model, texture, pos, scale) #self.node.setTransparency(TransparencyAttrib.MAlpha) self.node.setTag('noportals', '1') self.node.setTag('isexit', '1') cn = CollisionNode('levelExit') cn.setFromCollideMask(COLLISIONMASKS['exit']) cn.setIntoCollideMask(BitMask32.allOff()) np = self.node.attachNewNode(cn) cn.addSolid(CollisionSphere(0,0,0,1.1)) h = CollisionHandlerEvent() h.addInPattern('%fn-into-%in') h.addOutPattern('%fn-outof-%in') base.cTrav.addCollider(np, h)
def createPortalCollisions(self): # Enter the portals cn = CollisionNode('bluePortal') cn.setFromCollideMask(COLLISIONMASKS['portals']) cn.setIntoCollideMask(BitMask32.allOff()) np = self.bluePortal.attachNewNode(cn) cn.addSolid(CollisionSphere(0,0,0,2)) h = CollisionHandlerEvent() h.addInPattern('%fn-into-%in') h.addOutPattern('%fn-outof-%in') self.base.cTrav.addCollider(np, h) cn = CollisionNode('orangePortal') cn.setFromCollideMask(COLLISIONMASKS['portals']) cn.setIntoCollideMask(BitMask32.allOff()) np = self.orangePortal.attachNewNode(cn) cn.addSolid(CollisionSphere(0,0,0,2)) h = CollisionHandlerEvent() h.addInPattern('%fn-into-%in') h.addOutPattern('%fn-outof-%in') self.base.cTrav.addCollider(np, h)
class Pickup(DirectObject): #Creates health pickup object def __init__(self, idappend, spawn): self.id = "pick"+str(idappend) self.deletePickup = False self.projectileNode = NodePath('heal'+str(self.id)) self.projectileNode.setScale(1) self.projectileModel = loader.loadModel("./resources/healthPickup.egg") self.projectileModel.setColorScale(200, 0, 0, 100) self.projectileModel.reparentTo(self.projectileNode) self.projectileNode.reparentTo(render) self.projectileNode.setPos(spawn) cs = CollisionSphere(0, 0, 0, .5) cnode = CollisionNode('heal') self.colNode = self.projectileModel.attachNewNode(cnode) self.colNode.node().addSolid(cs) self.collHand = CollisionHandlerEvent() self.collHand.addInPattern('pickupin'+str(self.id)) self.collHand.addOutPattern('oot') base.cTrav.addCollider(self.colNode, self.collHand) self.accept('pickupin'+str(self.id), self.pickup) #Detects if the player has picked up the health def pickup(self, col): if col.getIntoNodePath().getName() == "cnode": messenger.send("pickuphealth") self.deletePickup = True #Destroys the health pickups from the scene graph def destroy(self): self.projectileNode.removeNode() self.projectileModel.removeNode() self.colNode.node().clearSolids() del self
class DKApp(ShowBase): def __init__(self): super().__init__(self) self.scene = self.loader.loadModel("models/DKSet1") self.scene.reparentTo(self.render) self.scene.setPos(0,0,0) self.jumping = False self.jumpTime = 0 # base.messenger.toggleVerbose() self.accept("raw-arrow_left" , self.pressLeft) self.accept("raw-arrow_left-up", self.releaseLeft) self.accept("raw-arrow_right" , self.pressRight) self.accept("raw-arrow_right-up", self.releaseRight) self.accept("raw-space" , self.pressSpace) self.accept("raw-space-up", self.releaseSpace) self.accept("raw-arrow_up" , self.pressUp) self.accept("raw-arrow_up-up", self.releaseUp) self.taskMgr.add(self.setup,"setup") self.taskMgr.add(self.update , "update") self.input= { "up":False, "left":False, "right":False, "space":False } def pressLeft(self): self.input["left"] = True def releaseLeft(self): self.input["left"] = False def pressRight(self): self.input["right"] = True def releaseRight(self): self.input["right"] = False def pressSpace(self): self.input["space"] = True def releaseSpace(self): self.input["space"] = False def pressUp(self): self.input["up"] = True def releaseUp(self): self.input["up"] = False def getHorizontalAxis(self): if( self.input["left"] and self.input["right"]): return 0 if( self.input["left"] ): return -1 if( self.input["right"]): return 1 return 0 def setupCollision(self): base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') hitBox = CollisionBox( Point3(7,0,-4.5) , 0.5,5,0.5) cnodePath = self.player.attachNewNode( CollisionNode('marioHitBox') ) cnodePath.node().addSolid(hitBox) cnodePath.show() base.cTrav.addCollider(cnodePath, self.collisionHandlerEvent) stairs1 = self.scene.find("root/bottomstair") hitBox = CollisionBox( Point3(-6.8,0,-3.0) , 0.5,5,2.5) cnodePath = stairs1.attachNewNode( CollisionNode('stairsHitBox') ) cnodePath.node().addSolid(hitBox) cnodePath.show() self.accept('into-stairsHitBox', self.enableStair) self.accept('outof-stairsHitBox', self.disableStair) base.cTrav.showCollisions(self.render) def enableStair(self, evt): print(f'{evt}') def disableStair(self, evt): print(f'{evt}') def setup(self, task): lens = OrthographicLens() lens.setFilmSize(25,20) base.camNode.setLens(lens) node = self.scene.find("root/camera1") node.remove() self.player = self.scene.find("root/mario") self.setupCollision() return Task.done def update(self,task): self.camera.setPos(0,35,0) self.camera.lookAt(self.scene) # print(f'{globalClock.getDt()}') jy = 0 # jump Y/Z vi = 4 # initial velocity g = -5 # gravity if self.jumping: self.jumpTime = self.jumpTime + globalClock.getDt() jy = vi*self.jumpTime + 0.5*g*self.jumpTime*self.jumpTime vy = vi + g*self.jumpTime if vy < 0 and abs(jy) < 0.2: # eventually jy substraction will change for the original y(aka Z) mario had self.jumpTime = 0 self.jumping = False jy = 0 else: if self.player.getZ() == 0 and self.input["space"] : self.jumping = True self.jumpTime = 0.01 # stop advancing if jumping! adv = self.getHorizontalAxis()*-.2 if self.jumping : adv = 0 self.player.setPos( self.player.getX()+adv , 0, jy ) return Task.cont
# this is what set our ray to shoot from the actual camera lenses off the 3d scene, passing by the mouse pointer position, making magically hit in the 3d space what is pointed by it pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) return task.cont #** This function then will be called when we click and release the left mouse button, showing himself changing the ball scale according with the pickingEnabled flag state. def mousePick(status): if pickingEnabled: if status == 'down': smileyModel.setScale(.9) if status == 'up': smileyModel.setScale(1.0) # Here as well we see something already seen in the previous steps related to collision events so I won't go into details. collisionHandler.addInPattern('%fn-into-%in') collisionHandler.addOutPattern('%fn-out-%in') #** Let's manage now the collision events: DO=DirectObject() # if you went from step3 and step4, here should not be mysteries for you DO.accept('mouseraycnode-into-smileycnode', collideEventIn) DO.accept('mouseraycnode-out-smileycnode', collideEventOut) #** This little but important variable will be used to know the picking state at any time - note that the picking is enabled ASA the mouse pointer goes above the ball and disabled when it leave. pickingEnabled=False #** This is how we interact with mouse clicks - see the mousePick function above for details DO.accept('mouse1', mousePick, ['down']) DO.accept('mouse1-up', mousePick, ['up']) #** And at last, we start the task that continuously update the ray collider position and orientation while we move the mouse pointer
class CBShield(DirectObject): #Property stuff creaTime = time.clock() dur = 5 vec = 0 delta = .15 prevtime = 0 flag = False #defining the thing fired by whatever gun we have def __init__(self, camera, look, id): #nodepath of the projectile, give it a trajectory self.projectileNode = NodePath('projectile'+str(id)) self.projectileNode.setTransparency(TransparencyAttrib.MAlpha) self.projectileNode.reparentTo(render) #by passing the camera node form the camMov object, all projectiles are spawned 5 units in front of the camera self.projectileNode.setHpr(look, 0, 0, 0) self.projectileNode.setPos(camera,-1,10, 3) #fix z position to line up with gun self.projectileNode.setScale(.1) projectileModel = loader.loadModel("./resources/cubeShot.egg") projectileModel.setColorScale(0, 0, 0, .5) projectileModel.setSz(50) projectileModel.setSy(1) projectileModel.setSx(50) projectileModel.reparentTo(self.projectileNode) #must calculate unit vector based on direction dir = render.getRelativeVector(look, Vec3(0, 1, 0)) #speed up or slow down projectiles here dir = dir*10 self.vec = dir #base.cTrav = CollisionTraverser() cs = CollisionSphere(0, 0, 0, 25) cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode')) cnodepath.node().addSolid(cs) self.collHand = CollisionHandlerEvent() self.collHand.addInPattern('into'+str(id)) self.collHand.addOutPattern('outof') #cTrav has the distinction of global colider handler base.cTrav.addCollider(cnodepath, self.collHand) self.acceptOnce('into'+str(id), self.hit) #deal with colliding or special effects here. #wanted projectiles to be short lived #so i will make them delete themselves after impact or time expired #writing a task that will rek the projectiles at the end of time self.damage = 20 def placeTask(self, task): #curtime = time.clock() #self.delta = curtime-self.prevtime if self.flag: return task.done #prevtime = time.clock() if task.time < self.dur: return task.cont else: self.flag = True return task.done def hit(self, collEntry): #throw out a custom message for what hit if collEntry.getIntoNodePath().getName() != 'projNode': temp = collEntry.getIntoNodePath().getName() messenger.send(temp, [self.damage]) #remove the impacting projectile collEntry.getFromNodePath().getParent().getParent().removeNode() self.flag = True del self
class GameContainer(ShowBase): def __init__(self): ShowBase.__init__(self) ########## Window configuration ######### wp = WindowProperties() wp.setSize(1024, 860) self.win.requestProperties(wp) ########## Gameplay settings ######### self.GAME_MODE = PLAY self.play_mode = SPACE self.level = 1.5 self.mode_initialized = False ######### Camera ######### self.disableMouse() self.mainCamera = Camera(self.camera) self.mainCamera.camObject.setHpr(0, 0, 0) #Trigger game chain self.loadLevel(LEVEL) ######### Events ######### self.taskMgr.add(self.gameLoop, "gameLoop", priority = 35) self.keys = {"w" : 0, "s" : 0, "a" : 0, "d" : 0, "space" : 0} self.accept("w", self.setKey, ["w", 1]) self.accept("w-up", self.setKey, ["w", 0]) self.accept("s", self.setKey, ["s", 1]) self.accept("s-up", self.setKey, ["s", 0]) self.accept("a", self.setKey, ["a", 1]) self.accept("a-up", self.setKey, ["a", 0]) self.accept("d", self.setKey, ["d", 1]) self.accept("d-up", self.setKey, ["d", 0]) self.accept("space", self.setKey, ["space", 1]) self.accept("space-up", self.setKey, ["space", 0]) self.accept("wheel_up", self.zoomCamera, [-1]) self.accept("wheel_down", self.zoomCamera, [1]) self.accept("escape", self.switchGameMode, [IN_GAME_MENU]) self.accept("window-event", self.handleWindowEvent) self.accept("playerGroundRayJumping-in", self.avatar.handleCollisionEvent, ["in"]) self.accept("playerGroundRayJumping-out", self.avatar.handleCollisionEvent, ["out"]) ######### GUI ######### self.gui_elements = [] def loadSpaceTexture(self, level): if level < 10: return 'textures/space#.jpg' elif level < 15: pass def loadLevel(self, level): #Resets self.avatarActor = Actor("models/panda", {"walk": "models/panda-walk"}) self.avatarActor.setScale(.5, .5, .5) self.avatarActor.setHpr(180, 0, 0) self.avatarActor.setCollideMask(BitMask32.allOff()) self.asteroidManager = AsteroidManager() #Alternate modes if int(self.level) == self.level: self.play_mode = TERRAIN else: self.play_mode = SPACE #Specifics if self.play_mode == SPACE: self.avatar = Avatar(self.avatarActor) self.avatar.objectNP.reparentTo(render) ########## Sky ######### cubeMap = loader.loadCubeMap(self.loadSpaceTexture(self.level)) self.spaceSkyBox = loader.loadModel('models/box') self.spaceSkyBox.setScale(100) self.spaceSkyBox.setBin('background', 0) self.spaceSkyBox.setDepthWrite(0) self.spaceSkyBox.setTwoSided(True) self.spaceSkyBox.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldCubeMap) self.spaceSkyBox.setTexture(cubeMap, 1) #self.spaceSkyBox.setEffect(CompassEffect.make(render)) parentNP = render.attachNewNode('parent') self.spaceSkyBox.reparentTo(parentNP) self.spaceSkyBox.setPos(-self.spaceSkyBox.getSx()/2, -self.spaceSkyBox.getSy()/2, -self.spaceSkyBox.getSz()/2) self.asteroidManager.initialize(self.level) elif self.play_mode == TERRAIN: ########## Terrain ######### #self.environ = loader.loadModel("../mystuff/test.egg") self.environ = loader.loadModel("models/environment") self.environ.setName("terrain") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) self.environ.setCollideMask(BitMask32.bit(0)) ######### Models ######### ######### Physics ######### base.enableParticles() gravityForce = LinearVectorForce(0, 0, -9.81) gravityForce.setMassDependent(False) gravityFN = ForceNode("world-forces") gravityFN.addForce(gravityForce) render.attachNewNode(gravityFN) base.physicsMgr.addLinearForce(gravityForce) self.avatarPhysicsActorNP = render.attachNewNode(ActorNode("player")) self.avatarPhysicsActorNP.node().getPhysicsObject().setMass(50.) self.avatarActor.reparentTo(self.avatarPhysicsActorNP) base.physicsMgr.attachPhysicalNode(self.avatarPhysicsActorNP.node()) self.avatarPhysicsActorNP.setPos(15, 10, 5) ######### Game objects ######### self.avatar = Avatar(self.avatarPhysicsActorNP) ######### Collisions ######### self.cTrav = CollisionTraverser() #Make player rigid body self.pandaBodySphere = CollisionSphere(0, 0, 4, 3) self.pandaBodySphereNode = CollisionNode("playerBodyRay") self.pandaBodySphereNode.addSolid(self.pandaBodySphere) self.pandaBodySphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaBodySphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaBodySphereNodepath = self.avatar.objectNP.attachNewNode(self.pandaBodySphereNode) self.pandaBodySphereNodepath.show() self.pandaBodyCollisionHandler = PhysicsCollisionHandler() self.pandaBodyCollisionHandler.addCollider(self.pandaBodySphereNodepath, self.avatar.objectNP) #Keep player on ground self.pandaGroundSphere = CollisionSphere(0, 0, 1, 1) self.pandaGroundSphereNode = CollisionNode("playerGroundRay") self.pandaGroundSphereNode.addSolid(self.pandaGroundSphere) self.pandaGroundSphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaGroundSphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaGroundSphereNodepath = self.avatar.objectNP.attachNewNode(self.pandaGroundSphereNode) self.pandaGroundSphereNodepath.show() self.pandaGroundCollisionHandler = PhysicsCollisionHandler() self.pandaGroundCollisionHandler.addCollider(self.pandaGroundSphereNodepath, self.avatar.objectNP) #Notify when player lands self.pandaGroundRayJumping = CollisionSphere(0, 0, 1, 1) self.pandaGroundRayNodeJumping = CollisionNode("playerGroundRayJumping") self.pandaGroundRayNodeJumping.addSolid(self.pandaGroundRayJumping) self.pandaGroundRayNodeJumping.setFromCollideMask(BitMask32.bit(0)) self.pandaGroundRayNodeJumping.setIntoCollideMask(BitMask32.allOff()) self.pandaGroundRayNodepathJumping = self.avatar.objectNP.attachNewNode(self.pandaGroundRayNodeJumping) self.pandaGroundRayNodepathJumping.show() self.collisionNotifier = CollisionHandlerEvent() self.collisionNotifier.addInPattern("%fn-in") self.collisionNotifier.addOutPattern("%fn-out") self.cTrav.addCollider(self.pandaGroundSphereNodepath, self.pandaGroundCollisionHandler) self.cTrav.addCollider(self.pandaGroundRayNodepathJumping, self.collisionNotifier) self.cTrav.addCollider(self.pandaBodySphereNodepath, self.pandaBodyCollisionHandler) def maintainTurrets(self): pass def setKey(self, key, value): self.keys[key] = value def zoomCamera(self, direction): Camera.AVATAR_DIST += direction def b(self, hey): self.avatarLanded = True def handleWindowEvent(self, window=None): wp = window.getProperties() self.win_center_x = wp.getXSize() / 2 self.win_center_y = wp.getYSize() / 2 def switchGameMode(self, newGameMode=None): self.cleanupGUI() if self.GAME_MODE == IN_GAME_MENU: if newGameMode == PLAY: render.clearFog() elif newGameMode == MAIN_MENU: pass elif True: pass self.GAME_MODE = newGameMode self.mode_initialized = False def cleanupGUI(self): for gui_element in self.gui_elements: gui_element.destroy() def evenButtonPositions(self, button_spacing, button_height, num_buttons): center_offset = (button_spacing/(2.0) if (num_buttons % 2 == 0) else 0) button_positions = [] current_pos = center_offset + ((num_buttons - 1)/2) * button_spacing for i in range(0, num_buttons): button_positions.append(current_pos + (button_height/2.0)) current_pos -= button_spacing return button_positions def buildInGameMenu(self): props = WindowProperties() props.setCursorHidden(False) base.win.requestProperties(props) resume_button = DirectButton(text = "Resume", scale = .1, command = (lambda: self.switchGameMode(PLAY)), rolloverSound=None) main_menu_button = DirectButton(text = "Main Menu", scale = .1, command = self.b, rolloverSound=None) options_button = DirectButton(text = "Options", scale = .1, command = self.b, rolloverSound=None) exit_button = DirectButton(text = "Exit", scale = .1, command = exit, rolloverSound=None) BUTTON_SPACING = .2 BUTTON_HEIGHT = resume_button.getSy() button_positions = self.evenButtonPositions(BUTTON_SPACING, BUTTON_HEIGHT, 4) resume_button.setPos(Vec3(0, 0, button_positions[0])) main_menu_button.setPos(Vec3(0, 0, button_positions[1])) options_button.setPos(Vec3(0, 0, button_positions[2])) exit_button.setPos(Vec3(0, 0, button_positions[3])) self.gui_elements.append(resume_button) self.gui_elements.append(main_menu_button) self.gui_elements.append(options_button) self.gui_elements.append(exit_button) def buildMainMenu(self): props = WindowProperties() props.setCursorHidden(False) base.win.requestProperties(props) start_game_button = DirectButton(text = "Start", scale = .1, command = self.b) select_level_button = DirectButton(text = "Select Level", scale = .1, command = self.b) game_options_button = DirectButton(text = "Options", scale = .1, command = self.b) exit_button = DirectButton(text = "Exit", scale = .1, command = exit) BUTTON_SPACING = .2 BUTTON_HEIGHT = start_game_button.getSy() button_positions = self.evenButtonPositions(BUTTON_SPACING, BUTTON_HEIGHT) start_game_button.setPos(Vec3(0, 0, button_positions[0])) select_level_button.setPos(Vec3(0, 0, button_positions[1])) game_options_button.setPos(Vec3(0, 0, button_positions[2])) exit_button.setPos(Vec3(0, 0, button_positions[3])) self.gui_elements.append(start_game_button) self.gui_elements.append(select_level_button) self.gui_elements.append(game_options_button) self.gui_elements.append(exit_button) def gameLoop(self, task): #Compensate for inconsistent update intervals dt = globalClock.getDt() if self.GAME_MODE == MAIN_MENU: if not self.mode_initialized: self.buildMainMenu() self.mode_initialized = True if self.GAME_MODE == IN_GAME_MENU: if not self.mode_initialized: #Fog out background inGameMenuFogColor = (50, 150, 50) inGameMenuFog = Fog("inGameMenuFog") inGameMenuFog.setMode(Fog.MExponential) inGameMenuFog.setColor(*inGameMenuFogColor) inGameMenuFog.setExpDensity(.01) render.setFog(inGameMenuFog) self.buildInGameMenu() self.mode_initialized = True if self.GAME_MODE == PLAY: if not self.mode_initialized: props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) self.last_mouse_x = self.win.getPointer(0).getX() self.last_mouse_y = self.win.getPointer(0).getY() self.mode_initialized = True if self.play_mode == TERRAIN: self.maintainTurrets() self.avatar.move(dt) elif self.play_mode == SPACE: self.asteroidManager.maintainAsteroidField(self.avatar.objectNP.getPos(), self.avatar.speed, dt) #Handle keyboard input self.avatar.handleKeys(self.keys, self.play_mode) ########## Mouse-based viewpoint rotation ########## mouse_pos = self.win.getPointer(0) current_mouse_x = mouse_pos.getX() current_mouse_y = mouse_pos.getY() #Side to side if self.play_mode == TERRAIN: mouse_shift_x = current_mouse_x - self.last_mouse_x self.last_mouse_x = current_mouse_x if current_mouse_x < 5 or current_mouse_x >= (self.win_center_x * 1.5): base.win.movePointer(0, self.win_center_x, current_mouse_y) self.last_mouse_x = self.win_center_x yaw_shift = -((mouse_shift_x) * Camera.ROT_RATE[0]) self.avatar.yawRot += yaw_shift self.avatar.objectNP.setH(self.avatar.yawRot) #Up and down mouse_shift_y = current_mouse_y - self.last_mouse_y self.last_mouse_y = current_mouse_y if current_mouse_y < 5 or current_mouse_y >= (self.win_center_y * 1.5): base.win.movePointer(0, current_mouse_x, self.win_center_y) self.last_mouse_y = self.win_center_y pitch_shift = -((mouse_shift_y) * Camera.ROT_RATE[1]) self.mainCamera.pitchRot += pitch_shift if self.mainCamera.pitchRot > Camera.FLEX_ROT_MAG[0]: self.mainCamera.pitchRot = Camera.FLEX_ROT_MAG[0] elif self.mainCamera.pitchRot < -Camera.FLEX_ROT_MAG[0]: self.mainCamera.pitchRot = -Camera.FLEX_ROT_MAG[0] xy_plane_cam_dist = Camera.AVATAR_DIST cam_x_adjust = xy_plane_cam_dist*sin(radians(self.avatar.yawRot)) cam_y_adjust = xy_plane_cam_dist*cos(radians(self.avatar.yawRot)) cam_z_adjust = Camera.ELEVATION self.mainCamera.camObject.setH(self.avatar.yawRot) self.mainCamera.camObject.setP(self.mainCamera.pitchRot) self.mainCamera.camObject.setPos(self.avatar.objectNP.getX() + cam_x_adjust, self.avatar.objectNP.getY() - cam_y_adjust, self.avatar.objectNP.getZ() + cam_z_adjust) #Find collisions #self.cTrav.traverse(render) #print self.environ.getBounds() return Task.cont
class PinchTask(ShowBase, GripStateMachine): DATA_DIR = 'data' def __init__(self, id, session, hand, block, mode, wrist): ShowBase.__init__(self) GripStateMachine.__init__(self) base.disableMouse() wp = WindowProperties() wp.setSize(1920,1080) wp.setFullscreen(True) base.win.requestProperties(wp) self.sub_id = str(id) self.sess_id = str(session) self.hand = str(hand) self.block = str(block) self.mode = str(mode) self.wrist = str(wrist) self.prev_blk = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand,"B0") if self.wrist == 'pron': self.table = np.loadtxt('src/pinch_task/trialtable_pron.csv',dtype='str',delimiter=',',skiprows=1) elif self.wrist == 'flex': self.table = np.loadtxt('src/pinch_task/trialtable_flex.csv',dtype='str',delimiter=',',skiprows=1) else: raise NameError('Wrist position not found') try: self.prev_table = np.loadtxt(os.path.join(self.prev_blk, 'final_targets.csv'),dtype='str',delimiter=',',skiprows=1) indices = {} for i in range(self.prev_table.shape[0]): indices[self.prev_table[i,1]] = int(self.prev_table[i,0])-1 for i in range(self.table.shape[0]): self.table[i,11] = self.prev_table[indices[self.table[i,1].strip()],11] self.table[i,12] = self.prev_table[indices[self.table[i,1].strip()],12] self.table[i,13] = self.prev_table[indices[self.table[i,1].strip()],13] except: print('Previous target file not found') self.table = np.array([[item.strip() for item in s] for s in self.table]) ################################################## #only use rows relevant to this block #HARDCODED! NOTE IN LOG SHEET spec_table = [] for i in range(self.table.shape[0]): if int(self.block)%4 == 0: if "(p)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%4 == 1: if "(t)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%4 == 2: if "(s)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%4 == 3: if "(t+s)" in self.table[i,2]: spec_table.append(self.table[i]) ################################################### self.table = np.array(spec_table) self.session_dir = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand) self.subjinfo = self.sub_id + '_' + self.sess_id + '_' + self.hand + '_log.yml' self.p_x,self.p_y,self.p_a = GET_POS(self.session_dir,self.subjinfo,self.hand,self.wrist) self.rotmat = ROT_MAT(self.p_a,self.hand) self.setup_text() self.setup_lights() self.setup_camera() self.trial_counter = 0 self.load_models() self.load_audio() self.update_trial_command() self.countdown_timer = CountdownTimer() self.hold_timer = CountdownTimer() self.cTrav = CollisionTraverser() self.chandler = CollisionHandlerEvent() self.chandler.addInPattern('%fn-into-%in') self.chandler.addAgainPattern('%fn-again-%in') self.chandler.addOutPattern('%fn-outof-%in') self.attachcollnodes() taskMgr.add(self.read_data, 'read') for i in range(5): taskMgr.add(self.move_player, 'move%d' % i, extraArgs = [i], appendTask=True) taskMgr.add(self.log_data, 'log data') taskMgr.add(self.update_state, 'update_state', sort=1) self.accept('space', self.space_on) self.accept('escape', self.clean_up) self.space = False self.statenum = list() self.max_time = 20 self.med_data = None self.grip_dir = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand,"B"+self.block) if not os.path.exists(self.grip_dir): print('Making new folders: ' + self.grip_dir) os.makedirs(self.grip_dir) self.dev = MpDevice(RightHand(calibration_files=['calibs/cal_mat_15.mat', # thumb 'calibs/cal_mat_31.mat', 'calibs/cal_mat_8.mat', 'calibs/cal_mat_21.mat', 'calibs/cal_mat_13.mat'], clock=mono_clock.get_time)) self.init_ser() ############ #SET UP HUD# ############ def setup_text(self): #OnscreenImage(parent=self.cam2dp, image='models/background.jpg') self.bgtext = OnscreenText(text='Not recording.', pos=(-0.8, 0.8), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.bgtext.reparentTo(self.aspect2d) self.dirtext = OnscreenText( pos=(-0.6, 0.65), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.dirtext.reparentTo(self.aspect2d) ########################## #SET UP SCENE AND PLAYERS# ########################## def setup_lights(self): pl = PointLight('pl') pl.setColor((1, 1, 1, 1)) plNP = self.render.attachNewNode(pl) plNP.setPos(-10, -10, 10) self.render.setLight(plNP) pos = [[[0, 0, 50], [0, 0, -10]], [[0, -50, 0], [0, 10, 0]], [[-50, 0, 0], [10, 0, 0]]] for i in pos: dl = Spotlight('dl') dl.setColor((1, 1, 1, 1)) dlNP = self.render.attachNewNode(dl) dlNP.setPos(*i[0]) dlNP.lookAt(*i[1]) dlNP.node().setShadowCaster(False) self.render.setLight(dlNP) def setup_camera(self): self.cam.setPos(0, -4, 12) self.cam.lookAt(0, 2, 0) self.camLens.setFov(90) def load_models(self): self.back_model = self.loader.loadModel('models/back') self.back_model.setScale(10, 10, 10) if self.hand == "Left": self.back_model.setH(90) self.back_model.reparentTo(self.render) self.player_offsets = [[self.p_x[0]-5, self.p_y[0]+3, 0], [self.p_x[1]-2.5, self.p_y[1]+4.5, 0], [self.p_x[2], self.p_y[2]+5, 0], [self.p_x[3]+2.5, self.p_y[3]+4.5, 0], [self.p_x[4]+5, self.p_y[4]+3, 0]] self.p_col =[[0,0,250],[50,0,200],[125,0,125],[200,0,50],[250,0,0]] if self.hand == 'Left': self.p_col = self.p_col[::-1] self.players = list() self.contacts = list() for counter, value in enumerate(self.player_offsets): self.players.append(self.loader.loadModel('models/target')) self.contacts.append(False) self.players[counter].setPos(*value) self.players[counter].setScale(0.2, 0.2, 0.2) self.players[counter].setColorScale( self.p_col[counter][0]/255, self.p_col[counter][1]/255, self.p_col[counter][2]/255, 1) self.players[counter].reparentTo(self.render) self.players[counter].show() self.target_select() def load_audio(self): self.pop = self.loader.loadSfx('audio/Blop.wav') self.buzz = self.loader.loadSfx('audio/Buzzer.wav') ############################ #SET UP COLLISION MECHANICS# ############################ def attachcollnodes(self): for i in range(5): self.fromObject = self.players[i].attachNewNode(CollisionNode('colfromNode'+str(i))) self.fromObject.node().addSolid(CollisionSphere(0,0,0,1)) self.cTrav.addCollider(self.fromObject, self.chandler) for i in range(5): self.accept('colfromNode%d-into-colintoNode' % i, self.collide1,[i]) self.accept('colfromNode%d-again-colintoNode' % i, self.collide2,[i]) self.accept('colfromNode%d-outof-colintoNode' % i, self.collide3,[i]) def collide1(self,f,collEntry): if f in self.highlighted_indices: self.players[f].setColorScale(0,1,0,0) self.tar.setColorScale(0.2,0.2,0.2,1) self.tar.setAlphaScale(0.7) self.contacts[f] = True taskMgr.doMethodLater(self.delay,self.too_long,'too_long%d' % f,extraArgs = [f]) self.sendsig(1,f,100) def collide2(self,f,collEntry): if f in self.highlighted_indices: dist = np.sqrt(self.distances[f][1]^2+self.distances[f][2]^2+self.distances[f][3]^2) self.sendsig(2,f,int(10/dist)+100) for i in self.highlighted_indices: if self.contacts[i] == False: return taskMgr.remove('too_long%d' % f) def collide3(self,f,collEntry): taskMgr.remove('too_long%d' % f) self.reset_fing(f) self.tar.setColorScale(0.1,0.1,0.1,1) self.tar.setAlphaScale(0.7) def too_long(self,f): self.reset_fing(f) self.tar.setColorScale(0.5,0.2,0.2,1) self.tar.setAlphaScale(0.7) def reset_fing(self,f): self.players[f].setColorScale( self.p_col[f][0]/255, self.p_col[f][1]/255, self.p_col[f][2]/255, 1) self.contacts[f] = False self.sendsig(3,f,0) ############### #TARGET THINGS# ############### def show_target(self): self.target_select() self.intoObject = self.tar.attachNewNode(CollisionNode('colintoNode')) if self.table[self.trial_counter,7] == "sphere": self.intoObject.node().addSolid(CollisionSphere(0,0,0,1)) elif self.table[self.trial_counter,7] == "cylinder": self.intoObject.node().addSolid(CollisionTube(0,0,-2,0,0,2,1)) else: raise NameError("No such collision type") self.tar.show() #hide players not related to target for i in range(5): if i not in self.highlighted_indices: self.players[i].hide() def target_select(self): self.tgtscx=float(self.table[self.trial_counter,14]) self.tgtscy=float(self.table[self.trial_counter,15]) self.tgtscz=float(self.table[self.trial_counter,16]) tgttsx=float(self.table[self.trial_counter,11]) tgttsy=float(self.table[self.trial_counter,12]) tgttsz=float(self.table[self.trial_counter,13]) tgtrx=float(self.table[self.trial_counter,17]) tgtry=float(self.table[self.trial_counter,18]) tgtrz=float(self.table[self.trial_counter,19]) if self.hand == 'Left': tgttsx *= -1 tgtrx *= -1 self.static_task = (str(self.table[self.trial_counter,5]) == "True") self.target_model = str(self.table[self.trial_counter,6]) self.highlighted_indices=[int(s)-1 for s in self.table[self.trial_counter,4].split(' ')] if self.hand == 'Left': self.highlighted_indices=[4-i for i in self.highlighted_indices] #NOTE:this position finding is present in all three tasks # it is somewhat hacky and can be improved upon self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[-2,-1],0]) + tgttsx self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[0,1],1]) + tgttsy if len(self.highlighted_indices) > 3: #for sphere, return to just average of all fingers self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,0]) + tgttsx #self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,1]) self.tgtposz = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,2]) + tgttsz self.tar = self.loader.loadModel(self.target_model) self.tar.setScale(self.tgtscx,self.tgtscy,self.tgtscz) self.tar.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.tar.setHpr(tgtrx,tgtry,tgtrz) self.tar.setColorScale(0.1, 0.1, 0.1, 1) self.tar.setAlphaScale(0.7) self.tar.setTransparency(TransparencyAttrib.MAlpha) self.tar.reparentTo(self.render) self.tar.hide() self.delay=float(self.table[self.trial_counter,8]) self.loc_angle=math.radians(float(self.table[self.trial_counter,9])) self.invf=float(self.table[self.trial_counter,10]) self.distances = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]] ############## #MOVE FINGERS# ############## def read_data(self,task): error, data = self.dev.read() if data is not None: data *= 0.001 self.ts = data.time data = np.dot(data,self.rotmat) self.data = data if self.med_data is None: self.med_data = np.median(data, axis=0) if self.space: self.statenum.extend(([self.checkstate()])*len(data.time)) return task.cont def move_player(self,p,task): if self.data is not None : k = p*3 new_x = 10*np.mean(self.data[-1,k]) + self.player_offsets[p][0] - 10*self.med_data[k] new_y = 10*np.mean(self.data[-1,k + 1]) + self.player_offsets[p][1] - 10*self.med_data[k + 1] new_z = 10*np.mean(self.data[-1,k + 2]) + self.player_offsets[p][2] - 10*self.med_data[k + 2] #make sure digits do not cross each other if ((p in range(1,3) and p+1 in self.highlighted_indices and new_x > self.players[p+1].getX()) or (p in range(2,4) and p-1 in self.highlighted_indices and new_x < self.players[p-1].getX())): new_x = self.players[p].getX() #make sure digits do not cross into target if self.space == True and p in self.highlighted_indices: self.distances[p][0] = new_x - self.tar.getX() self.distances[p][1] = new_y - self.tar.getY() self.distances[p][2] = new_z - self.tar.getZ() self.check_pos(p) self.players[p].setPos(new_x, new_y, new_z) return task.cont def check_pos(self,p): if (abs(self.distances[p][0]) < self.invf*self.tgtscx and abs(self.distances[p][1]) < self.invf*self.tgtscy and abs(self.distances[p][2]) < self.invf*self.tgtscz): self.too_long(p) ################## #CHECK COMPLETION# ################## def close_to_target(self): for i in self.highlighted_indices: if self.contacts[i] == False: return False if not self.check_angle(): self.tar.setColorScale(0.1,0.1,0.1,1) self.tar.setAlphaScale(0.7) return False self.tar.setColorScale(0,1,1,1) return True def check_hold(self): if not self.close_to_target(): self.hold_timer.reset(0.5) return False return self.hold_timer.elapsed() < 0 def check_angle(self): #hardcoded condition may be able to be assimilated into old angle method somehow if self.table[self.trial_counter,1] == 'pts': vec = np.subtract(self.players[self.highlighted_indices[1]].getPos(), self.players[self.highlighted_indices[0]].getPos()) xvec = [1,0,0] if self.hand == 'Left': xvec = [-1,0,0] print(math.degrees(math.acos(np.dot(vec,xvec)/(np.linalg.norm(vec)*np.linalg.norm(xvec))))) if math.acos(np.dot(vec,xvec)/(np.linalg.norm(vec)*np.linalg.norm(xvec))) < self.loc_angle: return True else: return False thumbindx = 0 if self.hand == "Left": thumbindx = 4 for i in self.highlighted_indices: if i == thumbindx: continue th = self.distances[thumbindx] fg = self.distances[i] if math.acos(np.dot(th,fg)/(np.linalg.norm(th)*np.linalg.norm(fg))) > self.loc_angle: return True return False def adjust_targets(self): #no adjustment if more than 2 fingers or position is prone if len(self.highlighted_indices) > 2 or self.wrist == 'pron': return xadj,yadj,zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices],0) #yadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][1]) #zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][2]) #do adjustment on all tasks with same name if self.hand == 'Left': xadj = -xadj for i in range(self.trial_counter+1,self.table.shape[0]): if self.table[i,1] == self.table[self.trial_counter,1]: self.table[i,11] = float(self.table[i,11]) + xadj self.table[i,12] = float(self.table[i,12]) + yadj self.table[i,13] = float(self.table[i,13]) + zadj ######### #LOGGING# ######### def play_success(self): if int(self.block) == 0: self.adjust_targets() self.pop.play() self.tar.hide() self.highlighted_indices = [0,1,2,3,4] def log_text(self): self.bgtext.setText('Now logging...') def log_data(self, task): if (self.trial_counter + 1) <= self.table.shape[0]: if self.space: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) self.movvars = np.column_stack((self.ts, self.statenum, self.data)) self.statenum = [] if self.mode=='task': with open(self.log_file_name, 'ab') as f: np.savetxt(f, self.movvars, fmt='%10.5f', delimiter=',') return task.cont else: pass def stoplog_text(self): self.dirtext.clearText() self.bgtext.setText('Done logging!') for i in range(5): self.players[i].show() ####### #RESET# ####### def delete_file(self): if (self.trial_counter + 1) <= self.table.shape[0]: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) try: os.remove(self.log_file_name) except OSError: pass else: pass def reset_baseline(self): self.med_data = None def reset_keyboard_bool(self): self.space = False def hide_target(self): self.tar.hide() self.intoObject.removeNode() self.imageObject.destroy() def update_trial_command(self): self.dirtext.setText(str(self.table[self.trial_counter,2])) if self.hand == 'Left': xfac = -0.25 else: xfac = 0.25 self.imageObject = OnscreenImage(image = str(self.table[self.trial_counter,3]),scale=(xfac,0.25,0.25),pos=(-1.2, 0, 0.3)) def increment_trial_counter(self): self.trial_counter += 1 self.update_trial_command() ######## #TIMERS# ######## def start_trial_countdown(self): self.countdown_timer.reset(self.max_time) def start_hold_countdown(self): self.hold_timer.reset(0.5) def start_post_countdown(self): self.countdown_timer.reset(2) def time_elapsed(self): return self.countdown_timer.elapsed() < 0 ######### #MACHINE# ######### def update_state(self, task): self.step() return task.cont def wait_for_space(self): return self.space def space_on(self): self.space = True ##### #END# ##### def trial_counter_exceeded(self): return (self.trial_counter+1) > self.table.shape[0]-1 def clean_up(self): #write last known positions to 'final_targets' file f = open('src/pinch_task/trialtable_flex.csv') header = f.readline().rstrip() np.savetxt(self.grip_dir + '/final_targets.csv',self.table,fmt='%s',header = header, delimiter=',') f.close() sys.exit() ######## #SERIAL# ######## def init_ser(self): #CONNECT TO HAPTIC DEVICE ports = list_ports.comports() mydev = next((p.device for p in ports if p.pid == 1155)) self.ser = serial.Serial(mydev,9600,timeout=.1) def sendsig(self,signal,finger,intensity): #would read from table, but table not available yet if intensity > 255: intensity = 255 dur_int = [signal,finger,intensity] data = struct.pack('3B',*dur_int) self.ser.write(data)
class DonkeyKong(ShowBase): def __init__(self): super().__init__(self) self.angle = 0 self.taskMgr.add(self.setup, "setup") self.taskMgr.add(self.update, "update") self.scene = self.loader.loadModel('models/DKSet') self.scene.reparentTo(self.render) self.arcadeTexture = self.loader.loadTexture('models/dk-arcade.png') self.scene.setTexture(self.arcadeTexture) self.scene.setTransparency(1) self.blocksTexture = self.loader.loadTexture('models/block.png') self.stairsTexture = self.loader.loadTexture('models/stairs.png') #messenger.toggleVerbose() def setup(self, task): lens = OrthographicLens() lens.setFilmSize(25, 20) base.camNode.setLens(lens) self.player = self.scene.attachNewNode("Player") self.marioGfx = self.scene.find('root/mario') self.marioGfx.reparentTo(self.player) self.jumpAvailable = False self.gravity = -.5 self.verticalTime = 0 self.v0 = 0 self.floorZ = 0 self.onStairs = False self.jumpCounter = 1 # input setup self.input = { 'up': False, 'down': False, 'left': False, 'right': False, 'space': False } key_list = ['up', 'down', 'left', 'right'] for k in key_list: self.accept(f'raw-arrow_{k}', self.buildPress(k)) self.accept(f'raw-arrow_{k}-up', self.buildRelease(k)) self.accept(f'raw-space', self.buildPress('space')) self.accept(f'raw-space-up', self.buildRelease('space')) # collision set up base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') ray = CollisionSegment(0, 0, 0, 0, 0, -.6) cNodePath = self.player.attachNewNode(CollisionNode('marioRay')) cNodePath.node().addSolid(ray) cNodePath.node().setIntoCollideMask(0x03) cNodePath.node().setFromCollideMask(0x03) cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) self.floor1 = self.createSquareCollider(-1.8, -5.5, 9.3, .5, 'floor0', 'floor1HitBox', 'Floor1', self.enableJump, self.disableJump, self.blocksTexture, 0x1) self.floor2 = self.createSquareCollider(2.08, -2.5, 8.0, .5, 'floor1', 'floor2HitBox', 'Floor2', self.enableJump, self.disableJump, self.blocksTexture, 0x1) self.floor3_1 = self.createSquareCollider(3.6, 0.5, 3.8, .5, 'floor2', 'floor3_1HitBox', 'Floor3_1', self.enableJump, self.disableJump, self.blocksTexture, 0x1) self.floor3_2 = self.createSquareCollider(-6.3, 0.5, 5, .5, 'pCube4', 'floor3_2HitBox', 'Floor3_2', self.enableJump, self.disableJump, self.blocksTexture, 0x1) self.floor4 = self.createSquareCollider(1.8, 3.5, 8.0, .5, 'floors', 'floor4HitBox', 'Floor4', self.enableJump, self.disableJump, self.blocksTexture, 0x1) self.topStair = self.createSquareCollider( -6.8, 3.5, 0.5, 2.5, 'topstair', 'topStairHitBox', 'TopStair', self.enableStairs, self.disableStairs, self.stairsTexture, 0x2) self.middleStair = self.createSquareCollider( -0.86, 0.1, 0.5, 2.5, 'middlestair', 'middleStairHitBox', 'MiddleStair', self.enableStairs, self.disableStairs, self.stairsTexture, 0x2) self.bottomStair = self.createSquareCollider( -6.8, -2.5, 0.5, 2.5, 'bottomstair', 'bottomStairHitBox', 'BottomStair', self.enableStairs, self.disableStairs, self.stairsTexture, 0x2) #self.createInvisibleSquareCollider(0,0,8,3,"NewCollision","NewNode") #self.createInvisibleSquareCollider(-6,0,4,5,"NewCollisio2","NewNode2") base.cTrav.showCollisions(self.render) # self.player.setPos(3,0,-3.5) self.player.setPos(-8, 0, -1.5) return Task.done def enableJump(self, evt): print(f'IN----> {evt}') self.floorZ = evt.getIntoNodePath().node().getParent( 0).getTransform().getPos().z + 1 self.jumpAvailable = True def disableJump(self, evt): print(f'Out----> {evt}') self.jumpAvailable = False def enableStairs(self, evt): print(f'IN----> {evt}') self.onStairs = True def disableStairs(self, evt): print(f'Out----> {evt}') self.onStairs = False def createSquareCollider(self, px, pz, w, h, modelName, collisionNodeName, nodeName, intoFunction, outFunction, texture, mask): obj = self.scene.attachNewNode(nodeName) hitBox = CollisionBox(Point3(0, 0, 0), w, 5, h) cNodePath = obj.attachNewNode(CollisionNode(collisionNodeName)) cNodePath.node().addSolid(hitBox) cNodePath.node().setIntoCollideMask(mask) cNodePath.node().setFromCollideMask(mask) #cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) self.scene.find(f'root/{modelName}').reparentTo(obj) obj.setPos(px, 0, pz) obj.setTexture(texture) self.accept(f'into-{collisionNodeName}', intoFunction) self.accept(f'outof-{collisionNodeName}', outFunction) return obj def createInvisibleSquareCollider(self, px, pz, w, h, collisionNodeName, nodeName, mask): obj = self.scene.attachNewNode(nodeName) hitBox = CollisionBox(Point3(0, 0, 0), w, 5, h) cNodePath = obj.attachNewNode(CollisionNode(collisionNodeName)) cNodePath.node().addSolid(hitBox) cNodePath.node().setIntoCollideMask(mask) cNodePath.node().setFromCollideMask(mask) cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) obj.setPos(px, 0, pz) def buildPress(self, key): def pressKey(): self.input[key] = True return pressKey def buildRelease(self, key): def releaseKey(): self.input[key] = False return releaseKey def applyMove(self): mv = Vec3(0, 0, 0) p = self.player.getPos() if (self.input["right"]): mv.x = -.1 if (self.input["left"]): mv.x = .1 """ if( self.input["space"]): playerPos.z += .1 if( self.input["down"]): playerPos.z -= .1 """ if (self.jumpAvailable and not self.onStairs): self.jumpCounter = 1 self.verticalTime = 0 self.v0 = 0 p.z = self.floorZ if (self.input["space"]): self.v0 = .165 self.jumpAvailable = False if (not self.jumpAvailable and not self.onStairs): self.verticalTime += globalClock.getDt() mv.z = self.v0 + self.gravity * self.verticalTime if (self.onStairs): self.jumpCounter = 0 self.v0 = 0 if (self.input["down"]): mv.z = -.1 if (self.input["up"]): mv.z = .1 if (not self.onStairs): if (not self.jumpAvailable): if (self.input["space"] and self.jumpCounter == 0): self.v0 = .165 self.jumpAvailable = False self.jumpCounter = 1 p.x += mv.x p.z += mv.z self.player.setPos(p) # hacer que se pueda agarrar el martillo, cuando suceda : self.marioGfx.setSx(self.player , -1) # self.hammer = self.createSquareCollider(6,1.5,.5,.5,'hammer','hammerHitbox', 'hammer', self.enableHammer, self.disableHammer, self.arcadeTexture, 0x02) def update(self, task): self.camera.setPos(0, 35, 0) self.camera.lookAt(self.scene) self.applyMove() return Task.cont
class Player(FSM, DirectObject): NormalMode = "Normal" FightMode = "Fight" GAMEPADMODE = "Gamepad" MOUSEANDKEYBOARD = "MouseAndKeyboard" def __init__(self): FSM.__init__(self, "FSM-Player") random.seed() # # PLAYER CONTROLS AND CAMERA # self.player = Actor( "Character", { "Idle": "Character-Idle", "Run": "Character-Run", "Activate": "Character-Activate", "Death": "Character-Death", "Jump": "Character-Jump", "Hit": "Character-Hit", "Fight_Attack": "Character-FightAttack", "Fight_Idle": "Character-FightIdle", "Fight_Left": "Character-FightLeft", "Fight_Right": "Character-FightRight", }, ) self.player.setBlend(frameBlend=True) # the initial cam distance self.fightCamDistance = 3.0 # the next two vars will set the min and max distance the cam can have # to the node it is attached to self.maxCamDistance = 4.0 self.minCamDistance = 1.2 # the initial cam distance self.camDistance = (self.maxCamDistance - self.minCamDistance) / 2.0 + self.minCamDistance # the next two vars set the min and max distance on the Z-Axis to the # node the cam is attached to self.maxCamHeightDist = 3.0 self.minCamHeightDist = 1.5 # the average camera height self.camHeightAvg = (self.maxCamHeightDist - self.minCamHeightDist) / 2.0 + self.minCamHeightDist # an invisible object which will fly above the player and will be used to # track the camera on it self.camFloater = NodePath(PandaNode("playerCamFloater")) self.camFloater.setPos(0, 0, 1.5) self.camFloater.reparentTo(self.player) # screen sizes self.winXhalf = base.win.getXSize() / 2 self.winYhalf = base.win.getYSize() / 2 # Interval for the jump animation self.jumpInterval = None self.jumpstartFloater = NodePath(PandaNode("jumpstartFloater")) self.jumpstartFloater.reparentTo(render) self.deathComplete = None # Joystick/Gamepad support self.hasJoystick = False if gamepadSupport: # initialize controls joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())] if len(joysticks) > 0: self.mainJoystick = joysticks[0] self.mainJoystick.init() self.hasJoystick = True # # WEAPONS AND ACCESSORIES # self.RightHandAttach = self.player.exposeJoint(None, "modelRoot", "HandAttach_R") self.spear = loader.loadModel("Spear") self.spear.setP(90) self.spear.setR(180) self.spear.reparentTo(self.RightHandAttach) self.LeftHandAttach = self.player.exposeJoint(None, "modelRoot", "HandAttach_L") self.shield = loader.loadModel("Shield") self.shield.setZ(0.05) self.shield.setH(-90) self.shield.reparentTo(self.LeftHandAttach) # # PLAYER COLLISION DETECTION AND PHYSICS # self.playerSphere = CollisionSphere(0, 0, 0.8, 0.7) self.playerCollision = self.player.attachNewNode(CollisionNode("playerCollision")) self.playerCollision.node().addSolid(self.playerSphere) base.pusher.addCollider(self.playerCollision, self.player) base.cTrav.addCollider(self.playerCollision, base.pusher) # The foot collision checks self.footRay = CollisionRay(0, 0, 0, 0, 0, -1) self.playerFootRay = self.player.attachNewNode(CollisionNode("playerFootCollision")) self.playerFootRay.node().addSolid(self.footRay) self.playerFootRay.node().setIntoCollideMask(0) self.lifter = CollisionHandlerFloor() self.lifter.addCollider(self.playerFootRay, self.player) self.lifter.setMaxVelocity(5) base.cTrav.addCollider(self.playerFootRay, self.lifter) # a collision segment slightly in front of the player to check for jump ledges self.jumpCheckSegment = CollisionSegment(0, -0.2, 0.5, 0, -0.2, -2) self.playerJumpRay = self.player.attachNewNode(CollisionNode("playerJumpCollision")) self.playerJumpRay.node().addSolid(self.jumpCheckSegment) self.playerJumpRay.node().setIntoCollideMask(0) self.jumper = CollisionHandlerEvent() self.jumper.addOutPattern("%fn-out") base.cTrav.addCollider(self.playerJumpRay, self.jumper) # a collision segment to check attacks self.attackCheckSegment = CollisionSegment(0, 0, 1, 0, -1.3, 1) self.playerAttackRay = self.player.attachNewNode(CollisionNode("playerAttackCollision")) self.playerAttackRay.node().addSolid(self.attackCheckSegment) self.playerAttackRay.node().setIntoCollideMask(0) self.attackqueue = CollisionHandlerQueue() base.cTrav.addCollider(self.playerAttackRay, self.attackqueue) # # SOUNDEFFECTS # self.footstep = loader.loadSfx("Footstep.ogg") self.footstep.setLoop(True) self.footstep.setPlayRate(1.5) self.footstep.setVolume(0.5) self.spearAttackSfx = loader.loadSfx("SpearAttack.ogg") self.spearAttackSfx.setVolume(0.5) # # START/STOP # def start(self, startPoint): self.player.setPos(startPoint.getPos()) self.player.setHpr(startPoint.getHpr()) self.player.reparentTo(render) self.jumpstartFloater.setPos(self.player.getPos()) self.keyMap = {"horizontal": 0, "vertical": 0} self.health = 3 self.trackedEnemy = None # this mode will be used to determine in which move mode the player currently is self.mode = Player.NormalMode # the initial cam height self.camHeight = self.camHeightAvg # a time to keep the cam zoom at a specific speed independent of # current framerate self.camElapsed = 0.0 self.mouseSpeedX = 15.0 * base.mouseSensitivity self.mouseSpeedY = 0.2 * base.mouseSensitivity self.speed = 1.0 self.camCenterEvents = ["centerCam", "home", "q"] self.camZoomInEvents = ["zoomIn", "+", "wheel_up"] self.camZoomOutEvents = ["zoomOut", "-", "wheel_down"] self.actionEvents = ["doAction", "enter", "e"] self.accept("arrow_left", self.setKey, ["horizontal", 1]) self.accept("arrow_right", self.setKey, ["horizontal", -1]) self.accept("arrow_up", self.setKey, ["vertical", -1]) self.accept("arrow_down", self.setKey, ["vertical", 1]) self.accept("arrow_left-up", self.setKey, ["horizontal", 0]) self.accept("arrow_right-up", self.setKey, ["horizontal", 0]) self.accept("arrow_up-up", self.setKey, ["vertical", 0]) self.accept("arrow_down-up", self.setKey, ["vertical", 0]) self.accept("a", self.setKey, ["horizontal", 1]) self.accept("d", self.setKey, ["horizontal", -1]) self.accept("w", self.setKey, ["vertical", -1]) self.accept("s", self.setKey, ["vertical", 1]) self.accept("a-up", self.setKey, ["horizontal", 0]) self.accept("d-up", self.setKey, ["horizontal", 0]) self.accept("w-up", self.setKey, ["vertical", 0]) self.accept("s-up", self.setKey, ["vertical", 0]) for event in self.camCenterEvents: self.acceptOnce(event, self.center) for event in self.camZoomInEvents: self.acceptOnce(event, self.zoom, [True]) for event in self.camZoomOutEvents: self.acceptOnce(event, self.zoom, [False]) for event in self.actionEvents: self.acceptOnce(event, self.request, ["Action"]) self.accept("ActionDone", self.request, ["Idle"]) self.accept("playerJumpCollision-out", self.jump) taskMgr.add(self.move, "task_movement", priority=-10) taskMgr.add(self.updateCam, "task_camActualisation", priority=-4) if self.hasJoystick: taskMgr.add(self.gamepadLoop, "task_gamepad_loop", priority=-5) camera.setPos(self.player, 0, self.camDistance, self.camHeightAvg) self.hasJumped = False self.isActionmove = False self.request("Idle") def stop(self): taskMgr.remove("task_movement") taskMgr.remove("task_camActualisation") taskMgr.remove("task_gamepad_loop") self.ignoreAll() self.player.hide() def cleanup(self): self.stop() if self.deathComplete is not None: self.deathComplete.finish() if self.jumpInterval is not None: self.jumpInterval.finish() self.spear.removeNode() self.shield.removeNode() self.player.cleanup() self.player.removeNode() self.jumpstartFloater.removeNode() self.camFloater.removeNode() # # BASIC FUNCTIONS # def die(self): self.health -= 1 base.messenger.send("setHealth", [self.health]) self.request("Death") def heal(self): if self.health >= 3: return self.health += 1 base.messenger.send("setHealth", [self.health]) def hit(self): self.health -= 1 base.messenger.send("setHealth", [self.health]) if self.health == 0: self.request("Death") else: self.request("Hit") def resetPlayerPos(self): self.player.setPos(self.jumpstartFloater.getPos()) self.jumper.clear() self.request("Idle") def gameOver(self): base.messenger.send("GameOver", ["loose"]) def enterFightMode(self, trackedEnemy): self.trackedEnemy = trackedEnemy self.mode = Player.FightMode base.messenger.send("EnterFightMode") def exitFightMode(self): self.trackedEnemy = None self.mode = Player.NormalMode base.messenger.send("ExitFightMode") def gamepadLoop(self, task): joymap = {0: "doAction", 5: "centerCam", 6: "zoomIn", 4: "zoomOut", 9: "escape"} for event in pygame.event.get(): for button in range(self.mainJoystick.get_numbuttons()): if button in joymap and self.mainJoystick.get_button(button): base.messenger.send(joymap[button]) if event.type == pygame.JOYAXISMOTION: for axis in range(self.mainJoystick.get_numaxes()): axisChange = 0.0 axisChange = self.mainJoystick.get_axis(axis) if axis == 0: self.setKey("horizontal", -axisChange) if axis == 1: self.setKey("vertical", axisChange) return task.cont def setAnimationSpeed(self, requestedState): if requestedState == "Run": self.player.setPlayRate(3 * self.speed, "Run") elif requestedState == "RunReverse": self.player.setPlayRate(-3 * self.speed, "Run") elif requestedState == "FightLeft": self.player.setPlayRate(2 * self.speed, "Fight_Left") elif requestedState == "FightRight": self.player.setPlayRate(2 * self.speed, "Fight_Right") # # MOVE FUNCTIONS # def setKey(self, key, value): self.keyMap[key] = value def move(self, task): dt = globalClock.getDt() resetMouse = False def resetMouse(): if base.controlType == Player.MOUSEANDKEYBOARD: base.win.movePointer(0, self.winXhalf, self.winYhalf) if self.player.getAnimControl("Hit").isPlaying() or self.player.getAnimControl("Death").isPlaying(): resetMouse() return task.cont if self.deathComplete is not None: if self.deathComplete.isPlaying(): resetMouse() return task.cont if self.jumpInterval is not None: if self.jumpInterval.isPlaying(): resetMouse() return task.cont if self.isActionmove: resetMouse() return task.cont if self.mode == Player.NormalMode: self.__normalMove(dt) else: self.__fightMove(dt) return task.cont def __normalMove(self, dt): requestState = "Idle" move = False if self.keyMap["horizontal"] != 0: requestState = "Run" move = True if self.keyMap["vertical"] != 0: requestState = "Run" move = True if move and base.controlType == Player.GAMEPADMODE: movementVec = Vec3(self.keyMap["horizontal"], self.keyMap["vertical"], 0) self.speed = max(abs(self.keyMap["horizontal"]), abs(self.keyMap["vertical"])) angle = math.atan2(-movementVec.getX(), movementVec.getY()) rotation = angle * (180.0 / math.pi) self.player.setH(camera, rotation) self.player.setP(0) self.player.setR(0) self.player.setPos(self.player, (0, -2 * self.speed * dt, 0)) elif base.controlType == Player.MOUSEANDKEYBOARD: if not base.mouseWatcherNode.hasMouse(): return self.pointer = base.win.getPointer(0) mouseX = self.pointer.getX() mouseY = self.pointer.getY() if base.win.movePointer(0, self.winXhalf, self.winYhalf): z = camera.getZ() + (mouseY - self.winYhalf) * self.mouseSpeedY * dt camera.setZ(z) h = self.player.getH() - (mouseX - self.winXhalf) * self.mouseSpeedX * dt if h < -360: h = 360 elif h > 360: h = -360 self.player.setH(h) if move: self.player.setPos( self.player, (2 * dt * self.keyMap["horizontal"], 2 * dt * self.keyMap["vertical"], 0) ) self.center() if self.state != requestState: self.request(requestState) self.setAnimationSpeed(requestState) def __fightMove(self, dt): if self.trackedEnemy == None: return requestState = "Idle" self.player.lookAt(self.trackedEnemy) self.player.setH(self.player, 180) if self.keyMap["horizontal"] > 0: self.player.setX(self.player, 2 * self.speed * dt) requestState = "FightLeft" elif self.keyMap["horizontal"] < 0: self.player.setX(self.player, -2 * self.speed * dt) requestState = "FightRight" elif self.keyMap["vertical"] < 0: self.player.setY(self.player, -2 * self.speed * dt) requestState = "Run" elif self.keyMap["vertical"] > 0: self.player.setY(self.player, 2 * self.speed * dt) requestState = "RunReverse" if self.state != requestState: self.request(requestState) self.setAnimationSpeed(requestState) def jump(self, extraArg): intoName = extraArg.getIntoNode().getName().lower() if not "floor" in intoName and not "plate" in intoName: return # setup the projectile interval startPos = self.player.getPos() self.jumpstartFloater.setPos(self.player, 0, 0.5, 0) tempFloater = NodePath(PandaNode("tempJumpFloater")) tempFloater.setPos(self.player, 0, -3.2, 0.1) endPos = tempFloater.getPos() tempFloater.removeNode() self.jumpInterval = ProjectileInterval( self.player, startPos=startPos, endPos=endPos, duration=1.5, gravityMult=0.25 ) self.request("Jump") self.jumpInterval.start() # # CAMERA FUNCTIONS # def updateCam(self, task): if self.mode == Player.NormalMode: self.__normalCam() else: self.__fightCam() return task.cont def zoom(self, zoomIn): # Camera Movement Updates camvec = self.player.getPos() - camera.getPos() camvec.setZ(0) camdist = camvec.length() zoom = 0 if zoomIn: if camdist > self.minCamDistance + 0.5: zoom = 0.5 for event in self.camZoomInEvents: self.acceptOnce(event, self.zoom, [True]) else: if camdist < self.maxCamDistance - 0.5: zoom = -0.5 for event in self.camZoomOutEvents: self.acceptOnce(event, self.zoom, [False]) camera.setPos(camera, 0, zoom, 0) def center(self): # Camera Movement Updates camvec = self.player.getPos() - camera.getPos() camvec.setZ(0) camdist = camvec.length() # get the cameras current offset to the player model on the z-axis offsetZ = camera.getZ() - self.player.getZ() camera.setPos(self.player, 0, camdist, offsetZ) for event in self.camCenterEvents: self.acceptOnce(event, self.center) def __normalCam(self): """This function will check the min and max distance of the camera to the defined model and will correct the position if the cam is to close or to far away""" # Camera Movement Updates camvec = self.player.getPos() - camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() # If far from player start following if camdist > self.maxCamDistance: camera.setPos(camera.getPos() + camvec * (camdist - self.maxCamDistance)) camdist = self.maxCamDistance # If player to close move cam backwards if camdist < self.minCamDistance: camera.setPos(camera.getPos() - camvec * (self.minCamDistance - camdist)) camdist = self.minCamDistance # get the cameras current offset to the player model on the z-axis offsetZ = camera.getZ() - self.player.getZ() # check if the camera is within the min and max z-axis offset if offsetZ < self.minCamHeightDist: camera.setZ(self.player.getZ() + self.minCamHeightDist) offsetZ = self.minCamHeightDist elif offsetZ > self.maxCamHeightDist: camera.setZ(self.player.getZ() + self.maxCamHeightDist) offsetZ = self.maxCamHeightDist if offsetZ != self.camHeightAvg and not base.controlType == Player.MOUSEANDKEYBOARD: # if we are not moving up or down, set the cam to an average position if offsetZ != self.camHeightAvg: if offsetZ > self.camHeightAvg: # the cam is higher then the average cam height above the player # so move it slowly down camera.setZ(camera.getZ() - 5 * globalClock.getDt()) newOffsetZ = camera.getZ() - self.player.getZ() # check if the cam has reached the desired offset if newOffsetZ < self.camHeightAvg: # set the cam z position to exactly the desired offset camera.setZ(self.player.getZ() + self.camHeightAvg) else: # the cam is lower then the average cam height above the player # so move it slowly up camera.setZ(camera.getZ() + 5 * globalClock.getDt()) newOffsetZ = camera.getZ() - self.player.getZ() # check if the cam has reached the desired offset if newOffsetZ > self.camHeightAvg: # set the cam z position to exactly the desired offset camera.setZ(self.player.getZ() + self.camHeightAvg) camera.lookAt(self.camFloater) def __fightCam(self): """This function will check the min and max distance of the camera to the defined model and will correct the position if the cam is to close or to far away""" camera.setX(self.player, 0) camera.setY(self.player, self.fightCamDistance) camera.setZ(0.5) camera.lookAt(self.camFloater) # # FSM FUNCTIONS # def enterIdle(self): if self.mode == Player.NormalMode: self.player.loop("Idle") self.footstep.stop() elif self.mode == Player.FightMode: self.player.loop("Fight_Idle") self.footstep.stop() def enterRun(self): self.player.loop("Run") self.footstep.play() def enterRunReverse(self): self.player.loop("Run") self.footstep.play() def enterAction(self): if self.player.getAnimControl("Hit").isPlaying() or self.player.getAnimControl("Death").isPlaying(): self.__exitAction() return self.isActionmove = True if self.mode == Player.NormalMode: self.__enterActivate() elif self.mode == Player.FightMode: self.__enterFightAttack() self.accept("ActionDone", self.__exitAction) def __exitAction(self): self.isActionmove = False for event in self.actionEvents: self.acceptOnce(event, self.request, ["Action"]) def __enterActivate(self): activateAnim = self.player.actorInterval("Activate", playRate=3) activateAnim.setDoneEvent("ActionDone") activateAnim.start() base.messenger.send("Player_Activate") self.footstep.stop() def enterDeath(self): self.footstep.stop() deathAnim = self.player.actorInterval("Death") deathComplete = None if self.health == 0: self.deathComplete = Sequence(deathAnim, Wait(2), Func(self.gameOver)) else: self.deathComplete = Sequence(deathAnim, Wait(2), Func(self.resetPlayerPos)) self.deathComplete.start() def enterJump(self): self.player.play("Jump") self.footstep.stop() def enterHit(self): self.player.setPlayRate(4, "Hit") self.player.play("Hit") self.footstep.stop() def __enterFightAttack(self): attackAnim = self.player.actorInterval("Fight_Attack", playRate=3) attackAnim.setDoneEvent("ActionDone") attackAnim.start() self.spearAttackSfx.play() for i in range(self.attackqueue.getNumEntries()): entry = self.attackqueue.getEntry(i) into = entry.getIntoNode() if "golemHitField" in into.getName(): if random.random() > 0.15: base.messenger.send("HitEnemy") self.footstep.stop() def enterFightLeft(self): self.player.loop("Fight_Left") self.footstep.play() def enterFightRight(self): self.player.loop("Fight_Right") self.footstep.play()
#** This is a task function called each frame, where the collision ray position is syncronized with the mouse pointer position def rayupdate(task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() # this function will set our ray to shoot from the actual camera lenses off the 3d scene, passing by the mouse pointer position, making magically hit what is pointed by it in the 3d space pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) return task.cont #** Now the tricky part: we have here a particular kind of pattern that react firing a task event when a collider, tagged as 'rays', whatever the value is stored into, hit an object tagged as 'balls', no matter what value is stored into its tag. The resulting event strings sent to the panda3D event manager will be the result of the FROM collider (ray) and the tag value owned by the INTO object being hit (a ball), provided that was settled with a tag key 'balls'. # That said, these two lines will catch all the events for either smiles and frowneys because we both tagged 'em as 'balls', for all IN events... collisionHandler.addInPattern("%(rays)ft-into-%(balls)it") # ...and here for the OUT events collisionHandler.addOutPattern("%(rays)ft-out-%(balls)it") #** To complicate things a little, this time we'll going to use the addAgainPattern method, that will raise an event while the mouse ponter is keeping over a ball of any group. Note that the 'ray_again_all' chunk will be used by the CollisionHandlerEvent to fire the event. See the related accept below. collisionHandler.addAgainPattern("ray_again_all%(" "rays" ")fh%(" "balls" ")ih") """ Note that we could have been done the same using this form as well: collisionHandler.addAgainPattern("%(rays)ft-again-%(balls)it") but then we should have used 2 accepts like this: DO.accept('ray1-again-smileys', collideAgainBalls) DO.accept('ray1-again-frowney', collideAgainBalls)
class DonkeyKong(ShowBase): def __init__(self): super().__init__(self) self.angle = 0 self.taskMgr.add(self.setup, "setup") self.taskMgr.add(self.update, "update") self.scene = self.loader.loadModel('models/DKSet') self.scene.reparentTo(self.render) self.arcadeTexture = self.loader.loadTexture('models/dk-arcade.png') self.scene.setTexture(self.arcadeTexture) self.scene.setTransparency(1) self.blocksTexture = self.loader.loadTexture('models/block.png') self.stairsTexture = self.loader.loadTexture('models/stairs.png') self.dkTimer = -1 self.lifeCounter = 3 self.playerLost = False self.playerWon = False #messenger.toggleVerbose() self.barrels_frames = [] self.barrels_frames.append(0) self.barrels_frames.append( 0.410573 - 0.375774) self.barrels_frames.append( 0.444913 - 0.375774) self.barrels_frames.append( 0.479941 - 0.375774) def setup(self,task): lens = OrthographicLens() lens.setFilmSize(23,19) base.camNode.setLens(lens) self.player = self.scene.attachNewNode("Player") self.marioGfx = self.scene.find('root/mario') self.marioGfx.reparentTo(self.player) self.marioGfx.setTwoSided(True) self.lifes = [ self.scene.attachNewNode("life1"), self.scene.attachNewNode("life2"), self.scene.attachNewNode("life3") ] self.marioGfx.instanceTo(self.lifes[0]) self.marioGfx.instanceTo(self.lifes[1]) self.marioGfx.instanceTo(self.lifes[2]) self.lifes[0].setPos(-9,0,7.5) self.lifes[1].setPos(-10,0,7.5) self.lifes[2].setPos(-11,0,7.5) self.hammerTime = False self.hammerDown = self.scene.find('root/hammerdowm') self.hammerDown.reparentTo(self.marioGfx) self.hammerDown.setPos(1,0,0) self.hammerUp = self.scene.find('root/hammerup') self.hammerUp.reparentTo(self.marioGfx) self.hammerUp.setPos(0,0,1) frame1 = Func(self.hammerFrame1) frame2 = Func(self.hammerFrame2) delay = Wait(0.1) self.hammerSequence = Sequence(frame1, delay, frame2, delay) # self.hammerSequence.loop() self.hammerUp.hide() self.hammerDown.hide() self.scene.find('root/walls').hide() self.scene.find('root/rightWall').hide() self.scene.find('root/barrel').setPos(0,100,0) self.jumpAvailable = False self.gravity = -.5 self.verticalTime = 0 self.v0 = 0 self.floorZ = 0 self.onStairs = False self.jumpCounter = 1 # input setup self.input = { 'up':False, 'down': False, 'left': False , 'right': False, 'space': False } key_list = ['up','down','left','right'] for k in key_list: self.accept(f'raw-arrow_{k}' , self.buildPress(k) ) self.accept(f'raw-arrow_{k}-up', self.buildRelease(k) ) self.accept(f'raw-space' , self.buildPress('space') ) self.accept(f'raw-space-up', self.buildRelease('space') ) # collision set up base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') ray = CollisionSegment(0,0,0,0,0,-.6) cNodePath = self.player.attachNewNode( CollisionNode('marioRay') ) cNodePath.node().addSolid(ray) cNodePath.node().setIntoCollideMask(0x03) cNodePath.node().setFromCollideMask(0x03) #cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) self.donkeykong = self.scene.find('root/donkeykong') self.donkeykonghit = self.createSquareCollider(8.7,5,1,1,'donkeykong','dkhitbox', 'DK' , self.reachedDK, self.exitDK , self.arcadeTexture, 0x02) self.createDkSequence() self.dk_sequence.start() self.floor1 = self.createSquareCollider(-1.8, -5.5 , 9.3, .5, 'floor0' , 'floor1HitBox', 'Floor1', self.enableJump, self.disableJump , self.blocksTexture, 0x1) self.floor2 = self.createSquareCollider(2.08, -2.5 , 8.0, .5, 'floor1' , 'floor2HitBox', 'Floor2', self.enableJump, self.disableJump , self.blocksTexture, 0x1) self.floor3_1 = self.createSquareCollider(3.6, 0.5 , 3.8, .5, 'floor2' , 'floor3_1HitBox', 'Floor3_1', self.enableJump, self.disableJump , self.blocksTexture, 0x1) self.floor3_2 = self.createSquareCollider(-6.3, 0.5 , 5, .5, 'pCube4' , 'floor3_2HitBox', 'Floor3_2', self.enableJump, self.disableJump , self.blocksTexture, 0x1) self.floor4 = self.createSquareCollider(1.8, 3.5 , 8.0, .5, 'floors' , 'floor4HitBox', 'Floor4', self.enableJump, self.disableJump , self.blocksTexture, 0x1) self.hammer = self.createSquareCollider(6,1.5,0.5,0.5,'hammer', 'hammerHitBox', 'hammer', self.enableHammer, self.disableHammer, self.arcadeTexture, 0x02) self.topStair = self.createSquareCollider(-6.8, 3.5 , 0.5, 2.5, 'topstair' , 'topStairHitBox', 'TopStair', self.enableStairs, self.disableStairs , self.stairsTexture, 0x2) self.middleStair= self.createSquareCollider(-0.86, 0.1 , 0.5, 2.5, 'middlestair' , 'middleStairHitBox', 'MiddleStair', self.enableStairs, self.disableStairs , self.stairsTexture, 0x2) self.bottomStair = self.createSquareCollider(-6.8, -2.5 , 0.5, 2.5, 'bottomstair' , 'bottomStairHitBox', 'BottomStair', self.enableStairs, self.disableStairs , self.stairsTexture, 0x2) self.leftWall = self.createInvisibleSquareCollider(-12.5, 0, 1, 10 , 'leftWallHitBox','leftWall',0x1) self.rightWall = self.createInvisibleSquareCollider(11.3, 0, 1, 20 , 'rightWallHitBox','rightWall',0x1) self.barrelDestroyer = self.createInvisibleSquareCollider(-.5,-10,10.5,1, 'barrelDestroyerHitBox' , 'barrelDestroyer' ,0x1) self.barrelBridge = self.createInvisibleSquareCollider(-0.4,0.5,2,0.5, 'barrelBridgeHitBox' , 'barrelBridge' ,0x4) self.accept('into-barrelCollider', self.barrelCrash) base.enableParticles() self.physicsCollisionPusher = PhysicsCollisionHandler() gravity = ForceNode('world-forces') gravityP = render.attachNewNode(gravity) gravityForce = LinearVectorForce(0,0,-9.81) gravity.addForce(gravityForce) base.physicsMgr.addLinearForce(gravityForce) #self.createInvisibleSquareCollider(0,0,8,3,"NewCollision","NewNode") #self.createInvisibleSquareCollider(-6,0,4,5,"NewCollisio2","NewNode2") #base.cTrav.showCollisions(self.render) # self.accept('raw-a', self.throwBarrel) # self.player.setPos(3,0,-3.5) self.player.setPos(-8,0,-1.5) return Task.done def reachedDK(self, evt): if self.hammerTime: self.playerWon = True else: self.playerLost = True pass def exitDK(self, evt): pass def calcNextBarrelThrow(self): self.dkTimer = random()*3+3 def changeDkFrame(self, dk,new_u, new_v): self.dkTimer = -1 dk.setTexOffset( TextureStage.getDefault() , new_u , new_v ) def createDkSequence(self): f1 = Func(self.changeDkFrame, self.donkeykong , 0.1408067 - 0.0446603 , 0 ) f2 = Func(self.changeDkFrame, self.donkeykong , 0.0431023 - 0.0446603 , 0.806672 - 0.703844 ) f3 = Func(self.changeDkFrame, self.donkeykong , 0 , 0 ) th = Func(self.throwBarrel) reset = Func(self.calcNextBarrelThrow) d = Wait(0.2) self.dk_sequence = Sequence(f1,d,f2,d,f3,th,d,f1,reset) def barrelCrash(self, evt): physicalBarrel = evt.getIntoNodePath().node().getParent(0).getParent(0) other = evt.getFromNodePath().node().getParent(0) if( other.name == 'leftWall' or other.name == 'rightWall'): forceNode = physicalBarrel.getChildren()[1] force = forceNode.getForce(0) force.setVector( force.getLocalVector().x*-1 , 0 ,0 ) forceNode.clear() forceNode.addForce(force) if( other.name == 'barrelDestroyer' ): self.scene.node().removeChild( physicalBarrel.getParent(0) ) if( other.name == 'Player' ): if(self.hammerTime): self.scene.node().removeChild( physicalBarrel.getParent(0) ) else: self.minusLife() def minusLife(self): self.lifes[self.lifeCounter-1].hide() self.lifeCounter -= 1 if( self.lifeCounter <= 0): self.playerLost = True def hammerFrame1(self): self.hammerUp.show() self.hammerDown.hide() def hammerFrame2(self): self.hammerUp.hide() self.hammerDown.show() def enableHammer(self, evt): self.hammerTime = True self.scene.node().removeChild( evt.getIntoNodePath().node().getParent(0) ) self.hammerSequence.loop() def disableHammer(self, evt): pass def enableJump(self, evt): #print(f'IN----> {evt}') self.floorZ = evt.getIntoNodePath().node().getParent(0).getTransform().getPos().z + 1 self.jumpAvailable = True def disableJump(self, evt): #print(f'Out----> {evt}') self.jumpAvailable = False def enableStairs(self, evt): #print(f'IN----> {evt}') self.onStairs = True def disableStairs(self, evt): #print(f'Out----> {evt}') self.onStairs = False def throwBarrel(self): barrelNode = self.scene.attachNewNode("PhysicalBarrel") physicalBarrel = ActorNode("physics_barrel") physicalBarrel.getPhysicsObject().setMass(0.01) barrel = barrelNode.attachNewNode(physicalBarrel) base.physicsMgr.attachPhysicalNode(physicalBarrel) visualBarrel = barrel.attachNewNode("BarrelCopy") originalBarrel = self.scene.find('root/barrel') originalBarrel.instanceTo(visualBarrel) visualBarrel.setPos(0,-100,0) sphere = CollisionSphere(0.16,100,0,0.5) cNodePath = visualBarrel.attachNewNode( CollisionNode("barrelCollider") ) cNodePath.node().addSolid(sphere) cNodePath.node().setIntoCollideMask(0x05) cNodePath.node().setFromCollideMask(0x05) #cNodePath.show() self.physicsCollisionPusher.addCollider(cNodePath, barrel) base.cTrav.addCollider(cNodePath, self.physicsCollisionPusher) barrelForceNode = ForceNode("barrelForce") barrel.attachNewNode(barrelForceNode) barrelForce = LinearVectorForce(-8,0,0,1,False) barrelForceNode.addForce(barrelForce) physicalBarrel.getPhysical(0).addLinearForce(barrelForce) barrelNode.setPos(self.scene,7 , 0 , 4.5) dataNode = AuxNode("sequenceData") seq = self.createBarrelSequence(visualBarrel , physicalBarrel, dataNode ) dataNode.setSequence(seq) barrelNode.attachNewNode(dataNode) def createBarrelSequence(self, vBarrel, pBarrel, dNode ): def updateBarrel(): vel = pBarrel.getPhysicsObject().getVelocity() frame = dNode.frame if( vel.x > 0 ): frame = (frame+1)%4 if( vel.x < 0): frame = (frame-1)%4 dNode.frame = frame vBarrel.setTexOffset( TextureStage.getDefault() , self.barrels_frames[frame] , 0 ) f1 = Func(updateBarrel) d = Wait(0.1) seq = Sequence(f1,d) seq.loop() return seq def createSquareCollider(self, px,pz, w, h, modelName, collisionNodeName, nodeName , intoFunction, outFunction, texture, mask ): obj = self.scene.attachNewNode(nodeName) hitBox = CollisionBox( Point3(0,0,0), w, 5, h ) cNodePath = obj.attachNewNode( CollisionNode(collisionNodeName) ) cNodePath.node().addSolid(hitBox) cNodePath.node().setIntoCollideMask(mask) cNodePath.node().setFromCollideMask(mask) #cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) self.scene.find(f'root/{modelName}').reparentTo(obj) obj.setPos(px,0,pz) obj.setTexture(texture) self.accept(f'into-{collisionNodeName}' , intoFunction) self.accept(f'outof-{collisionNodeName}' , outFunction) return obj def createInvisibleSquareCollider(self, px,pz, w, h, collisionNodeName, nodeName , mask ): obj = self.scene.attachNewNode(nodeName) hitBox = CollisionBox( Point3(0,0,0), w, 5, h ) cNodePath = obj.attachNewNode( CollisionNode(collisionNodeName) ) cNodePath.node().addSolid(hitBox) cNodePath.node().setIntoCollideMask(mask) cNodePath.node().setFromCollideMask(mask) #cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) obj.setPos(px,0,pz) def buildPress(self,key): def pressKey(): self.input[key] = True return pressKey def buildRelease(self, key): def releaseKey(): self.input[key] = False return releaseKey def applyMove(self): mv = Vec3(0,0,0) p = self.player.getPos() if( self.input["right"]): mv.x = -.1 self.marioGfx.setSx(self.player , -1) self.lifes[0].setSx(-1) self.lifes[1].setSx(-1) self.lifes[2].setSx(-1) if( self.input["left"]): mv.x = .1 self.marioGfx.setSx(self.player , 1) self.lifes[0].setSx(1) self.lifes[1].setSx(1) self.lifes[2].setSx(1) """ if( self.input["space"]): playerPos.z += .1 if( self.input["down"]): playerPos.z -= .1 """ if( self.jumpAvailable and not self.onStairs ): self.jumpCounter = 1 self.verticalTime = 0 self.v0 = 0 p.z = self.floorZ if(self.input["space"]): self.v0 = .165 self.jumpAvailable = False if(not self.jumpAvailable and not self.onStairs): self.verticalTime += globalClock.getDt() mv.z = self.v0 + self.gravity*self.verticalTime if( self.onStairs): self.jumpCounter = 0 self.v0 = 0 if( self.input["down"]): mv.z = -.1 if( self.input["up"]): mv.z = .1 if( not self.onStairs ): if(not self.jumpAvailable): if(self.input["space"] and self.jumpCounter == 0): self.v0 = .165 self.jumpAvailable = False self.jumpCounter = 1 p.x += mv.x p.z += mv.z self.player.setPos(p) # hacer que se pueda agarrar el martillo, cuando suceda : self.marioGfx.setSx(self.player , -1) # self.hammer = self.createSquareCollider(6,1.5,.5,.5,'hammer','hammerHitbox', 'hammer', self.enableHammer, self.disableHammer, self.arcadeTexture, 0x02) def update(self, task): self.camera.setPos(0,35,0) self.camera.lookAt(self.scene) if( self.dkTimer > -1): self.dkTimer -= globalClock.getDt() if(self.dkTimer <= 0): self.dk_sequence.start() if( self.playerLost): text = DirectLabel(text="Player Lost" , text_scale=(0.5,0.5) ) return Task.done if( self.playerWon): text = DirectLabel(text="Player Won" , text_scale=(0.5,0.5) ) return Task.done self.applyMove() return Task.cont
class Player(DirectObject): def __init__(self, _main): self.main = _main self.name = "" self.points = 0 self.health = 100.0 self.runSpeed = 1.8 self.keyMap = { "left":False, "right":False, "up":False, "down":False } base.camera.setPos(0,0,0) self.model = loader.loadModel("Player") self.model.find('**/+SequenceNode').node().stop() self.model.find('**/+SequenceNode').node().pose(0) base.camera.setP(-90) self.playerHud = Hud() self.playerHud.hide() self.model.hide() # Weapons: size=2, 0=main, 1=offhand self.mountSlot = [] self.activeWeapon = None self.isAutoActive = False self.trigger = False self.lastShot = 0.0 self.fireRate = 0.0 self.playerTraverser = CollisionTraverser() self.playerEH = CollisionHandlerEvent() ## INTO PATTERNS self.playerEH.addInPattern('intoPlayer-%in') #self.playerEH.addInPattern('colIn-%fn') self.playerEH.addInPattern('intoHeal-%in') self.playerEH.addInPattern('intoWeapon-%in') ## OUT PATTERNS self.playerEH.addOutPattern('outOfPlayer-%in') playerCNode = CollisionNode('playerSphere') playerCNode.setFromCollideMask(BitMask32.bit(1)) playerCNode.setIntoCollideMask(BitMask32.bit(1)) self.playerSphere = CollisionSphere(0, 0, 0, 0.6) playerCNode.addSolid(self.playerSphere) self.playerNP = self.model.attachNewNode(playerCNode) self.playerTraverser.addCollider(self.playerNP, self.playerEH) #self.playerNP.show() self.playerPusher = CollisionHandlerPusher() self.playerPusher.addCollider(self.playerNP, self.model) self.playerPushTraverser = CollisionTraverser() self.playerPushTraverser.addCollider(self.playerNP, self.playerPusher) def acceptKeys(self): self.accept("w", self.setKey, ["up", True]) self.accept("w-up", self.setKey, ["up", False]) self.accept("a", self.setKey, ["left", True]) self.accept("a-up", self.setKey, ["left", False]) self.accept("s", self.setKey, ["down", True]) self.accept("s-up", self.setKey, ["down", False]) self.accept("d", self.setKey, ["right", True]) self.accept("d-up", self.setKey, ["right", False]) # Add mouse btn for fire() self.accept("mouse1", self.setWeaponTrigger, [True]) self.accept("mouse1-up", self.setWeaponTrigger, [False]) # Killed enemies self.accept("killEnemy", self.addPoints) # Game states self.accept("doDamageToPlayer", self.doDamage) def ignoreKeys(self): self.ignore("w") self.ignore("a") self.ignore("s") self.ignore("d") self.ignore("killEnemy") self.ignore("mouse1") self.ignore("mouse1-up") for item in self.main.itemList: if item.type == "heal": self.ignore("intoHeal-" + "itemHeal" + str(item.id)) elif item.type == "gun": self. ignore("intoWeapon-" + "itemWeapon" + str(item.id)) for enemy in self.main.enemyList: self.ignore("intoPlayer-" + "colEnemy" + str(enemy.id)) # Add mouse btn for fire to ignore def setKey(self, action, pressed): self.keyMap[action] = pressed def start(self, startPos, playerName): self.name = playerName self.points = 0 self.health = 100 self.model.reparentTo(render) self.model.setPos(startPos.x, startPos.y, 0) for slot in self.mountSlot[:]: self.mountSlot.remove(slot) # Create a basic weapon self.mountSlot.append(Weapon(self.main, "Pistol", 0.30, 25, weaponType="Pistol")) # Mount the players default weapon self.mountWeapon(self.mountSlot[0]) self.playerHud.setWeapon("Pistol") self.acceptKeys() self.playerHud.show() taskMgr.add(self.move, "moveTask") def stop(self): taskMgr.remove("moveTask") self.ignoreKeys() self.unmountWeapon() self.playerHud.hide() self.model.hide() def addPoints(self, args): self.points += 10 base.messenger.send("setHighscore", [self.points]) def move(self, task): elapsed = globalClock.getDt() #self.playerTraverser.traverse(self.main.enemyParent) #self.playerTraverser.traverse(self.main.itemParent) # set headding pos = self.main.mouse.getMousePos() pos.setZ(0) self.model.lookAt(pos) self.model.setP(-90) # new player position if self.keyMap["up"]: # follow mouse mode #self.model.setZ(self.model, 5 * elapsed * self.runSpeed) # axis move mode self.model.setY(self.model.getY() + elapsed * self.runSpeed) elif self.keyMap["down"]: #self.model.setZ(self.model, -5 * elapsed * self.runSpeed) self.model.setY(self.model.getY() - elapsed * self.runSpeed) if self.keyMap["left"]: # follow mouse mode #self.model.setX(self.model, -5 * elapsed * self.runSpeed) # axis move mode self.model.setX(self.model.getX() - elapsed * self.runSpeed) elif self.keyMap["right"]: #self.model.setX(self.model, 5 * elapsed * self.runSpeed) self.model.setX(self.model.getX() + elapsed * self.runSpeed) # actualize cam position base.camera.setPos(self.model.getPos()) base.camera.setZ(20) return task.cont def mountWeapon(self, _weaponToMount): self.activeWeapon = _weaponToMount # self.mountSlot[0] if self.activeWeapon.style == "TwoHand": self.model.find('**/+SequenceNode').node().pose(0) else: self.model.find('**/+SequenceNode').node().pose(1) self.activeWeapon.model.reparentTo(self.model) self.activeWeapon.model.setY(self.model.getY() - 0.1) self.model.show() self.activeWeapon.model.show() self.fireRate = self.activeWeapon.fireRate def unmountWeapon(self): self.activeWeapon.model.hide() def setWeaponTrigger(self, _state): self.trigger = _state if _state: mpos = self.main.mouse.getMousePos() self.activeWeapon.doFire(mpos) if self.activeWeapon.weaponType == "MG": self.fireActiveWeapon() else: self.activeWeapon.stopFire() else: self.activeWeapon.stopFire() taskMgr.remove("Fire") def fireActiveWeapon(self): if self.activeWeapon: #mpos = self.main.mouse.getMousePos() taskMgr.add(self.fireUpdate, "Fire") #self.activeWeapon.doFire(mpos) def fireUpdate(self, task): dt = globalClock.getDt() self.lastShot += dt mpos = self.main.mouse.getMousePos() #print self.lastShot if self.lastShot >= self.fireRate: self.lastShot -= self.fireRate if self.trigger: self.activeWeapon.doFire(mpos) #task.delayTime += self.fireRate return task.again def setMouseBtn(self): self.trigger = False print "Mouse Released" def addEnemyDmgEvent(self, _id): self.accept("intoPlayer-" + "colEnemy" + str(_id), self.setEnemyAttack) #self.accept("outOfPlayer-" + "colEnemy" + str(_id), self.setEnemyAttackOutOfRange) def setEnemyAttack(self, _entry): enemyColName = _entry.getIntoNodePath().node().getName() base.messenger.send("inRange-" + enemyColName, [True]) def setEnemyAttackOutOfRange(self, _entry): enemyColName = _entry.getIntoNodePath().node().getName() base.messenger.send("inRange-" + enemyColName, [False]) def doDamage(self, _dmg): if self.health <= 0: #print "KILLED IN ACTION" self.main.stop() else: self.health -= _dmg #print "Remaining Health: ", self.health base.messenger.send("setHealth", [self.health]) def addHealItemEvent(self, _id): self.accept("intoHeal-" + "itemHeal" + str(_id), self.healPlayer) def healPlayer(self, _entry): itemColName = _entry.getIntoNodePath().node().getName() if self.health == 100: pass else: self.health += 50 base.messenger.send("into-" + itemColName) if self.health > 100: self.health = 100 print self.health def addWeaponItemEvent(self, _id): self.accept("intoWeapon-" + "itemWeapon" + str(_id), self.changeWeapon) def changeWeapon(self, _entry): itemColName = _entry.getIntoNodePath().node().getName() base.messenger.send("into-" + itemColName) for weapon in self.mountSlot: if weapon.name == "MachineGun": return self.unmountWeapon() self.mountSlot.append(Weapon(self.main, "MachineGun", 0.15, 50, weaponType="MG")) self.playerHud.setWeapon("MG") self.mountWeapon(self.mountSlot[len(self.mountSlot) - 1]) self.activeWeapon.model.show()
class Starfox(ShowBase): def __init__(self): self.height = 500 super().__init__(self) self.scene = self.loader.loadModel("./models/world.egg") playerTexture = loader.loadTexture("models/starfoxShip.jpg") enemyTexture = loader.loadTexture("models/enemyShip.jpg") bulletTexture = loader.loadTexture("models/shot.png") self.scene.reparentTo(self.render) base.setBackgroundColor(0.1, 0.1, 0.1, 1) self.player = self.scene.find("player") self.player.setPythonTag("ObjectController", Player(self.player)) self.player.setTexture(playerTexture) self.building_enemy = self.scene.find("building_enemy") self.dynamic_enemy = self.scene.find("enemy1") self.dynamic_enemy.setTexture(enemyTexture) self.bullet = self.scene.find("bullet") self.bullet.setTexture(bulletTexture) base.cTrav = CollisionTraverser() self.CollisionHandlerEvent = CollisionHandlerEvent() base.enableParticles() self.CollisionHandlerEvent.addInPattern('into-%in') self.CollisionHandlerEvent.addOutPattern('out-%in') self.accept('into-collision_player', self.crash) self.accept('into-collision_plane', self.crash) self.accept('into-collision_enemy', self.crash) base.cTrav.addCollider(self.scene.find("player/collision**"), self.CollisionHandlerEvent) base.cTrav.addCollider(self.scene.find("basePlane/collision**"), self.CollisionHandlerEvent) self.player.find("**collision**").node().setFromCollideMask(0x3) self.player.find("**collision**").node().setIntoCollideMask(0x3) self.dynamic_enemy.find("**collision**").node().setFromCollideMask(0x5) self.dynamic_enemy.find("**collision**").node().setIntoCollideMask(0x5) self.building_enemy.find("**collision**").node().setFromCollideMask( 0x5) self.building_enemy.find("**collision**").node().setIntoCollideMask( 0x5) #base.cTrav.showCollisions(self.render) self.taskMgr.add(self.update, "update") InputManager.initWith(self, [ InputManager.arrowUp, InputManager.arrowDown, InputManager.arrowLeft, InputManager.arrowRight, InputManager.space, InputManager.keyX, InputManager.keyV ]) self.rails = self.scene.attachNewNode("rails") self.scene.find("basePlane").setHpr(70, 0, 0) self.rails.setPos(self.scene, 0, 0, 0) self.player.reparentTo(self.rails) self.player.setPos(self.rails, 0, 0, 0) self.rails_y = -50 self.createStaticEnemy(self.building_enemy, 0, 50, 0) self.createStaticEnemy(self.building_enemy, -50, 50, 0) self.createStaticEnemy(self.building_enemy, -100, 50, 0) self.createStaticEnemy(self.building_enemy, -70, 130, 0) self.createStaticEnemy(self.building_enemy, -120, 80, 0) self.createStaticEnemy(self.building_enemy, -220, 130, 0) DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-230, 140, 10), base.cTrav, self.CollisionHandlerEvent, type=ENEMY_TYPE.CHASER) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-240,160,10) , base.cTrav, self.CollisionHandlerEvent) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-250,200,10) , base.cTrav, self.CollisionHandlerEvent) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-270,160,10) , base.cTrav, self.CollisionHandlerEvent) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-250,200,10) , base.cTrav, self.CollisionHandlerEvent) self.building_enemy.hide() self.dynamic_enemy.hide() self.fog = Fog("fog") self.fog.setColor(0.1, 0.1, 0.1) self.fog.setExpDensity(.3) self.fog.setLinearRange(50, 150) self.fog.setLinearFallback(45, 160, 320) self.render.setFog(self.fog) self.dirLight = DirectionalLight("dir light") self.dirLight.color = (0.7, 0.7, 1, 1) self.dirLightPath = self.render.attachNewNode(self.dirLight) self.dirLightPath.setHpr(45, -45, 0) self.dirLight.setShadowCaster(True, 512, 512) render.setLight(self.dirLightPath) filters = CommonFilters(base.win, base.cam) filters.setBloom(size="large", mintrigger=0.2) self.render.setShaderAuto() self.initSounds() self.initUI() self.onGame = False def initUI(self): self.font = loader.loadFont('./fonts/Magenta.ttf') self.lifes = [ OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(1.1, 0, 0.8), scale=0.05), OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(1.2, 0, 0.8), scale=0.05) ] self.lifes[0].setTransparency(True) self.lifes[1].setTransparency(True) self.dialogScreen = DirectDialog(frameSize=(-0.7, 0.7, -0.7, 0.7), relief=DGG.FLAT) s = OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(0, 0, -0.2), scale=0.20, parent=self.dialogScreen) s.setTransparency(True) self.titleUI = DirectLabel(text="Starfox Region 4", parent=self.dialogScreen, scale=0.1, pos=(0, 0, .2), text_font=self.font) self.btn = DirectButton(text="Start", command=self.startGame, pos=(0, 0, 0), parent=self.dialogScreen, scale=0.07) def startGame(self): self.dialogScreen.hide() self.flyingSound.play() self.onGame = True self.btn.hide() def initSounds(self): self.audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], self.camera) self.flyingSound = self.audio3d.loadSfx( "./sounds/great fox flying.mp3") self.flyingSound.setLoop(True) self.audio3d.attachSoundToObject(self.flyingSound, self.player) self.audio3d.setSoundVelocityAuto(self.flyingSound) self.audio3d.setListenerVelocityAuto() #self.audio3d.setDistanceFactor(100) self.audio3d.setDropOffFactor(0) self.fireSound = self.audio3d.loadSfx( "./sounds/arwing double laser one shot.mp3") self.crashSound = self.audio3d.loadSfx("./sounds/break.mp3") def createStaticEnemy(self, original, px, py, pz): be = original.copyTo(self.scene) be.setPos(px, py, pz) base.cTrav.addCollider(be.find("**collision**"), self.CollisionHandlerEvent) """ self.pointLight = PointLight("point light") self.pointLight.color = (1,1,1,1) self.pointLightPath = self.render.attachNewNode(self.pointLight) self.pointLightPath.setPos(px,py,pz) self.pointLight.attenuation = (1,0,0) #self.pointLight.setShadowCaster(True,1024,1024) self.render.setLight(self.pointLightPath) """ def crash(self, evt): self.crashSound.play() objectInto = evt.getIntoNodePath().node().getParent(0).getPythonTag( "ObjectController") objectFrom = evt.getFromNodePath().node().getParent(0).getPythonTag( "ObjectController") if (objectInto != None): objectInto.crash(objectFrom) if (objectFrom != None): objectFrom.crash(objectInto) lifes = self.player.getPythonTag("ObjectController").getLifes() if (lifes <= 0): self.onGame = False self.dialogScreen.show() self.flyingSound.stop() def update(self, evt): #self.camera.setPos(0,-100,100) lifes = self.player.getPythonTag("ObjectController").getLifes() if (lifes > 2): self.lifes[0].show() self.lifes[1].show() elif (lifes > 1): self.lifes[0].show() self.lifes[1].hide() elif (lifes > 0): self.lifes[0].hide() self.lifes[1].hide() self.camera.lookAt(self.player) self.rails.setPos(self.scene, Path.getXOfY(self.rails_y), self.rails_y, 12.4) self.rails.setHpr(Path.getHeading(self.rails_y), 0, 0) self.dirLight.color = (self.rails_y / 600, 0.7, 1, 1) self.camera.setHpr(Path.getHeading(self.rails_y), 0, 0) if (self.onGame): self.rails_y = self.rails_y + globalClock.getDt() * 10 #self.player.setPos(self.rails, 0, 0, sin(self.z/10.0)*40 ) relX, relZ, isShooting = self.player.getPythonTag( "ObjectController").update(self.rails, globalClock.getDt()) self.camera.setPos(self.rails, relX, -30, relZ) if (isShooting): self.fireSound.play() b = Bullet( self.bullet, self.scene, self.player.getPos(self.scene), base.cTrav, self.CollisionHandlerEvent, self.scene.getRelativeVector(self.player, Vec3(0, 1, 0)), 40, 0x4) enemies = self.scene.findAllMatches("dynamicEnemy") for e in enemies: enemy = e.getPythonTag("ObjectController") enemy.update(self.scene, globalClock.getDt(), self.player, self.bullet) bullets = self.scene.findAllMatches("bulletC") for b in bullets: bullet = b.getPythonTag("ObjectController") bullet.update(self.scene, globalClock.getDt(), self.player) return Task.cont
class World(DirectObject): def __init__(self): # Initialize the traverser. base.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.collHandEvent.addOutPattern('outof-%in') # Make a variable to store the unique collision string count. self.collCount = 0 # Load a model. Reparent it to the camera so we can move it. s = base.loader.loadModel('smiley') s.reparentTo(base.camera) s.setPos(0, 25, 0) # Setup a collision solid for this model. sColl = self.initCollisionSphere(s, True) # Add this object to the traverser. base.cTrav.addCollider(sColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + sColl[1], self.collide3) self.accept('outof-' + sColl[1], self.collide4) print(sColl[1]) # Load another model. t = base.loader.loadModel('smiley') t.reparentTo(base.render) t.setPos(5, 25, 0) # Setup a collision solid for this model. tColl = self.initCollisionSphere(t, True) # Add this object to the traverser. base.cTrav.addCollider(tColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + tColl[1], self.collide) self.accept('outof-' + tColl[1], self.collide2) print(tColl[1]) print("WERT") def collide(self, collEntry): print("WERT: object has collided into another object") collParent = collEntry.getFromNodePath().getParent() Sequence( Func(collParent.setColor, (1, 0, 0, 1)), Wait(0.2), Func(collParent.setColor, (0, 1, 0, 1)), Wait(0.2), Func(collParent.setColor, (1, 1, 1, 1)), ).start() def collide2(self, collEntry): print("WERT.: object is no longer colliding with another object") def collide3(self, collEntry): print("WERT2: object has collided into another object") def collide4(self, collEntry): print("WERT2: object is no longer colliding with another object") def initCollisionSphere(self, obj, show=False): # Get the size of the object for the collision sphere. bounds = obj.getChild(0).getBounds() center = bounds.getCenter() radius = bounds.getRadius() * 1.1 # Create a collision sphere and name it something understandable. collSphereStr = 'CollisionHull{0}_{1}'.format(self.collCount, obj.name) self.collCount += 1 cNode = CollisionNode(collSphereStr) cNode.addSolid(CollisionSphere(center, radius)) cNodepath = obj.attachNewNode(cNode) if show: cNodepath.show() # Return a tuple with the collision node and its corrsponding string so # that the bitmask can be set. return (cNodepath, collSphereStr)
class CogdoFlyingCollisions(GravityWalker): wantFloorSphere = 0 def __init__(self): GravityWalker.__init__(self, gravity=0.0) def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0): self.cHeadSphereNodePath = None self.cFloorEventSphereNodePath = None self.setupHeadSphere(avatarNodePath) self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius) GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach) return def setupWallSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius) cSphereNode = CollisionNode('Flyer.cWallSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) if config.GetBool('want-fluid-pusher', 0): self.pusher = CollisionHandlerFluidPusher() else: self.pusher = CollisionHandlerPusher() self.pusher.addCollider(cSphereNodePath, self.avatarNodePath) self.cWallSphereNodePath = cSphereNodePath def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath def setupRay(self, bitmask, floorOffset, reach): cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0) cRayNode = CollisionNode('Flyer.cRayNode') cRayNode.addSolid(cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerGravity() self.lifter.setLegacyMode(self._legacyLifter) self.lifter.setGravity(self.getGravity(0)) self.lifter.addInPattern('%fn-enter-%in') self.lifter.addAgainPattern('%fn-again-%in') self.lifter.addOutPattern('%fn-exit-%in') self.lifter.setOffset(floorOffset) self.lifter.setReach(reach) self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath def deleteCollisions(self): GravityWalker.deleteCollisions(self) if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) self.cHeadSphereNodePath.detachNode() self.cHeadSphereNodePath = None self.headCollisionsEvent = None if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) self.cFloorEventSphereNodePath.detachNode() self.cFloorEventSphereNodePath = None self.floorCollisionEvent = None self.cRayNodePath.detachNode() del self.cRayNodePath self.cEventSphereNodePath.detachNode() del self.cEventSphereNodePath return def setCollisionsActive(self, active = 1): if self.collisionsActive != active: if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) if active: base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) if active: base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent) GravityWalker.setCollisionsActive(self, active) return def enableAvatarControls(self): pass def disableAvatarControls(self): pass def handleAvatarControls(self, task): pass
def __init__(self): global collide ShowBase.__init__(self) self.traverser = CollisionTraverser('traverser1') base.cTrav = self.traverser #traverser.addCollider(cnode1, handler) entry = 1 imageObject = OnscreenImage(image = '/Users/devanshi/Downloads/sky.png', pos = (0, 0, 0), scale = 2) imageObject.setTransparency(TransparencyAttrib.MAlpha) base.cam.node().getDisplayRegion(0).setSort(20) self.forest=NodePath(PandaNode("Forest Root")) self.forest.reparentTo(render) loader.loadModel("models/background").reparentTo(self.forest) loader.loadModel("models/foliage01").reparentTo(self.forest) loader.loadModel("models/foliage02").reparentTo(self.forest) loader.loadModel("models/foliage03").reparentTo(self.forest) loader.loadModel("models/foliage04").reparentTo(self.forest) loader.loadModel("models/foliage05").reparentTo(self.forest) loader.loadModel("models/foliage06").reparentTo(self.forest) loader.loadModel("models/foliage07").reparentTo(self.forest) loader.loadModel("models/foliage08").reparentTo(self.forest) loader.loadModel("models/foliage09").reparentTo(self.forest) self.forest1=NodePath(PandaNode("Forest Root")) self.forest1.reparentTo(render) loader.loadModel("models/foliage01").reparentTo(self.forest1) loader.loadModel("models/foliage02").reparentTo(self.forest1) loader.loadModel("models/foliage03").reparentTo(self.forest1) loader.loadModel("models/foliage04").reparentTo(self.forest1) loader.loadModel("models/foliage05").reparentTo(self.forest1) loader.loadModel("models/foliage06").reparentTo(self.forest1) loader.loadModel("models/foliage07").reparentTo(self.forest1) loader.loadModel("models/foliage08").reparentTo(self.forest1) loader.loadModel("models/foliage09").reparentTo(self.forest1) self.forest.hide(BitMask32.bit(1)) self.forest.setScale(2.5, 2.5, 2.5) self.forest.setPos(0, 0, -2) self.forest1.hide(BitMask32.bit(1)) self.forest1.setScale(1.5, 1.5, 1.5) self.forest1.setPos(-1,-1, 0) self.forest2=NodePath(PandaNode("Forest Root")) self.forest2.reparentTo(render) loader.loadModel("models/foliage01").reparentTo(self.forest2) loader.loadModel("models/foliage02").reparentTo(self.forest2) loader.loadModel("models/foliage03").reparentTo(self.forest2) loader.loadModel("models/foliage04").reparentTo(self.forest2) loader.loadModel("models/foliage05").reparentTo(self.forest2) loader.loadModel("models/foliage06").reparentTo(self.forest2) loader.loadModel("models/foliage07").reparentTo(self.forest2) loader.loadModel("models/foliage08").reparentTo(self.forest2) loader.loadModel("models/foliage09").reparentTo(self.forest2) self.forest2.hide(BitMask32.bit(1)) self.forest1.setScale(1.5, 1.5, 1.5) self.forest1.setPos(1,1, 0) self.stall = self.loader.loadModel("models/patch/cornfield") self.stall.reparentTo(self.render) self.stall.setScale(0.5) self.stall.setPos(40,0,1) self.stall.setHpr(0,0,0) self.tex1=self.loader.loadTexture("models/water.png") self.stall.setTexture(self.tex1,1) self.flock = Actor("models/goose/goosemodelonly", {"gfly":"models/goose/gooseanimationonly" }) self.flock.setScale(0.05, 0.05, 0.05) self.flock.setPos(0,-30,13) self.flock.reparentTo(self.render) self.flock.loop("gfly") self.tex2=self.loader.loadTexture("models/orange.jpg") self.flock.setTexture(self.tex2,1) self.camera.setPos(0,0,0) self.camera.setHpr(90,0,0) # Create the four lerp intervals needed for the panda to # walk back and forth. pandaPosInterval1 = self.flock.posInterval(13, Point3(-5, -30, 13), startPos=Point3(5, -30, 13)) pandaPosInterval2 = self.flock.posInterval(13, Point3(5, -30, 13), startPos=Point3(-5, -30, 13)) pandaHprInterval1 = self.flock.hprInterval(3, Point3(0, 0, 0), startHpr=Point3(180, 0, 0)) pandaHprInterval2 = self.flock.hprInterval(3, Point3(180, 0, 0), startHpr=Point3(0, 0, 0)) # Create and play the sequence that coordinates the intervals. self.pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1, pandaPosInterval2, pandaHprInterval2, name="pandaPace") self.pandaPace.loop() # Disable the camera trackball controls. #self.disableMouse() # Load the environment model. self.environ = self.loader.loadModel("models/environment1") # Reparent the model to render. self.environ.reparentTo(self.render) # Apply scale and position transforms on the model. self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0) self.boy = Actor("models/trex/trex", {"run":"models/trex/trex-run", "eat":"models/trex/trex-eat"}) self.boy.reparentTo(self.render) self.boy.setPos(0,0,0) self.boy.setScale(0.5) self.isMoving = False self.myAnimControl = self.boy.getAnimControl('run') base.camera.setPos(self.boy.getX(),self.boy.getY()+10,20) self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) self.cBoy = self.boy.attachNewNode(CollisionNode('cBoyNode')) self.cBoy.node().addSolid(CollisionSphere(0, 0, 3, 8.5)) #self.cBoy.show() #self.cPond = self.stall.attachNewNode(CollisionNode('cPond')) #self.cPond.node().addSolid(CollisionSphere(40, 0, 1, 70)) #self.cPond.show() # Add the spinCameraTask procedure to the task manager. #self.taskMgr.add(self.spinCameraTask,"asdsad") self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0} cs1 = CollisionSphere(0, 0, 0, 2) self.cnodePath1 = render.attachNewNode(CollisionNode('cnode1')) self.cnodePath1.node().addSolid(cs1) #self.cnodePath1.setCollideMask(BitMask32(0x10)) #self.cnodePath1.show() self.taskMgr.add(self.moveSphere1, "sfasdasf") cs2 = CollisionSphere(0, 0, 0, 1) self.cnodePath2 = render.attachNewNode(CollisionNode('cnode2')) self.cnodePath2.node().addSolid(cs2) #self.cnodePath2.reparentTo(self.render) #self.cnodePath2.node().setFromCollideMask(BitMask32.bit(0)) #self.cnodePath2.node().setIntoCollideMask(BitMask32.allOff()) #self.cnodePath2.show() self.taskMgr.add(self.moveSphere2, "sfasd") handler = CollisionHandlerEvent() handler.addInPattern('cnode1-into-cnode2') handler.addAgainPattern('cnode1-again-cnode2') handler.addOutPattern('cs1-out-cs2') self.accept('cnode1-into-cnode2', self.collide) #self.accept('cs1-out-cs2', self.collide) #self.accept('cnode1-again-cnode2', self.collide) self.traverser.addCollider(self.cnodePath1, handler) # Load and transform the panda actor. self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.pandaActor.setScale(0.005, 0.005, 0.005) self.pandaActor.reparentTo(self.render) # Loop its animation. self.pandaActor.loop("walk") self.taskMgr.add(self.movePanda, "Sasdas") self.pandaActor2 = Actor("models/panda-model",{"walk": "models/panda-walk4"}) self.pandaActor2.setScale(0.003, 0.003, 0.003) self.pandaActor2.reparentTo(self.render) # Loop its animation. self.pandaActor2.loop("walk") self.taskMgr.add(self.movePanda2, "Sak") self.camera.setPos(0,0,0) self.camera.setHpr(90,0,0) self.cTrav1=CollisionTraverser() self.collisionHandler1 = CollisionHandlerQueue() self.cTrav1.addCollider(self.cBoy, self.collisionHandler1) self.taskMgr.add(self.boyMoveTask, "BoyMoveTask") #self.accept("v",self.switchView) self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left",1]) self.accept("arrow_right", self.setKey, ["right",1]) self.accept("arrow_up", self.setKey, ["forward",1]) #self.accept("a", self.setKey, ["cam-left",1]) #self.accept("s", self.setKey, ["cam-right",1]) self.accept("arrow_left-up", self.setKey, ["left",0]) self.accept("arrow_right-up", self.setKey, ["right",0]) self.accept("arrow_up-up", self.setKey, ["forward",0]) #self.accept("a-up", self.setKey, ["cam-left",0]) #self.accept("s-up", self.setKey, ["cam-right",0]) self.cTrav2=CollisionTraverser() self.collisionHandler2 = CollisionHandlerQueue()
class DKGame(ShowBase): def __init__(self): super().__init__(self) self.loadScenery() self.mario = None #base.messenger.toggleVerbose() self.taskMgr.add(self.setup, "setup") self.taskMgr.add(self.update, "update") self.accept("raw-arrow_right", self.pressRight) self.accept("raw-arrow_right-up", self.stopRight) self.accept("raw-arrow_left", self.pressLeft) self.accept("raw-arrow_left-up", self.stopLeft) self.accept("raw-arrow_up", self.pressUp) self.accept("raw-arrow_up-up", self.stopUp) self.accept("raw-space", self.pressSpace) self.accept("raw-space-up", self.stopSpace) self.canClimb = False self.isClimbing = False #NUEVA! self.isGrounded = True self.canJump = True self.jumpTime = 0 self.vyi = 0 self.floorValidPosition = 0 self.barrelTimer = 0 self.lifes = 3 self.marioInitialPos = None self.posNotInitialized = True self.hammer = False self.input = { "left": False, "right": False, "space": False, "up": False } def loadScenery(self): self.scene = self.loader.loadModel( "models/DKSet1") # only for non animated objects self.scene.reparentTo(self.render) def setup(self, task): lens = OrthographicLens() lens.setFilmSize(25, 20) # Or whatever is appropriate for your scene base.camNode.setLens(lens) node = self.scene.find("root/camera1") node.removeNode() self.camera.setPos(0, 30, 0) self.camera.lookAt(self.scene) self.mario = self.scene.find("root/mario") self.mario.reparentTo(self.scene) self.scene.find("root/bottomstair").reparentTo(self.scene) self.scene.find("root/floor0").reparentTo(self.scene) self.scene.find("root/floor1").reparentTo(self.scene) self.scene.find("root/middlestair").reparentTo(self.scene) self.scene.find("root/topstair").reparentTo(self.scene) self.scene.find("root/floor2").reparentTo(self.scene) self.scene.find("root/pCube4").reparentTo(self.scene) self.scene.find("root/floors").reparentTo(self.scene) self.scene.find("root/barrel").reparentTo(self.scene) self.scene.find("root/walls").reparentTo(self.scene) self.scene.find("root/rightWall").reparentTo(self.scene) self.scene.find("root/MainGroup").reparentTo(self.scene) self.scene.find("root/hammer1").reparentTo(self.scene) self.barrel = self.scene.find("barrel") self.barrel.setPos(self.scene, 0, 0, 0) self.setupCollision() base.enableParticles() gravityFN = ForceNode('world-forces') gravityFNP = render.attachNewNode(gravityFN) gravityForce = LinearVectorForce(0, 0, -9.81) #gravity acceleration gravityFN.addForce(gravityForce) base.physicsMgr.addLinearForce(gravityForce) return Task.done def createBarrel(self): barrelNode = NodePath("PhysicalBarrel") barrelNode.reparentTo(self.scene) physicsBarrel = ActorNode("physics_barrel") physicsBarrel.getPhysicsObject().setMass( 0.01) #in what units? (69 kindda 3 lbs) barrel = barrelNode.attachNewNode(physicsBarrel) base.physicsMgr.attachPhysicalNode(physicsBarrel) barrel.setPos(0, 0, 2) visual_barrel = self.scene.attachNewNode("BarrelCopy") originalBarrel = self.scene.find("barrel") originalBarrel.instanceTo(visual_barrel) visual_barrel.reparentTo(barrel) sphere = CollisionSphere(6.6, 0, 4.78, 0.5) cnodePath = visual_barrel.attachNewNode( CollisionNode('barrelCollider')) cnodePath.node().addSolid(sphere) cnodePath.node().setFromCollideMask( 0xD) # crash with default and mario body and walls cnodePath.node().setIntoCollideMask( 0xD) # crash with default and mario body and walls cnodePath.show() self.physicsCollisionPusher.addCollider(cnodePath, barrel) base.cTrav.addCollider(cnodePath, self.physicsCollisionPusher) barrelForceNode = ForceNode('barrelForce') barrel.attachNewNode(barrelForceNode) barrelForce = LinearVectorForce(-7, 0, 0, 1, False) # barrelForce.setMassDependent(0) barrelForceNode.addForce(barrelForce) physicsBarrel.getPhysical(0).addLinearForce(barrelForce) def setupBoxCollider(self, node, px, py, pz, w, d, h, nm, colliderEventHandler, fromCollisionMask=0, intoCollisionMask=0): hitBox = CollisionBox(Point3(px, py, pz), w, d, h) cnodePath = node.attachNewNode(CollisionNode(nm)) cnodePath.node().addSolid(hitBox) cnodePath.node().setIntoCollideMask(intoCollisionMask) cnodePath.node().setFromCollideMask(fromCollisionMask) cnodePath.show() base.cTrav.addCollider(cnodePath, colliderEventHandler) def setupCollision(self): base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() self.physicsCollisionPusher = PhysicsCollisionHandler() self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') # create masks defaultCollisionMask = BitMask32(0b0001) #0x1 segmentCollisionMask = BitMask32(0b1000) #0x8 stairsCollisionMask = BitMask32(0b0010) #0x2 marioBodyCollisionMask = BitMask32(0b0011) #0x3 collisionWallsForBarrels = BitMask32(0b0100) #0x4 # mario segment collider ray = CollisionSegment(7, 0, -4.5, 7, 0, -5.1) cnodePath = self.mario.attachNewNode(CollisionNode('marioRay')) cnodePath.node().addSolid(ray) cnodePath.node().setFromCollideMask(segmentCollisionMask) cnodePath.node().setIntoCollideMask(0) cnodePath.show() base.cTrav.addCollider(cnodePath, self.collisionHandlerEvent) self.setupBoxCollider(self.mario, 7, 0, -4.5, 0.5, 5, 0.5, 'marioHitBox', self.collisionHandlerEvent, marioBodyCollisionMask, marioBodyCollisionMask) stairs1 = self.scene.find("bottomstair") self.setupBoxCollider(stairs1, -6.8, 0, -3.0, 0.5, 5, 2.5, 'stairs1HitBox', self.collisionHandlerEvent, stairsCollisionMask, stairsCollisionMask) stairs2 = self.scene.find("middlestair") self.setupBoxCollider(stairs2, -0.86, 0, .1, 0.5, 5, 2.1, 'stairs2HitBox', self.collisionHandlerEvent, stairsCollisionMask, stairsCollisionMask) stairs3 = self.scene.find("topstair") self.setupBoxCollider(stairs3, -6.8, 0, 3.1, 0.5, 5, 2.2, 'stairs3HitBox', self.collisionHandlerEvent, stairsCollisionMask, stairsCollisionMask) hammer = self.scene.find("MainGroup") # hammer self.setupBoxCollider(hammer, 5.5, 0, -1.5, 0.5, 5, 0.5, 'hammer1HitBox', self.collisionHandlerEvent, stairsCollisionMask, stairsCollisionMask) dk = self.scene.find("hammer1") self.setupBoxCollider(dk, 8.7, 0, 5, 1, 5, 1, 'dkHitBox', self.collisionHandlerEvent, stairsCollisionMask, stairsCollisionMask) floor0 = self.scene.find("floor0") self.setupBoxCollider(floor0, -2.5, 0, -5.5, 10, 5, 0.5, 'floor0HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask) floor1 = self.scene.find("floor1") self.setupBoxCollider(floor1, 2, 0, -2.5, 8.4, 5, 0.5, 'floor1HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask) floor2_1 = self.scene.find("floor2") self.setupBoxCollider(floor2_1, 3.6, 0, 0.5, 3.8, 5, 0.5, 'floor21HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask) floor2_2 = self.scene.find("pCube4") self.setupBoxCollider(floor2_2, -6.3, 0, 0.5, 5.0, 5, 0.5, 'floor22HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask) floor3 = self.scene.find("floors") self.setupBoxCollider(floor3, 1.8, 0, 3.5, 8, 5, 0.5, 'floor3HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask) rightWall = self.scene.find("rightWall") self.setupBoxCollider(rightWall, -12, 0, 0, 1, 5, 10, 'rightWallHitBox', self.collisionHandlerEvent, fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels) leftWall = self.scene.find("walls") self.setupBoxCollider(leftWall, 11.5, 0, 0, 1, 5, 10, 'leftWallHitBox', self.collisionHandlerEvent, fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels) barrelFixer = self.scene.attachNewNode("barrelFixer") self.setupBoxCollider(barrelFixer, -3, 0, 0.505, 10, 5, 0.5, 'barrelFixerHitBox', self.collisionHandlerEvent, fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels) barrelDestroyer = self.scene.attachNewNode("barrelDestroyer") self.setupBoxCollider(barrelDestroyer, 0, 0, -8, 15, 5, 0.5, 'barrelDestroyerHitBox', self.collisionHandlerEvent, fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels) self.accept('into-stairs1HitBox', self.enableStair) self.accept('outof-stairs1HitBox', self.disableStair) self.accept('into-stairs2HitBox', self.enableStair) self.accept('outof-stairs2HitBox', self.disableStair) self.accept('into-stairs3HitBox', self.enableStair) self.accept('outof-stairs3HitBox', self.disableStair) self.accept('into-hammer1HitBox', self.enableHammer) self.accept('into-dkHitBox', self.dkArrived) self.accept('into-floor0HitBox', self.enableJump) self.accept('outof-floor0HitBox', self.disableJump) self.accept('into-floor1HitBox', self.enableJump) self.accept('outof-floor1HitBox', self.disableJump) self.accept('into-floor21HitBox', self.enableJump) self.accept('outof-floor21HitBox', self.disableJump) self.accept('into-floor22HitBox', self.enableJump) self.accept('outof-floor22HitBox', self.disableJump) self.accept('into-floor3HitBox', self.enableJump) self.accept('outof-floor3HitBox', self.disableJump) self.accept("into-barrelCollider", self.barrelCrash) base.cTrav.showCollisions(self.render) def dkArrived(self, evt): if (self.hammer): self.scene.node().removeChild( evt.getIntoNodePath().node().getParent(0)) else: self.floorValidPosition = 0 self.mario.setPos(self.scene, self.marioInitialPos) text = DirectLabel(text="Game Over", text_scale=(0.5, 0.5)) def enableHammer(self, evt): print(f"{evt.getIntoNodePath()}{evt.getFromNodePath()}") self.scene.node().removeChild( evt.getIntoNodePath().node().getParent(0)) self.hammer = True def changeBarrelDirection(self, evt): print(f"Changing barrel direction {evt}") def barrelCrash(self, evt): barrel = evt.getIntoNodePath().node().getParent(0).getParent(0) other = evt.getFromNodePath().node().getParent(0) parents = barrel.parents print(f"{other}") if other.name == "barrelDestroyer": p = parents[0] self.scene.node().removeChild(p) return if not (other == self.mario.node() or other.name == "barrelFixer"): forceNode = barrel.getChildren()[1] actualForce = forceNode.getForce(0) actualForce.setVector(actualForce.getLocalVector().x * -1, 0, 0) forceNode.clear() forceNode.addForce(actualForce) if (other == self.mario.node()): if not self.hammer: self.lifes = self.lifes - 1 self.floorValidPosition = 0 self.mario.setPos(self.scene, self.marioInitialPos) p = parents[0] self.scene.node().removeChild(p) if (self.lifes < 0): print("game over dude!!") text = DirectLabel(text="Game Over", text_scale=(0.5, 0.5)) def enableStair(self, evt): print("crashed mario and stair") self.canClimb = True def disableStair(self, evt): print("exit mario and stair") self.canClimb = False def enableJump(self, evt): self.isGrounded = True print("enable jump") # fromCollider = evt.getFrom().getCenter().z - evt.getFrom().getDimensions().z/2 self.floorValidPosition = evt.getInto().getCenter().z + 5.5 #print(f"{ evt.getInto().getCenter().z } {self.floorValidPosition} ") def disableJump(self, evt): print("disable jump") self.isGrounded = False def pressUp(self): print("up enabled") self.input["up"] = True def stopUp(self): print("up disabled") self.input["up"] = False def pressRight(self): self.input["right"] = True def stopRight(self): self.input["right"] = False def pressLeft(self): self.input["left"] = True def stopLeft(self): self.input["left"] = False def pressSpace(self): self.input["space"] = True self.camera.setPos(0, 30, 0) self.camera.lookAt(self.scene) def stopSpace(self): self.input["space"] = False def getAdvance(self): if self.input["left"] and self.input["right"]: return 0 if self.input["left"]: return -1 if self.input["right"]: return 1 return 0 def applyJump(self): jz = 0 # jump Y/Z vi = 4 # initial velocity g = -6 # gravity if (self.isGrounded): if (self.canJump): if (self.input["space"]): self.jumpTime = 0.1 self.canJump = False self.vyi = vi jz = self.vyi * self.jumpTime + 0.5 * g * self.jumpTime * self.jumpTime vz = self.vyi + g * self.jumpTime else: return 0 else: self.jumpTime = self.jumpTime + globalClock.getDt() jz = self.vyi * self.jumpTime + 0.5 * g * self.jumpTime * self.jumpTime vz = self.vyi + g * self.jumpTime if vz < 0: #finished self.jumpTime = 0 self.canJump = True self.vyi = 0 jz = 0 else: if (not self.isClimbing): self.canJump = False self.jumpTime = self.jumpTime + globalClock.getDt() jz = self.vyi * self.jumpTime + 0.5 * g * self.jumpTime * self.jumpTime vz = self.vyi + g * self.jumpTime return jz def applyStairs(self, pz): if (self.canClimb): if (self.input["up"]): self.isClimbing = True if (self.isClimbing): if (self.input["up"]): return pz + 0.1 if (not self.canClimb): self.isClimbing = False return pz def update(self, task): self.camera.setPos(0, 30, 0) self.camera.lookAt(self.scene) pz = self.applyJump() if (self.posNotInitialized): self.marioInitialPos = self.mario.getPos() self.posNotInitialized = False self.barrelTimer = self.barrelTimer + globalClock.getDt() if self.barrelTimer > (3 + random() * 2): self.createBarrel() self.barrelTimer = 0 # self.mario.getPos(self.render).z advZ = self.applyStairs(self.floorValidPosition) self.floorValidPosition = advZ #print(f' {self.mario.getPos(self.render).z} {self.floorValidPosition} ') self.mario.setPos(self.render, self.mario.getPos().x + -self.getAdvance() * .1, 0, advZ + pz) return Task.cont
class TunnelPinchTask(ShowBase, GripStateMachine): DATA_DIR = 'data' def __init__(self, id, session, hand, block, mode, wrist): ShowBase.__init__(self) GripStateMachine.__init__(self) base.disableMouse() wp = WindowProperties() wp.setSize(1920,1080) wp.setFullscreen(True) wp.setUndecorated(True) base.win.requestProperties(wp) self.sub_id = str(id) self.sess_id = str(session) self.hand = str(hand) self.block = str(block) self.mode = str(mode) self.wrist = str(wrist) self.prev_blk = os.path.join(self.DATA_DIR,'exp_2',self.sub_id,self.sess_id,self.wrist,self.hand,"B0") self.exp_blk0 = os.path.join(self.DATA_DIR,'exp_1',self.sub_id,self.sess_id,self.wrist,self.hand,"B0") self.table = np.loadtxt('src/tunnel_pinch_task/trialtable_flex.csv',dtype='str',delimiter=',',skiprows=1) indices = {} try: self.prev_table = np.loadtxt(os.path.join(self.prev_blk, 'final_targets.csv'),dtype='str',delimiter=',',skiprows=1) except: try: self.prev_table = np.loadtxt(os.path.join(self.exp_blk0, 'final_targets.csv'),dtype='str',delimiter=',',skiprows=1) except: print('Previous target file not found, results may be suboptimal') try: for i in range(self.prev_table.shape[0]): indices[self.prev_table[i,1]] = int(self.prev_table[i,0])-1 for i in range(self.table.shape[0]): self.table[i,11] = self.prev_table[indices[self.table[i,1].strip()],11] self.table[i,12] = self.prev_table[indices[self.table[i,1].strip()],12] self.table[i,13] = self.prev_table[indices[self.table[i,1].strip()],13] except: print('Invalid target file') self.table = np.array([[item.strip() for item in s] for s in self.table]) ################################################### #only use rows relevant to this block #HARDCODED! NOTE IN LOG SHEET spec_table = [] for i in range(self.table.shape[0]): if int(self.block)%5 == 0: #block 0 to adjust positions if "(p)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 1: if "(L)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 2: if "(L+t)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 3: if "(S)" in self.table[i,2]: spec_table.append(self.table[i]) elif int(self.block)%5 == 4: if "(S+t)" in self.table[i,2]: spec_table.append(self.table[i]) ################################################### self.table = np.array(spec_table) self.session_dir = os.path.join(self.DATA_DIR,'exp_2',self.sub_id,self.sess_id,self.wrist,self.hand) self.subjinfo = self.sub_id + '_' + self.sess_id + '_' + self.hand + '_log.yml' self.p_x,self.p_y,self.p_a = GET_POS(self.session_dir,self.subjinfo,self.hand,self.wrist) self.rotmat = ROT_MAT(self.p_a,self.hand) self.setup_text() self.setup_lights() self.setup_camera() self.trial_counter = 0 self.load_models() self.load_audio() self.update_trial_command() self.countdown_timer = CountdownTimer() self.hold_timer = CountdownTimer() self.cTrav = CollisionTraverser() self.chandler = CollisionHandlerEvent() self.chandler.addInPattern('%fn-into-%in') self.chandler.addOutPattern('%fn-outof-%in') self.chandler.addAgainPattern('%fn-again-%in') self.attachcollnodes() taskMgr.add(self.read_data, 'read') for i in range(5): taskMgr.add(self.move_player, 'move%d' % i, extraArgs = [i], appendTask=True) taskMgr.add(self.log_data, 'log_data') taskMgr.add(self.update_state, 'update_state', sort=1) self.accept('space', self.space_on) self.accept('escape', self.clean_up) self.space = False self.statenum = list() self.max_time = 20 self.med_data = None self.grip_dir = os.path.join(self.DATA_DIR,'exp_2',self.sub_id,self.sess_id,self.wrist,self.hand,"B"+self.block) if not os.path.exists(self.grip_dir): print('Making new folders: ' + self.grip_dir) os.makedirs(self.grip_dir) self.dev = MpDevice(RightHand(calibration_files=['calibs/cal_mat_70_v2.mat', 'calibs/cal_mat_73_v2.mat', 'calibs/cal_mat_56.mat', 'calibs/cal_mat_58_v2.mat', 'calibs/cal_mat_50.mat'], clock=mono_clock.get_time)) ############ #SET UP HUD# ############ def setup_text(self): self.bgtext = OnscreenText(text='Not recording.', pos=(-0.8, 0.8), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.bgtext.reparentTo(self.aspect2d) self.dirtext = OnscreenText( pos=(-0.6, 0.65), scale=0.08, fg=(0, 0, 0, 1), bg=(1, 1, 1, 1), frame=(0.2, 0.2, 0.8, 1), align=TextNode.ACenter) self.dirtext.reparentTo(self.aspect2d) ########################## #SET UP SCENE AND PLAYERS# ########################## def setup_lights(self): pl = PointLight('pl') pl.setColor((1, 1, 1, 1)) plNP = self.render.attachNewNode(pl) plNP.setPos(-10, -10, 10) self.render.setLight(plNP) pos = [[[0, 0, 50], [0, 0, -10]], [[0, -50, 0], [0, 10, 0]], [[-50, 0, 0], [10, 0, 0]]] for i in pos: dl = Spotlight('dl') dl.setColor((1, 1, 1, 1)) dlNP = self.render.attachNewNode(dl) dlNP.setPos(*i[0]) dlNP.lookAt(*i[1]) dlNP.node().setShadowCaster(False) self.render.setLight(dlNP) def setup_camera(self): self.cam.setPos(0, 0, 12) self.cam.lookAt(0, 2, 0) self.camLens.setFov(90) def load_models(self): self.back_model = self.loader.loadModel('models/back') self.back_model.setScale(10, 10, 10) if self.hand == "Left": self.back_model.setH(90) self.back_model.reparentTo(self.render) self.player_offsets = [[self.p_x[0]-5, self.p_y[0]+3, 0], [self.p_x[1]-2.5, self.p_y[1]+4.5, 0], [self.p_x[2], self.p_y[2]+5, 0], [self.p_x[3]+2.5, self.p_y[3]+4.5, 0], [self.p_x[4]+5, self.p_y[4]+3, 0]] self.p_col =[[0,0,250],[50,0,200],[125,0,125],[200,0,50],[250,0,0]] if self.hand == 'Left': self.p_col = self.p_col[::-1] self.players = list() self.contacts = list() for counter, value in enumerate(self.player_offsets): self.players.append(self.loader.loadModel('models/target')) self.contacts.append(False) self.players[counter].setPos(*value) self.players[counter].setScale(0.2, 0.2, 0.2) self.players[counter].setColorScale( self.p_col[counter][0]/255, self.p_col[counter][1]/255, self.p_col[counter][2]/255, 1) self.players[counter].reparentTo(self.render) self.players[counter].show() self.target_select() def load_audio(self): self.pop = self.loader.loadSfx('audio/Blop.wav') self.buzz = self.loader.loadSfx('audio/Buzzer.wav') ############################ #SET UP COLLISION MECHANICS# ############################ def attachcollnodes(self): self.inside = [False]*5 for i in range(5): self.fromObject = self.players[i].attachNewNode(CollisionNode('colfromNode'+str(i))) self.fromObject.node().addSolid(CollisionSphere(0,0,0,1)) self.cTrav.addCollider(self.fromObject, self.chandler) for i in range(5): self.accept('colfromNode%d-into-colintoNode' % i, self.collide1,[i]) self.accept('colfromNode%d-again-colintoNode' % i, self.collide2,[i]) self.accept('colfromNode%d-outof-colintoNode' % i, self.collide3,[i]) def collide1(self,f,collEntry): if f in self.highlighted_indices: self.players[f].setColorScale(0,1,0,1) self.tar.setColorScale(0.2,0.2,0.2,1) self.tar.setAlphaScale(0.7) self.contacts[f] = True taskMgr.doMethodLater(self.delay,self.too_long,'too_long%d' % f,extraArgs = [f]) def collide2(self,f,collEntry): for i in self.highlighted_indices: if self.contacts[i] == False: return taskMgr.remove('too_long%d' % f) def collide3(self,f,collEntry): taskMgr.remove('too_long%d' % f) self.reset_fing(f) self.tar.setColorScale(0.1,0.1,0.1,1) self.tar.setAlphaScale(0.7) def too_long(self,f): self.reset_fing(f) self.tar.setColorScale(0.5,0.2,0.2,1) self.tar.setAlphaScale(0.7) def reset_fing(self,f): self.players[f].setColorScale( self.p_col[f][0]/255, self.p_col[f][1]/255, self.p_col[f][2]/255, 1) self.contacts[f] = False ############### #TARGET THINGS# ############### def show_target(self): self.target_select() self.intoObject = self.tar.attachNewNode(CollisionNode('colintoNode')) if self.table[self.trial_counter,7] == "sphere": self.intoObject.node().addSolid(CollisionSphere(0,0,0,1)) elif self.table[self.trial_counter,7] == "cylinder": self.intoObject.node().addSolid(CollisionTube(0,0,-2,0,0,2,1)) else: raise NameError("No such collision type") self.tar.show() self.occSolid.show() self.occLines.show() for i in range(5): if i not in self.highlighted_indices: self.players[i].hide() def target_select(self): self.tgtscx=float(self.table[self.trial_counter,14]) self.tgtscy=float(self.table[self.trial_counter,15]) self.tgtscz=float(self.table[self.trial_counter,16]) tgttsx=float(self.table[self.trial_counter,11]) tgttsy=float(self.table[self.trial_counter,12]) tgttsz=float(self.table[self.trial_counter,13]) tgtrx=float(self.table[self.trial_counter,17]) tgtry=float(self.table[self.trial_counter,18]) tgtrz=float(self.table[self.trial_counter,19]) if self.hand == 'Left': tgttsx *= -1 tgtrx *= -1 self.static_task = (str(self.table[self.trial_counter,5]) == "True") self.target_model = str(self.table[self.trial_counter,6]) self.highlighted_indices=[int(s)-1 for s in self.table[self.trial_counter,4].split(' ')] if self.hand == 'Left': self.highlighted_indices=[4-i for i in self.highlighted_indices] self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[-2,-1],0]) + tgttsx self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[0,1],1]) + tgttsy if self.hand == 'Left': self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[0,1],0]) + tgttsx self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][[-2,-1],1]) + tgttsy #self.tgtposx = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,0]) #self.tgtposy = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,1]) self.tgtposz = np.mean(np.asarray(self.player_offsets)[self.highlighted_indices][:,2]) + tgttsz self.tar = self.loader.loadModel(self.target_model) self.tar.setScale(self.tgtscx,self.tgtscy,self.tgtscz) self.tar.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.tar.setHpr(tgtrx,tgtry,tgtrz) self.tar.setColorScale(0.1, 0.1, 0.1, 1) self.tar.setAlphaScale(0.7) self.tar.setTransparency(TransparencyAttrib.MAlpha) self.tar.reparentTo(self.render) self.tar.hide() if len(self.highlighted_indices) == 2: dx = self.players[self.highlighted_indices[0]].getX() - self.players[self.highlighted_indices[1]].getX() dy = self.players[self.highlighted_indices[0]].getY() - self.players[self.highlighted_indices[1]].getY() angle = math.degrees(math.atan(dy/dx)) self.table[self.trial_counter,9] = str(angle) + ' ' + str(angle-180) self.angs=self.table[self.trial_counter,9].split(' ') self.angs = [float(a) for a in self.angs] self.tunn_width=float(self.table[self.trial_counter,10]) self.r = 1.5 if int(self.block) == 0: self.r = 0 self.x = [self.r*math.cos(math.radians(a)) for a in self.angs] self.y = [self.r*math.sin(math.radians(a)) for a in self.angs] self.occ = draw_shape(self.angs,self.tunn_width,self.r) self.occSolid = render.attachNewNode(self.occ[0]) self.occSolid.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.occSolid.setColorScale(0,1,1,0) self.occSolid.setTransparency(TransparencyAttrib.MAlpha) self.occSolid.setAlphaScale(0.6) self.occLines = render.attachNewNode(self.occ[1]) self.occLines.setPos(self.tgtposx,self.tgtposy,self.tgtposz) self.occSolid.hide() self.occLines.hide() self.delay=float(self.table[self.trial_counter,8]) self.distances = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]] #change camera to be on top of target self.cam.setPos(self.tgtposx, self.tgtposy - 2, 12) self.back_model.setPos(self.tgtposx,self.tgtposy - 2,0) self.cam.lookAt(self.tgtposx, self.tgtposy, 0) ############## #MOVE FINGERS# ############## def read_data(self,task): error, data = self.dev.read() if data is not None: data *= 0.001 self.ts = data.time data = np.dot(data,self.rotmat) self.data = data if self.med_data is None: self.med_data = np.median(data, axis=0) if self.space: self.statenum.extend(([self.checkstate()])*len(data.time)) return task.cont def move_player(self,p,task): if self.data is not None : k = p*3 new_x = 10*np.mean(self.data[-1,k]) + self.player_offsets[p][0] - 10*self.med_data[k] new_y = 10*np.mean(self.data[-1,k + 1]) + self.player_offsets[p][1] - 10*self.med_data[k + 1] new_z = 10*np.mean(self.data[-1,k + 2]) + self.player_offsets[p][2] - 10*self.med_data[k + 2] #make sure digits do not cross each other if ((p in range(1,3) and p+1 in self.highlighted_indices and new_x > self.players[p+1].getX()) or (p in range(2,4) and p-1 in self.highlighted_indices and new_x < self.players[p-1].getX())): new_x = self.players[p].getX() #make sure digits do not cross into target if self.space == True and p in self.highlighted_indices: self.distances[p][0] = new_x - self.tar.getX() self.distances[p][1] = new_y - self.tar.getY() self.distances[p][2] = new_z - self.tar.getZ() self.check_pos(p) self.players[p].setPos(new_x, new_y, new_z) return task.cont def check_pos(self, p): x = self.distances[p][0] y = self.distances[p][1] z = self.distances[p][2] hit = True for i in range(len(self.angs)): p_ang = math.acos((x*self.x[i]+y*self.y[i])/(self.r*(x**2+y**2)**0.5)) if math.sin(p_ang)*(x**2+y**2)**0.5 < self.tunn_width and p_ang < math.pi/2: hit = False break if (abs(z) <= 1.2 #check z location and x**2 + y**2 <= self.r**2 #within radius of circle and hit == True): if self.inside[p] is False: self.ignore('colfromNode%d-into-colintoNode' % p) self.ignore('colfromNode%d-again-colintoNode' % p) self.players[p].setColorScale(1,1,0,1) self.inside[p] = True else: if self.inside[p] is True and x**2 + y**2 > self.r**2: self.accept('colfromNode%d-into-colintoNode' % p, self.collide1,[p]) self.accept('colfromNode%d-again-colintoNode' % p, self.collide2,[p]) self.players[p].setColorScale( self.p_col[p][0]/255, self.p_col[p][1]/255, self.p_col[p][2]/255, 1) self.inside[p] = False ################## #CHECK COMPLETION# ################## def close_to_target(self): for i in self.highlighted_indices: if self.contacts[i] == False: return False self.tar.setColorScale(0,1,1,1) return True def check_hold(self): if not self.close_to_target(): self.hold_timer.reset(0.5) return False return self.hold_timer.elapsed() < 0 def adjust_targets(self): #no adjustment if more than 2 fingers or position is prone if len(self.highlighted_indices) > 2 or self.wrist == 'pron': return xadj,yadj,zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices],0) #xadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][0]) #yadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][1]) #zadj = np.mean(np.asarray(self.distances)[self.highlighted_indices][2]) #do adjustment on all tasks with same name if self.hand == 'Left': xadj = -xadj for i in range(self.trial_counter+1,self.table.shape[0]): if self.table[i,1] == self.table[self.trial_counter,1]: self.table[i,11] = float(self.table[i,11]) + xadj self.table[i,12] = float(self.table[i,12]) + yadj self.table[i,13] = float(self.table[i,13]) + zadj ######### #LOGGING# ######### def play_success(self): if int(self.block) == 0: self.adjust_targets() self.pop.play() self.tar.hide() self.highlighted_indices = [0,1,2,3,4] def log_text(self): self.bgtext.setText('Now logging...') def log_data(self, task): if (self.trial_counter + 1) <= self.table.shape[0]: if self.space: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) self.movvars = np.column_stack((self.ts, self.statenum, self.data)) self.statenum = [] if self.mode=='task': with open(self.log_file_name, 'ab') as f: np.savetxt(f, self.movvars, fmt='%10.5f', delimiter=',') return task.cont else: pass def stoplog_text(self): self.dirtext.clearText() self.bgtext.setText('Done logging!') for i in range(5): self.players[i].show() ####### #RESET# ####### def delete_file(self): if (self.trial_counter + 1) <= self.table.shape[0]: self.log_file_name = os.path.join(self.grip_dir, self.sub_id+"_"+self.sess_id+"_"+self.hand+"_"+ str(self.table[self.trial_counter,1])+"_"+str(self.table[self.trial_counter,0])+".csv" ) try: os.remove(self.log_file_name) except OSError: pass else: pass def reset_baseline(self): self.med_data = None def reset_keyboard_bool(self): self.space = False def hide_target(self): self.tar.hide() self.occSolid.hide() self.occLines.hide() self.intoObject.removeNode() self.imageObject.destroy() def update_trial_command(self): self.dirtext.setText(str(self.table[self.trial_counter,2])) if self.hand == 'Left': xfac = -0.25 else: xfac = 0.25 self.imageObject = OnscreenImage(image = str(self.table[self.trial_counter,3]),scale=(xfac,0.25,0.25),pos=(-0.8, 0, 0.3)) def increment_trial_counter(self): self.trial_counter += 1 self.update_trial_command() ######## #TIMERS# ######## def start_trial_countdown(self): self.countdown_timer.reset(self.max_time) def start_hold_countdown(self): self.hold_timer.reset(0.5) def start_post_countdown(self): self.countdown_timer.reset(2) def time_elapsed(self): return self.countdown_timer.elapsed() < 0 ######### #MACHINE# ######### def update_state(self, task): self.step() return task.cont def wait_for_space(self): return self.space def space_on(self): self.space = True ##### #END# ##### def trial_counter_exceeded(self): return (self.trial_counter+1) > self.table.shape[0]-1 def clean_up(self): #write last known positions to 'final_targets' file f = open('src/pinch_task/trialtable_flex.csv') header = f.readline().rstrip() np.savetxt(self.grip_dir + '/final_targets.csv',self.table,fmt='%s',header = header, delimiter=',') f.close() sys.exit()
class World(DirectObject): def __init__( self ): # Initialize the traverser. base.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.collHandEvent.addOutPattern('outof-%in') # Make a variable to store the unique collision string count. self.collCount = 0 # Load a model. Reparent it to the camera so we can move it. s = loader.loadModel('smiley') s.reparentTo(camera) s.setPos(0, 25, 0) # Setup a collision solid for this model. sColl = self.initCollisionSphere(s, True) # Add this object to the traverser. base.cTrav.addCollider(sColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + sColl[1], self.collide3) self.accept('outof-' + sColl[1], self.collide4) print(sColl[1]) # Load another model. t = loader.loadModel('smiley') t.reparentTo(render) t.setPos(5, 25, 0) # Setup a collision solid for this model. tColl = self.initCollisionSphere(t, True) # Add this object to the traverser. base.cTrav.addCollider(tColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + tColl[1], self.collide) self.accept('outof-' + tColl[1], self.collide2) print(tColl[1]) print("WERT") def collide(self, collEntry): print("WERT: object has collided into another object") Sequence(Func(collEntry.getFromNodePath().getParent().setColor, VBase4(1, 0, 0, 1)), Wait(0.2), Func(collEntry.getFromNodePath().getParent().setColor, VBase4(0, 1, 0, 1)), Wait(0.2), Func(collEntry.getFromNodePath().getParent().setColor, VBase4(1, 1, 1, 1))).start() def collide2(self, collEntry): print("WERT.: object is no longer colliding with another object") def collide3(self, collEntry): print("WERT2: object has collided into another object") def collide4(self, collEntry): print("WERT2: object is no longer colliding with another object") def initCollisionSphere(self, obj, show=False): # Get the size of the object for the collision sphere. bounds = obj.getChild(0).getBounds() center = bounds.getCenter() radius = bounds.getRadius() * 1.1 # Create a collision sphere and name it something understandable. collSphereStr = 'CollisionHull' + str(self.collCount) + "_" + obj.getName() self.collCount += 1 cNode = CollisionNode(collSphereStr) cNode.addSolid(CollisionSphere(center, radius)) cNodepath = obj.attachNewNode(cNode) if show: cNodepath.show() # Return a tuple with the collision node and its corrsponding string so # that the bitmask can be set. return (cNodepath, collSphereStr)
class Starfox(ShowBase): def __init__(self): super().__init__(self) self.scene = self.loader.loadModel("./models/world.egg") self.scene.reparentTo(self.render) base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() base.enableParticles() #base.messenger.toggleVerbose() #self.collisionHandlerEvent.addInPattern('from-%in') self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') self.player = self.scene.find("player") self.enemy = self.scene.find("enemy1") self.player.setPythonTag("ObjectController", Player(self.player, collisionMask=0x4)) self.building_enemy = self.scene.find("building_enemy") #self.player.setPos(self.scene, 0,0,5) self.camera.setPos(self.render, 0, -50, 100) self.taskMgr.add(self.update, "update") self.accept('into-collision_enemy', self.crash) self.accept('into-collision_player', self.crash) self.accept('into-collision_plane', self.crash) base.cTrav.addCollider(self.scene.find("player/collision**"), self.collisionHandlerEvent) base.cTrav.addCollider(self.scene.find("enemy1/collision**"), self.collisionHandlerEvent) base.cTrav.addCollider(self.scene.find("basePlane/collision**"), self.collisionHandlerEvent) #base.cTrav.showCollisions(self.render) InputManager.initWith(self, [ InputManager.arrowUp, InputManager.arrowDown, InputManager.arrowRight, InputManager.arrowLeft, InputManager.keyS, InputManager.keyA, InputManager.space, InputManager.keyX, InputManager.keyV ]) self.rails = self.scene.attachNewNode("rails") self.rails.setPos(self.scene, 0, 0, 0) self.rails_y = 0 self.player.reparentTo(self.rails) self.player.setPos(self.rails, 0, 20, 0) #self.createStaticEnemy(self.building_enemy , -100 ,500, 0 ) self.createStaticEnemy(self.building_enemy, 200, 850, 0) self.createStaticEnemy(self.building_enemy, -100, 1000, 0) self.createDynamicEnemy(self.enemy, -80, 500, 20, -200, 500, 20) def createDynamicEnemy(self, original, ox, oy, oz, tx=0, ty=0, tz=0): """ de = DynamicEnemy( Vec3(ox,oy,oz), self.scene, original, self.player, base.cTrav, self.collisionHandlerEvent, vel=5, distanceToAttack = 80 ) de.setTargetPos( Vec3(tx,ty,tz) ) """ de = DynamicEnemy(Vec3(ox, oy, oz), self.scene, original, self.player, base.cTrav, self.collisionHandlerEvent, type=ENEMY_TYPE.CHASER, vel=35, distanceToAttack=2000, collisionMask=0x3) def createStaticEnemy(self, original, x, y, z): be = original.copyTo(self.scene) be.setPos(self.scene, x, y, z) base.cTrav.addCollider(be.find("**collision**"), self.collisionHandlerEvent) be.find("**collision*").node().setIntoCollideMask(0x3) be.find("**collision*").node().setFromCollideMask(0x3) def crash(self, evt): #a = 2 objectInto = evt.getIntoNodePath().node().getParent(0).getPythonTag( "ObjectController") objectFrom = evt.getFromNodePath().node().getParent(0).getPythonTag( "ObjectController") if (objectInto != None): objectInto.crash(objectFrom) if (objectFrom != None): objectFrom.crash(objectInto) print(f"{objectInto} {objectFrom}") def update(self, task): extraX, extraZ = self.player.getPythonTag("ObjectController").update( self.rails, globalClock.getDt()) self.rails.setPos(self.scene, Path.getXOfY(self.rails_y), self.rails_y, 20) #self.camera.lookAt(self.player) self.camera.setHpr(Path.getHeading(self.rails_y), 0, 0) self.rails.setHpr(Path.getHeading(self.rails_y), 0, 0) self.camera.setPos(self.rails, extraX, -10, extraZ) self.rails_y = self.rails_y + 20 * globalClock.getDt() if self.player.getPythonTag("ObjectController").getShoot(): v = self.render.getRelativeVector(self.rails, Vec3(0, 1, 0)) b = Bullet(self.render, self.player.getPos(self.render), self.enemy, base.cTrav, self.collisionHandlerEvent, v, collisionMask=0x3) bullets = self.render.findAllMatches("bullet") for i in bullets: b = i.getPythonTag('ObjectController') b.update(globalClock.getDt()) enemies = self.scene.findAllMatches("dynamicEnemy") for i in enemies: e = i.getPythonTag('ObjectController') s = e.update(globalClock.getDt(), self.rails) if (s): dir = self.player.getPos(self.render) - i.getPos(self.render) dir.normalize() b = Bullet(self.render, i.getPos(self.render), self.enemy, base.cTrav, self.collisionHandlerEvent, dir, collisionMask=0xC) return Task.cont
class DonkeyKong(ShowBase): def __init__(self): super().__init__(self) self.playerLost = False self.playerWon = False self.scene = self.loader.loadModel('models/DKSet') self.scene.reparentTo(self.render) self.arcadeTexture = self.loader.loadTexture('models/dk-arcade.png') self.scene.setTexture(self.arcadeTexture) self.scene.setTransparency(1) self.blockTexture = self.loader.loadTexture('models/block.png') self.stairsTexture = self.loader.loadTexture('models/stairs.png') self.taskMgr.add(self.setup, "setup") self.taskMgr.add(self.update, "update") self.jumpAvailable = False self.baseTime = 0 self.v0 = 0 self.gravity = -.5 self.stairsAvailable = False self.lastPlayerValidZ = 0 self.hammerTime = False self.dkTimer = 5 self.lifeCounter = 3 def pressUp(self): print("up") self.input["up"] = not self.input["up"] def pressDown(self): print("down") self.input["down"] = not self.input["down"] def pressLeft(self): print("left") self.input["left"] = not self.input["left"] def pressRight(self): print("right") self.input["right"] = not self.input["right"] def pressSpace(self): print("space") self.input["space"] = not self.input["space"] def hammerFrame1(self): self.hammerDown.show() self.hammerUp.hide() def hammerFrame2(self): self.hammerDown.hide() self.hammerUp.show() def setup(self, task): lens = OrthographicLens() lens.setFilmSize(25, 20) base.camNode.setLens(lens) self.player = self.scene.attachNewNode("Player") self.scene.find("root/barrel").setPos(0, 100, 0) self.scene.find("root/walls").hide() self.scene.find("root/rightWall").hide() self.lifes = [ self.scene.attachNewNode("life1"), self.scene.attachNewNode("life2"), self.scene.attachNewNode("life3"), ] # init mario gfx stuff self.marioGfx = self.scene.find('root/mario') self.marioGfx.instanceTo(self.lifes[0]) self.marioGfx.instanceTo(self.lifes[1]) self.marioGfx.instanceTo(self.lifes[2]) self.lifes[0].setPos(-9, 0, 7.5) self.lifes[1].setPos(-10, 0, 7.5) self.lifes[2].setPos(-11, 0, 7.5) self.marioGfx.reparentTo(self.player) self.marioGfx.setTwoSided(True) self.hammerDown = self.scene.find('root/hammerdowm') self.hammerDown.reparentTo(self.marioGfx) self.hammerDown.setPos(1, 0, 0) self.hammerUp = self.scene.find('root/hammerup') self.hammerUp.reparentTo(self.marioGfx) self.hammerUp.setPos(0, 0, 1) self.hammerDown.hide() self.hammerUp.hide() frame1 = Func(self.hammerFrame1) frame2 = Func(self.hammerFrame2) delay = Wait(0.1) self.hammerSequence = Sequence(frame1, delay, frame2, delay) #sequence.loop() #sequence.start() #sequence.finish() #input setup self.accept("raw-arrow_up", self.pressUp) self.accept("raw-arrow_down", self.pressDown) self.accept("raw-arrow_left", self.pressLeft) self.accept("raw-arrow_right", self.pressRight) self.accept("raw-space", self.pressSpace) self.accept("raw-arrow_up-up", self.pressUp) self.accept("raw-arrow_down-up", self.pressDown) self.accept("raw-arrow_left-up", self.pressLeft) self.accept("raw-arrow_right-up", self.pressRight) self.accept("raw-space-up", self.pressSpace) self.input = { 'left': False, 'right': False, 'up': False, 'down': False, 'space': False } # collision handling base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') ray = CollisionSegment(0, 0, 0, 0, 0, -.6) cNodePath = self.player.attachNewNode(CollisionNode('marioRay')) cNodePath.node().addSolid(ray) cNodePath.node().setIntoCollideMask(0x3) cNodePath.node().setFromCollideMask(0x3) cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) self.donkeykonggfx = self.scene.find(f'root/donkeykong') self.donkeykong = self.createSquareCollider(8.7, 5, 1, 1, 'donkeykong', 'dkHitbox', 'DK', self.reachedDk, self.exitDk, self.arcadeTexture, 0x2) self.floor1 = self.createSquareCollider(-1.8, -5.5, 9.3, .5, 'floor0', 'floor1Hitbox', 'Floor1', self.enableJump, self.disableJump, self.blockTexture, 0x01) self.floor2 = self.createSquareCollider(2.08, -2.5, 8.0, .5, 'floor1', 'floor2Hitbox', 'Floor2', self.enableJump, self.disableJump, self.blockTexture, 0x01) self.floor3_1 = self.createSquareCollider(3.6, 0.5, 3.8, .5, 'floor2', 'floor3_1Hitbox', 'Floor3_1', self.enableJump, self.disableJump, self.blockTexture, 0x01) self.floor3_2 = self.createSquareCollider(-6.3, 0.5, 5, .5, 'pCube4', 'floor3_2Hitbox', 'Floor3_2', self.enableJump, self.disableJump, self.blockTexture, 0x01) self.floor4 = self.createSquareCollider(1.8, 3.5, 8, .5, 'floors', 'floor4Hitbox', 'Floor4', self.enableJump, self.disableJump, self.blockTexture, 0x01) self.hammer = self.createSquareCollider(6, 1.5, .5, .5, 'hammer', 'hammerHitbox', 'hammer', self.enableHammer, self.disableHammer, self.arcadeTexture, 0x02) self.topstair = self.createSquareCollider( -6.8, 3.5, 0.5, 2.5, 'topstair', 'topstairHitbox', 'TopStair', self.enableStairs, self.disableStairs, self.stairsTexture, 0x02) self.middlestair = self.createSquareCollider( -0.86, 0.1, 0.5, 2.5, 'middlestair', 'middlestairHitbox', 'MiddleStair', self.enableStairs, self.disableStairs, self.stairsTexture, 0x02) self.bottomstair = self.createSquareCollider( -6.8, -2.5, 0.5, 2.5, 'bottomstair', 'bottomstairHitbox', 'BottomStair', self.enableStairs, self.disableStairs, self.stairsTexture, 0x02) self.leftWall = self.invisibleSquareCollider(-12.5, 0, 1, 10, "leftWallHitbox", "leftWall", 0x1) self.rightWall = self.invisibleSquareCollider(11.3, 0, 1, 20, "rightWallHitbox", "rightWall", 0x1) self.barrelDestroyer = self.invisibleSquareCollider( -0.5, -10, 10.5, 1, "barrelDestroyHitBox", "barrelDestroyer", 0x1) self.barrelBridge = self.invisibleSquareCollider( -0.4, 0.5, 2, 0.5, "barrelBridgeHitBox", "barrelBridge", 0x4) base.enableParticles() self.physicsCollisionPusher = PhysicsCollisionHandler() gravity = ForceNode("world-forces") gravityP = render.attachNewNode(gravity) gravityForce = LinearVectorForce(0, 0, -9.81) gravity.addForce(gravityForce) base.physicsMgr.addLinearForce(gravityForce) self.accept("into-barrelCollider", self.barrelCrash) #self.accept("raw-a", self.throwBarrel) #base.cTrav.showCollisions(self.render) self.barrels_frames = [] self.barrels_frames.append(0) self.barrels_frames.append(0.410573 - 0.375774) self.barrels_frames.append(0.444913 - 0.375774) self.barrels_frames.append(0.479941 - 0.375774) self.createDKSequence() self.player.setPos(3, 0, -3) return Task.done def changeDkFrame(self, dk, new_u, new_v): dk.setTexOffset(TextureStage.getDefault(), new_u, new_v) def createDKSequence(self): #self.donkeykonggfx f1 = Func(self.changeDkFrame, self.donkeykonggfx, 0.140867 - 0.0446603, 0) f2 = Func(self.changeDkFrame, self.donkeykonggfx, 0.0431023 - 0.0446603, 0.806672 - 0.703844) f3 = Func(self.changeDkFrame, self.donkeykonggfx, 0, 0) th = Func(self.throwBarrel) d = Wait(0.2) self.dk_sequence = Sequence(f1, d, f2, d, f3, th, d, f1) def reachedDk(self, evt): if (self.hammerTime): self.playerWon = True else: self.playerLost = True print("dk entered") def exitDk(self, evt): print("dk exit") def enableHammer(self, evt): self.hammerTime = True self.hammerSequence.loop() self.scene.node().removeChild( evt.getIntoNodePath().node().getParent(0)) def disableHammer(self, evt): pass def barrelCrash(self, evt): physicsBarrel = evt.getIntoNodePath().node().getParent(0).getParent(0) other = evt.getFromNodePath().node().getParent(0) if (other.name == "leftWall" or other.name == "rightWall"): forceNode = physicsBarrel.getChildren()[1] force = forceNode.getForce(0) force.setVector(force.getLocalVector().x * -1, 0, 0) forceNode.clear() forceNode.addForce(force) if other.name == "barrelDestroyer": self.scene.node().removeChild(physicsBarrel.getParent(0)) if other.name == "Player": if (self.hammerTime): self.scene.node().removeChild(physicsBarrel.getParent(0)) else: self.lifeCounter = self.lifeCounter - 1 if (self.lifeCounter < 0): self.playerLost = True else: self.lifes[self.lifeCounter].hide() def throwBarrel(self): barrelNode = self.scene.attachNewNode("PhysicalBarrel") physicsBarrel = ActorNode("physics_barrel") physicsBarrel.getPhysicsObject().setMass(0.01) barrel = barrelNode.attachNewNode(physicsBarrel) base.physicsMgr.attachPhysicalNode(physicsBarrel) visualBarrel = barrel.attachNewNode("BarrelCopy") originalBarrel = self.scene.find("root/barrel") originalBarrel.instanceTo(visualBarrel) visualBarrel.setPos(0, -100, 0) sphere = CollisionSphere(0.16, 100, 0, 0.5) cNodePath = visualBarrel.attachNewNode(CollisionNode("barrelCollider")) cNodePath.node().addSolid(sphere) cNodePath.node().setFromCollideMask(0x05) cNodePath.node().setIntoCollideMask(0x05) #cNodePath.show() self.physicsCollisionPusher.addCollider(cNodePath, barrel) base.cTrav.addCollider(cNodePath, self.physicsCollisionPusher) barrelForceNode = ForceNode("barrelForce") barrel.attachNewNode(barrelForceNode) barrelForce = LinearVectorForce(-8, 0, 0, 1, False) barrelForceNode.addForce(barrelForce) physicsBarrel.getPhysical(0).addLinearForce(barrelForce) barrelNode.setPos(self.scene, 7, 0, 4.5) dataNode = AuxNode("sequenceData") seq = self.createBarrelSequence(visualBarrel, physicsBarrel, dataNode) dataNode.setSequence(seq) barrelNode.attachNewNode(dataNode) def createBarrelSequence(self, visual, physics, dataNode): def updateBarrel(): vel = physics.getPhysicsObject().getVelocity() frame = dataNode.frame if (vel.x > 0): frame = (frame + 1) % 4 #vel.x = 5 if (vel.x < 0): frame = (frame - 1) % 4 #vel.x = -5 dataNode.frame = frame physics.getPhysicsObject().setVelocity(vel) visualFrame = self.barrels_frames[frame] visual.setTexOffset(TextureStage.getDefault(), visualFrame, 0.0) f1 = Func(updateBarrel) d = Wait(0.1) seq = Sequence(f1, d) seq.loop() return seq def createSquareCollider(self, px, pz, w, h, modelName, collisionNodeName, nodeName, enableFunction, disableFunction, texture, mask): obj = self.scene.attachNewNode(nodeName) hitbox = CollisionBox(Point3(0, 0, 0), w, 5, h) cNodePath = obj.attachNewNode(CollisionNode(collisionNodeName)) cNodePath.node().addSolid(hitbox) cNodePath.node().setIntoCollideMask(mask) cNodePath.node().setFromCollideMask(mask) #cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) self.scene.find(f'root/{modelName}').reparentTo(obj) obj.setPos(px, 0, pz) obj.setTexture(texture) self.accept(f'into-{collisionNodeName}', enableFunction) self.accept(f'outof-{collisionNodeName}', disableFunction) return obj def invisibleSquareCollider(self, px, pz, w, h, collisionNodeName, nodeName, mask): obj = self.scene.attachNewNode(nodeName) hitbox = CollisionBox(Point3(0, 0, 0), w, 5, h) cNodePath = obj.attachNewNode(CollisionNode(collisionNodeName)) cNodePath.node().addSolid(hitbox) cNodePath.node().setIntoCollideMask(mask) cNodePath.node().setFromCollideMask(mask) #cNodePath.show() base.cTrav.addCollider(cNodePath, self.collisionHandlerEvent) obj.setPos(px, 0, pz) def enableJump(self, evt): self.lastPlayerValidZ = evt.getIntoNodePath().node().getParent( 0).getTransform().getPos().z + 1 self.jumpAvailable = True print("enable jump") def disableJump(self, evt): print(evt.getIntoNodePath().node().getParent(0)) self.jumpAvailable = False print("disable jump") def enableStairs(self, evt): self.stairsAvailable = True print("enable stairs") def disableStairs(self, evt): self.stairsAvailable = False print("disable stairs") def applyMove(self): mv = Vec3(0, 0, 0) p = self.player.getPos() if (self.input["left"]): self.marioGfx.setSx(self.player, 1) mv.x = 0.1 if (self.input["right"]): self.marioGfx.setSx(self.player, -1) mv.x = -0.1 if (self.jumpAvailable): mv.z = self.v0 + self.baseTime * self.gravity if (not self.stairsAvailable): p.z = self.lastPlayerValidZ if (mv.z < 0): self.v0 = 0 self.baseTime = 0 mv.z = 0 if (self.input["space"] and self.jumpAvailable): self.baseTime = 0 self.v0 = .2 mv.z = self.v0 + self.baseTime * self.gravity if (not self.jumpAvailable and not self.stairsAvailable): self.baseTime = self.baseTime + globalClock.getDt() mv.z = self.v0 + self.baseTime * self.gravity if (self.stairsAvailable): self.baseTime = 0 self.v0 = 0 if (self.input["up"]): mv.z = mv.z + 0.1 if (self.input["down"] and not self.jumpAvailable): mv.z = mv.z - 0.1 p.x = p.x + mv.x p.z = p.z + mv.z self.player.setPos(p) def update(self, task): self.camera.setPos(0, 35, 0) self.camera.lookAt(self.scene) self.dkTimer = self.dkTimer + globalClock.getDt() if (self.dkTimer > 10): self.dk_sequence.start() self.dkTimer = 0 if ((self.playerLost or self.playerWon)): if (self.playerLost): text = DirectLabel(text="Perdiste!!!!", text_scale=(0.5, 0.5)) if (self.playerWon): text = DirectLabel(text="Ganastesss!", text_scale=(0.5, 0.5)) return Task.done self.applyMove() return Task.cont
class MHBProjectile(DirectObject): #Property stuff creaTime = time.clock() dur = .5 vec = 0 delta = .15 prevtime = 0 flag = False #defining the thing fired by whatever gun we have def __init__(self, camera, look, id, model): self.id = id #nodepath of the projectile, give it a trajectory self.projectileNode = NodePath('projectile'+str(id)) self.projectileNode.reparentTo(render) #by passing the camera node form the camMov object, all projectiles are spawned 5 units in front of the camera self.projectileNode.setHpr(look, 0, 0, 0) self.projectileNode.setPos(camera,0,3, 3) #fix z position to line up with gun self.projectileNode.setScale(.1) projectileModel = loader.loadModel("./resources/cubeShot.egg") projectileModel.setColor(255, 0, 0) projectileModel.reparentTo(self.projectileNode) #must calculate unit vector based on direction dir = render.getRelativeVector(look, Vec3(0, 1, 0)) #speed up or slow down projectiles here dir = dir*10 self.vec = dir #Balance vectors when magnitude in direction is low if self.vec.x < 2: self.vec.x += random.randint(-1,1) if self.vec.z < 2: self.vec.z += random.randint(-1,1) if self.vec.y < 2: self.vec.y += random.randint(-1,1) #Random vector displacements self.vec.x *= random.uniform(.5,1) self.vec.y *= random.uniform(.5,1) self.vec.z *= random.uniform(.5,1) #base.cTrav = CollisionTraverser() cs = CollisionSphere(0, 0, 0, 2.5) self.cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode')) self.cnodepath.node().addSolid(cs) self.collHand = CollisionHandlerEvent() self.cnodepath.setTag('tag', str(self.cnodepath)) self.collHand.addInPattern('%(tag)ix-into'+str(id)) self.collHand.addOutPattern('outof') #cTrav has the distinction of global colider handler base.cTrav.addCollider(self.cnodepath, self.collHand) self.acceptOnce(self.cnodepath.getTag('self')+'-into'+str(id), self.hit) #deal with colliding or special effects here. #wanted projectiles to be short lived # so i will make them delete themselves after impact or time expired # writing a task that will rek the projectiles at the end of time self.damage = 1.1 def moveTask(self, task): #curtime = time.clock() #self.delta = curtime-self.prevtime if self.flag: self.ignore(self.cnodepath.getTag('self')+'-into'+str(self.id)) return task.done velx = self.vec.x*self.delta vely = self.vec.y*self.delta velz = self.vec.z*self.delta x = self.projectileNode.getX() y = self.projectileNode.getY() z = self.projectileNode.getZ() self.projectileNode.setPos(x+velx, y+vely, z+velz) #prevtime = time.clock() self.cnodepath.setTag('tag', str(self)) if task.time < self.dur: return task.cont else: self.flag = True return task.done def hit(self, collEntry): # throw out a custom message for what hit if collEntry.getIntoNodePath().getName() != 'projNode': temp = collEntry.getIntoNodePath().getName() messenger.send(temp, [self.damage]) #remove the impacting projectile collEntry.getFromNodePath().getParent().getParent().removeNode() self.flag = True
class DKGame(ShowBase): def __init__(self): super().__init__(self) self.t = 1 self.loadScenery() self.mario = None #base.messenger.toggleVerbose() self.taskMgr.add(self.setup, "setup") self.taskMgr.add(self.update, "update") self.accept("raw-arrow_right" , self.pressRight) self.accept("raw-arrow_right-up" , self.stopRight) self.accept("raw-arrow_left" , self.pressLeft) self.accept("raw-arrow_left-up" , self.stopLeft) self.accept("raw-arrow_up" , self.pressUp) self.accept("raw-arrow_up-up" , self.stopUp) self.accept("raw-space" , self.pressSpace) self.accept("raw-space-up" , self.stopSpace) self.canClimb = False self.isClimbing = False #NUEVA! self.isGrounded = True self.canJump = True self.jumpTime = 0 self.vyi = 0 self.floorValidPosition = -4.5 self.barrelTimer = 0 self.lifes = 3 self.marioInitialPos = None self.posNotInitialized = True self.hammer = False self.barrels_frames = [] self.barrels_frames.append(0) self.barrels_frames.append( 0.410573 - 0.375774) self.barrels_frames.append( 0.444913 - 0.375774) self.barrels_frames.append( 0.479941 - 0.375774) self.dk_barrel_sequence = self.createDKBarrelSequence() self.hammer_sequence = self.createMarioHammerSequence() self.input = { "left":False, "right":False, "space":False, "up":False } def showHammerFrame(self, frame): if( frame == 1): self.marioRealGraphic.find("hammerup").show() self.marioRealGraphic.find("hammerdowm").hide() if( frame == 2): self.marioRealGraphic.find("hammerdowm").show() self.marioRealGraphic.find("hammerup").hide() def createMarioHammerSequence(self): f1 = Func( self.showHammerFrame , 1 ) f2 = Func( self.showHammerFrame , 2 ) delay = Wait(0.1) mySequence = Sequence(f1, delay,f2, delay) return mySequence def changeDKFrame(self, frame): dk = self.scene.find("hammer1") #remember that the name is wrong here if( frame == 1): dk.setTexOffset(TextureStage.getDefault() , 0.140867 - 0.0446603 ,0.0 ) if( frame == 2): dk.setTexOffset(TextureStage.getDefault() , 0.0431023 - 0.0446603 , 0.806672 - 0.703844 ) if( frame == 3): dk.setTexOffset(TextureStage.getDefault() , 0 ,0.0 ) """ frames 2) 0.140867 0.703844 1) 0.0431023 0.806672 ; throw 0 0.0446603 0.703065 """ def createDKBarrelSequence(self): func1 = Func(self.changeDKFrame,1) func2 = Func(self.changeDKFrame,2) func3 = Func(self.changeDKFrame,3) func4 = Func(self.createBarrel) delay = Wait(0.5) mySequence = Sequence(func1, delay,func2, delay, func3, func4, delay, func1) mySequence.loop() return mySequence def loadScenery(self): self.scene = self.loader.loadModel("models/DKSetTextured") # only for non animated objects myTexture = loader.loadTexture("models/dk-arcade.png") self.scene.setTexture(myTexture) self.scene.setTransparency(1) self.scene.reparentTo(self.render) def setup(self,task): lens = OrthographicLens() lens.setFilmSize(21.8,18) # Or whatever is appropriate for your scene #lens.setFilmSize(142,136) # Or whatever is appropriate for your scene base.camNode.setLens(lens) node = self.scene.find("root/camera1") node.removeNode() self.camera.setPos( 0,30,0 ) self.camera.lookAt(self.scene) self.mario = self.render.attachNewNode("MarioContainer") self.mario.setPos(self.scene, 0,0,0) self.marioGraphic = self.mario.attachNewNode("MarioGraphic") self.marioGraphic.setPos(self.mario, 0,0,0) self.scene.find("root/mario").reparentTo(self.marioGraphic) myTexture = loader.loadTexture("models/dk-arcade.png") self.marioRealGraphic = self.marioGraphic.find("mario") self.marioRealGraphic.setPos(self.marioGraphic, -6.7, 1, 4.5 ) self.marioRealGraphic.setTexture(myTexture) self.marioRealGraphic.setTwoSided(True) self.marioRealGraphic.setTransparency(1) self.scene.find("root/hammerup").reparentTo(self.marioRealGraphic) self.scene.find("root/hammerdowm").reparentTo(self.marioRealGraphic) self.marioRealGraphic.find("hammerup").hide() self.marioRealGraphic.find("hammerdowm").hide() self.scene.find("root/bottomstair").reparentTo(self.scene) self.scene.find("root/floor0").reparentTo(self.scene) self.scene.find("root/floor1").reparentTo(self.scene) self.scene.find("root/middlestair").reparentTo(self.scene) self.scene.find("root/topstair").reparentTo(self.scene) self.scene.find("root/floor2").reparentTo(self.scene) self.scene.find("root/pCube4").reparentTo(self.scene) self.scene.find("root/floors").reparentTo(self.scene) self.scene.find("root/barrel").reparentTo(self.scene) self.scene.find("root/walls").reparentTo(self.scene) self.scene.find("root/rightWall").reparentTo(self.scene) self.scene.find("root/MainGroup").reparentTo(self.scene) self.scene.find("root/hammer1").reparentTo(self.scene) self.barrel = self.scene.find("barrel") self.barrel.setPos(self.scene, 0,0,20) myTexture = loader.loadTexture("models/block.png") self.scene.find("floor0").setTexture(myTexture) self.scene.find("floor1").setTexture(myTexture) self.scene.find("floor2").setTexture(myTexture) self.scene.find("floors").setTexture(myTexture) self.scene.find("pCube4").setTexture(myTexture) self.scene.find("floor0").setTransparency(1) self.scene.find("floor1").setTransparency(1) self.scene.find("floor2").setTransparency(1) self.scene.find("floors").setTransparency(1) self.scene.find("pCube4").setTransparency(1) myTexture = loader.loadTexture("models/stairs.png") self.scene.find("bottomstair").setTexture(myTexture) self.scene.find("middlestair").setTexture(myTexture) self.scene.find("topstair").setTexture(myTexture) self.scene.find("bottomstair").setTransparency(1) self.scene.find("middlestair").setTransparency(1) self.scene.find("topstair").setTransparency(1) base.setBackgroundColor(0,0,0) self.setupCollision() base.enableParticles() gravityFN=ForceNode('world-forces') gravityFNP=render.attachNewNode(gravityFN) gravityForce=LinearVectorForce(0,0,-9.81) #gravity acceleration gravityFN.addForce(gravityForce) base.physicsMgr.addLinearForce(gravityForce) # create dk graphic barrel sequence return Task.done def barrelGraphicUpdate(self, visual, physics, data): def update(): vel = physics.getPhysicsObject().getVelocity() prevFrame = data.node().getPythonTag("subclass").frame if( vel.x < 0): data.node().getPythonTag("subclass").frame = (prevFrame - 1)%4 else: data.node().getPythonTag("subclass").frame = (prevFrame + 1)%4 visual.setTexOffset(TextureStage.getDefault() , self.barrels_frames[prevFrame] ,0.0 ) return update def createBarrelGraphicSequence(self, visual, physics, data): funcInterval = FunctionInterval(self.barrelGraphicUpdate(visual, physics, data), name = "BarrelGraphicUpdate") delay = Wait(0.1) mySequence = Sequence(funcInterval, delay) mySequence.loop() return mySequence def createBarrel(self): barrelNode = NodePath("PhysicalBarrel") barrelNode.reparentTo(self.scene) barrelNode.setPos(self.scene, 0,0,0) physicsBarrel = ActorNode("physics_barrel") physicsBarrel.getPhysicsObject().setMass(0.01) #in what units? (69 kindda 3 lbs) barrel = barrelNode.attachNewNode(physicsBarrel) base.physicsMgr.attachPhysicalNode(physicsBarrel) barrel.setPos(barrelNode, 0,0,0) visual_barrel = self.scene.attachNewNode("BarrelCopy") originalBarrel = self.scene.find("barrel") originalBarrel.instanceTo(visual_barrel) visual_barrel.reparentTo(barrel) visual_barrel.setPos(self.scene, -6.5,0,-24.5 ) dataNode = barrelNode.attachNewNode(AuxData("Sequence",None)) seq = self.createBarrelGraphicSequence(visual_barrel, physicsBarrel, dataNode) dataNode.node().getPythonTag("subclass").sequence = seq #sphere = CollisionSphere(6.6,0,4.78, 0.5) sphere = CollisionSphere(6.6,0,24.7, 0.5) cnodePath = visual_barrel.attachNewNode(CollisionNode('barrelCollider')) cnodePath.node().addSolid(sphere) cnodePath.node().setFromCollideMask(0xD) # crash with default and mario body and walls cnodePath.node().setIntoCollideMask(0xD) # crash with default and mario body and walls self.showCollision(cnodePath) #cnodePath.show() self.physicsCollisionPusher.addCollider(cnodePath,barrel) base.cTrav.addCollider(cnodePath, self.physicsCollisionPusher) barrelForceNode = ForceNode('barrelForce') barrel.attachNewNode(barrelForceNode) barrelForce = LinearVectorForce(-7,0,0, 1, False) # barrelForce.setMassDependent(0) barrelForceNode.addForce(barrelForce) physicsBarrel.getPhysical(0).addLinearForce(barrelForce) # starting barrel point :D barrelNode.setPos(self.scene,6.5,0,4.5) def setupBoxCollider(self , node, px, py, pz, w,d,h, nm, colliderEventHandler , fromCollisionMask=0, intoCollisionMask=0 ): hitBox = CollisionBox( Point3(px,py,pz) , w,d,h) cnodePath = node.attachNewNode( CollisionNode(nm) ) cnodePath.node().addSolid(hitBox) cnodePath.node().setIntoCollideMask(intoCollisionMask) cnodePath.node().setFromCollideMask(fromCollisionMask) # cnodePath.show() self.showCollision(cnodePath) base.cTrav.addCollider(cnodePath, colliderEventHandler) def setupCollision(self): base.cTrav = CollisionTraverser() self.collisionHandlerEvent = CollisionHandlerEvent() self.physicsCollisionPusher = PhysicsCollisionHandler() self.collisionHandlerEvent.addInPattern('into-%in') self.collisionHandlerEvent.addOutPattern('outof-%in') # create masks defaultCollisionMask = BitMask32(0b0001) #0x1 segmentCollisionMask = BitMask32(0b1000) #0x8 stairsCollisionMask = BitMask32(0b0010) #0x2 marioBodyCollisionMask = BitMask32(0b0011) #0x3 collisionWallsForBarrels = BitMask32(0b0100) #0x4 # mario segment collider #ray = CollisionSegment(7,0,-4.5, 7,0,-5.1) ray = CollisionSegment(0,0,0, 0,0,-.51) cnodePath = self.mario.attachNewNode(CollisionNode('marioRay')) cnodePath.node().addSolid(ray) cnodePath.node().setFromCollideMask(segmentCollisionMask) cnodePath.node().setIntoCollideMask(0) self.showCollision(cnodePath) base.cTrav.addCollider(cnodePath, self.collisionHandlerEvent) #self.setupBoxCollider(self.mario, 7,0,-4.5, 0.5,5,0.5, 'marioHitBox', self.collisionHandlerEvent, marioBodyCollisionMask,marioBodyCollisionMask ) self.setupBoxCollider(self.mario, 0,0,0, 0.5,5,0.5, 'marioHitBox', self.collisionHandlerEvent, marioBodyCollisionMask,marioBodyCollisionMask ) stairs1 = self.scene.find("bottomstair") self.setupBoxCollider(stairs1, -6.8,0,-3.0, 0.5,5,2.5, 'stairs1HitBox', self.collisionHandlerEvent, stairsCollisionMask,stairsCollisionMask ) stairs2 = self.scene.find("middlestair") self.setupBoxCollider(stairs2, -0.86,0, .1, 0.5,5,2.1, 'stairs2HitBox', self.collisionHandlerEvent, stairsCollisionMask,stairsCollisionMask ) stairs3 = self.scene.find("topstair") self.setupBoxCollider(stairs3, -6.8,0, 3.1, 0.5,5,2.2, 'stairs3HitBox', self.collisionHandlerEvent, stairsCollisionMask,stairsCollisionMask ) hammer = self.scene.find("MainGroup") # hammer self.setupBoxCollider(hammer, 5.5,0, -1.5, 0.5,5,0.5, 'hammer1HitBox', self.collisionHandlerEvent, stairsCollisionMask,stairsCollisionMask ) dk = self.scene.find("hammer1") self.setupBoxCollider(dk, 8.7,0, 5, 1,5,1, 'dkHitBox', self.collisionHandlerEvent, stairsCollisionMask,stairsCollisionMask ) floor0 = self.scene.find("floor0") self.setupBoxCollider(floor0, -2.5,0,-5.5, 10,5,0.5, 'floor0HitBox', self.collisionHandlerEvent , intoCollisionMask=segmentCollisionMask ) floor1 = self.scene.find("floor1") self.setupBoxCollider(floor1, 2,0, -2.5, 8.4,5,0.5, 'floor1HitBox', self.collisionHandlerEvent , intoCollisionMask=segmentCollisionMask ) floor2_1 = self.scene.find("floor2") self.setupBoxCollider(floor2_1, 3.6,0, 0.5, 3.8,5,0.5, 'floor21HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask ) floor2_2 = self.scene.find("pCube4") self.setupBoxCollider(floor2_2, -6.3,0, 0.5, 5.0 ,5,0.5, 'floor22HitBox', self.collisionHandlerEvent, intoCollisionMask=segmentCollisionMask ) floor3 = self.scene.find("floors") self.setupBoxCollider(floor3, 1.8,0, 3.5, 8,5,0.5, 'floor3HitBox', self.collisionHandlerEvent , intoCollisionMask=segmentCollisionMask ) rightWall = self.scene.find("rightWall") self.setupBoxCollider(rightWall, -12,0, 0, 1,5,10, 'rightWallHitBox', self.collisionHandlerEvent , fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels ) leftWall = self.scene.find("walls") self.setupBoxCollider(leftWall, 11.5,0, 0, 1,5,10, 'leftWallHitBox', self.collisionHandlerEvent , fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels ) barrelFixer = self.scene.attachNewNode("barrelFixer") self.setupBoxCollider(barrelFixer, -3,0, 0.505, 10,5,0.5, 'barrelFixerHitBox', self.collisionHandlerEvent , fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels ) barrelDestroyer = self.scene.attachNewNode("barrelDestroyer") self.setupBoxCollider(barrelDestroyer, 0,0, -8, 15,5,0.5, 'barrelDestroyerHitBox', self.collisionHandlerEvent , fromCollisionMask=collisionWallsForBarrels, intoCollisionMask=collisionWallsForBarrels ) self.accept('into-stairs1HitBox', self.enableStair) self.accept('outof-stairs1HitBox', self.disableStair) self.accept('into-stairs2HitBox', self.enableStair) self.accept('outof-stairs2HitBox', self.disableStair) self.accept('into-stairs3HitBox', self.enableStair) self.accept('outof-stairs3HitBox', self.disableStair) self.accept('into-hammer1HitBox', self.enableHammer) self.accept('into-dkHitBox', self.dkArrived) self.accept('into-floor0HitBox', self.enableJump) self.accept('outof-floor0HitBox', self.disableJump) self.accept('into-floor1HitBox', self.enableJump) self.accept('outof-floor1HitBox', self.disableJump) self.accept('into-floor21HitBox', self.enableJump) self.accept('outof-floor21HitBox', self.disableJump) self.accept('into-floor22HitBox', self.enableJump) self.accept('outof-floor22HitBox', self.disableJump) self.accept('into-floor3HitBox', self.enableJump) self.accept('outof-floor3HitBox', self.disableJump) self.accept("into-barrelCollider", self.barrelCrash) #base.cTrav.showCollisions(self.render) def showCollision(self, col): #col.show() print("Not showing collider") def dkArrived(self,evt): if(self.hammer): self.scene.node().removeChild(evt.getIntoNodePath().node().getParent(0)) text = DirectLabel(text="You won", text_scale=(0.5,0.5)) else: self.floorValidPosition = -4.5 self.mario.setPos(self.scene, self.marioInitialPos) text = DirectLabel(text="Game Over", text_scale=(0.5,0.5)) def enableHammer(self, evt): print(f"{evt.getIntoNodePath()}{evt.getFromNodePath()}") self.scene.node().removeChild(evt.getIntoNodePath().node().getParent(0)) self.hammer_sequence.loop() self.hammer = True def changeBarrelDirection(self, evt): print(f"Changing barrel direction {evt}") def barrelCrash(self,evt): barrel = evt.getIntoNodePath().node().getParent(0).getParent(0) other = evt.getFromNodePath().node().getParent(0) parents = barrel.parents # print(f"{other}") if other.name=="barrelDestroyer": p = parents[0] childrens = barrel.getParent(0).getChildren() childrens[1].getPythonTag("subclass").sequence.finish() self.scene.node().removeChild(p) return if not (other==self.mario.node() or other.name=="barrelFixer" ) : forceNode = barrel.getChildren()[1] actualForce = forceNode.getForce(0) actualForce.setVector( actualForce.getLocalVector().x*-1, 0 , 0 ) forceNode.clear() forceNode.addForce(actualForce) if( other == self.mario.node() ): if not self.hammer: self.lifes = self.lifes - 1 self.floorValidPosition = -4.5 self.mario.setPos(self.scene, self.marioInitialPos) p = parents[0] childrens = barrel.getParent(0).getChildren() childrens[1].getPythonTag("subclass").sequence.finish() self.scene.node().removeChild(p) if( self.lifes < 0): print("game over dude!!") text = DirectLabel(text="Game Over", text_scale=(0.5,0.5)) def enableStair(self, evt): print("crashed mario and stair"); self.canClimb = True def disableStair(self, evt): print("exit mario and stair"); self.canClimb = False def enableJump(self, evt): self.isGrounded = True print("enable jump") # fromCollider = evt.getFrom().getCenter().z - evt.getFrom().getDimensions().z/2 self.floorValidPosition = evt.getInto().getCenter().z + 1 print(f"{ evt.getInto().getCenter().z } {self.floorValidPosition} ") def disableJump(self, evt): print("disable jump") self.isGrounded = False def pressUp(self): print("up enabled") self.input["up"] = True; def stopUp(self): print("up disabled") self.input["up"] = False; def pressRight(self): self.input["right"] = True; def stopRight(self): self.input["right"] = False; def pressLeft(self): self.input["left"] = True; def stopLeft(self): self.input["left"] = False; def pressSpace(self): self.input["space"] = True; #self.camera.setPos( 0,30,0 ) #self.camera.lookAt(self.scene) def stopSpace(self): self.input["space"] = False; def getAdvance(self): if self.input["left"] and self.input["right"]: return 0 if self.input["left"]: return -1 if self.input["right"]: return 1 return 0 def applyJump(self): jz = 0 # jump Y/Z vi = 4 # initial velocity g = -6 # gravity if(self.isGrounded): if(self.canJump): if(self.input["space"]): self.jumpTime = 0.1 self.canJump = False self.vyi = vi jz = self.vyi*self.jumpTime + 0.5*g*self.jumpTime*self.jumpTime vz = self.vyi + g*self.jumpTime else: return 0 else: self.jumpTime = self.jumpTime + globalClock.getDt() jz = self.vyi*self.jumpTime + 0.5*g*self.jumpTime*self.jumpTime vz = self.vyi + g*self.jumpTime if vz < 0: #finished self.jumpTime = 0 self.canJump = True self.vyi = 0 jz = 0 else: if(not self.isClimbing): self.canJump = False self.jumpTime = self.jumpTime + globalClock.getDt() jz = self.vyi*self.jumpTime + 0.5*g*self.jumpTime*self.jumpTime vz = self.vyi + g*self.jumpTime return jz def applyStairs(self, pz): if( self.canClimb): if(self.input["up"]): self.isClimbing = True if( self.isClimbing ): if( self.input["up"]): return pz + 0.1 if( not self.canClimb): self.isClimbing = False return pz def update(self,task): self.camera.setPos( 0,30,0 ) self.camera.lookAt(self.scene) pz = self.applyJump() if( self.posNotInitialized): self.marioInitialPos = self.mario.getPos() self.posNotInitialized = False self.barrelTimer = self.barrelTimer + globalClock.getDt() if self.barrelTimer > (3 + random()*2): # fix error! when dk has lost! -> exercise :D self.dk_barrel_sequence.start() self.barrelTimer = 0 # self.mario.getPos(self.render).z advZ = self.applyStairs(self.floorValidPosition ) self.floorValidPosition = advZ if( self.getAdvance() != 0): self.marioGraphic.setSx(self.mario, -self.getAdvance()) self.mario.setPos(self.render, self.mario.getPos().x + -self.getAdvance()*.1 , 0 , advZ+pz ) # advZ+pz return Task.cont
class ChargeProjectile(DirectObject): dur = 2 delta = .15 flag = False def __init__(self, spawn, taregt, id): self.projectileNode = NodePath('projectile'+str(id)) self.projectileNode.reparentTo(render) self.projectileNode.setPos(spawn,0,-10, 0) self.projectileNode.setScale(1.5) self.projectileModel = Actor("./resources/sphereShot",{"grow":"./resources/sphereShot-grow"}) self.projectileModel.setColorScale(200, 0, 255, 100) self.projectileModel.reparentTo(self.projectileNode) self.projectileNode.setHpr(spawn, 0, 0, 0) dir = render.getRelativeVector(spawn, Vec3(0, 1, 0)) self.vec = dir*-100 cs = CollisionSphere(0, 0, 0, 2.5) cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode')) cnodepath.node().addSolid(cs) self.collHand = CollisionHandlerEvent() self.collHand.addInPattern('bossProjectileinto'+str(id)) self.collHand.addOutPattern('outof') base.cTrav.addCollider(cnodepath, self.collHand) self.acceptOnce('bossProjectileinto'+str(id), self.hit) self.damage = 15 def moveTask(self, task): if self.flag: return task.done velx = self.vec.x*self.delta vely = self.vec.y*self.delta velz = self.vec.z*self.delta x = self.projectileNode.getX() y = self.projectileNode.getY() z = self.projectileNode.getZ() self.projectileNode.setPos(x+velx, y+vely, z+velz) if task.time < self.dur: return task.cont else: self.flag = True return task.done def hit(self, collEntry): #throw out a custom message for what hit if collEntry.getIntoNodePath().getName() != 'projNode': temp = collEntry.getIntoNodePath().getName() print temp messenger.send(temp, [self.damage]) #remove the impacting projectile collEntry.getFromNodePath().getParent().getParent().removeNode() self.flag = True del self def wait(self, task): if task.time > 2.24: return task.done return task.cont
class CogdoFlyingCollisions(GravityWalker): wantFloorSphere = 0 def __init__(self): GravityWalker.__init__(self, gravity=0.0) def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius=1.4, floorOffset=1.0, reach=1.0): self.cHeadSphereNodePath = None self.cFloorEventSphereNodePath = None self.setupHeadSphere(avatarNodePath) self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius) GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach) return def setupWallSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius) cSphereNode = CollisionNode('Flyer.cWallSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) if config.GetBool('want-fluid-pusher', 0): self.pusher = CollisionHandlerFluidPusher() else: self.pusher = CollisionHandlerPusher() self.pusher.addCollider(cSphereNodePath, self.avatarNodePath) self.cWallSphereNodePath = cSphereNodePath def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath def setupRay(self, bitmask, floorOffset, reach): cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0) cRayNode = CollisionNode('Flyer.cRayNode') cRayNode.addSolid(cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerGravity() self.lifter.setLegacyMode(self._legacyLifter) self.lifter.setGravity(self.getGravity(0)) self.lifter.addInPattern('%fn-enter-%in') self.lifter.addAgainPattern('%fn-again-%in') self.lifter.addOutPattern('%fn-exit-%in') self.lifter.setOffset(floorOffset) self.lifter.setReach(reach) self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath def deleteCollisions(self): GravityWalker.deleteCollisions(self) if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) self.cHeadSphereNodePath.detachNode() self.cHeadSphereNodePath = None self.headCollisionsEvent = None if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) self.cFloorEventSphereNodePath.detachNode() self.cFloorEventSphereNodePath = None self.floorCollisionEvent = None self.cRayNodePath.detachNode() del self.cRayNodePath self.cEventSphereNodePath.detachNode() del self.cEventSphereNodePath return def setCollisionsActive(self, active=1): if self.collisionsActive != active: if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) if active: base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) if active: base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent) GravityWalker.setCollisionsActive(self, active) return def enableAvatarControls(self): pass def disableAvatarControls(self): pass def handleAvatarControls(self, task): pass
class GameContainer(ShowBase): def __init__(self): ShowBase.__init__(self) ########## Window configuration ######### wp = WindowProperties() wp.setSize(1024, 860) wp.setTitle("") wp.setOrigin(-2, -2) self.win.requestProperties(wp) self.win.movePointer(0, wp.getXSize() / 2, wp.getYSize() / 2) print wp.getXSize() / 2, wp.getYSize() / 2 ########## Gameplay settings ######### self.gameMode = {"display": PLAY, "play": TERRAIN} self.level = 1.5 self.mode_initialized = False ######### Camera ######### self.disableMouse() self.mainCamera = Camera(self.camera) self.mainCamera.camObject.setHpr(0, 0, 0) self.loadLevel() ######### Events ######### self.taskMgr.add(self.gameLoop, "gameLoop", priority=35) self.keys = {"w": 0, "s": 0, "a": 0, "d": 0, "space": 0, "escape": 0} self.accept("w", self.setKey, ["w", 1]) self.accept("w-up", self.setKey, ["w", 0]) self.accept("s", self.setKey, ["s", 1]) self.accept("s-up", self.setKey, ["s", 0]) self.accept("a", self.setKey, ["a", 1]) self.accept("a-up", self.setKey, ["a", 0]) self.accept("d", self.setKey, ["d", 1]) self.accept("d-up", self.setKey, ["d", 0]) self.accept("space", self.setKey, ["space", 1]) self.accept("space-up", self.setKey, ["space", 0]) self.accept("escape", self.setKey, ["escape", 1]) self.accept("escape-up", self.setKey, ["escape", 0]) self.accept("wheel_up", self.zoomCamera, [-1]) self.accept("wheel_down", self.zoomCamera, [1]) self.accept("window-event", self.handleWindowEvent) ######### GUI ######### #self.fonts = {"failure" : loader.loadFont('myfont.ttf')} self.guiElements = [] self._GCLK = None self._FT = None #Trigger game chain #self.enableParticles() #self.buildMainMenu() def setKey(self, key, value): self.keys[key] = value def zoomCamera(self, direction): if self.gameMode["play"] == TERRAIN: Camera.AVATAR_DIST += direction def toggleCursor(self, state): props = WindowProperties() props.setCursorHidden(state) base.win.requestProperties(props) def handleWindowEvent(self, window=None): wp = window.getProperties() self.win_center_x = wp.getXSize() / 2 self.win_center_y = wp.getYSize() / 2 def processKeys(self): if self.keys["escape"]: if self.gameMode["display"] == PLAY: self.switchDisplayMode(IN_GAME_MENU) elif self.gameMode["display"] == IN_GAME_MENU: self.switchDisplayMode(PLAY) self.setKey("escape", 0) ######### Level specific features ######### def maintainTurrets(self): pass def switchDisplayMode(self, newGameMode): self.cleanupGUI() if self.gameMode["display"] == MAIN_MENU: pass elif self.gameMode["display"] == IN_GAME_MENU: if newGameMode == PLAY: render.clearFog() self.togglePhysicsPause() elif newGameMode == MAIN_MENU: pass elif self.gameMode["display"] == PLAY: if newGameMode == IN_GAME_MENU: self.togglePhysicsPause() self.gameMode["display"] = newGameMode self.mode_initialized = False def advanceLevel(self): self.level += .5 self.loadLevel() def evenButtonPositions(self, button_spacing, button_height, num_buttons): centerOffset = (button_spacing / (2.0) if (num_buttons % 2 == 0) else 0) buttonPositions = [] current_pos = centerOffset + ((num_buttons - 1) / 2) * button_spacing for i in range(0, num_buttons): buttonPositions.append(current_pos + (button_height / 2.0)) current_pos -= button_spacing return buttonPositions def buildInGameMenu(self): self.toggleCursor(False) resume_button = DirectButton( text="Resume", scale=.1, command=(lambda: self.switchDisplayMode(PLAY)), rolloverSound=None) main_menu_button = DirectButton(text="Main Menu", scale=.1, command=None, rolloverSound=None) options_button = DirectButton(text="Settings", scale=.1, command=None, rolloverSound=None) exit_button = DirectButton(text="Exit", scale=.1, command=exit, rolloverSound=None) BUTTON_SPACING = .2 BUTTON_HEIGHT = resume_button.getSy() button_positions = self.evenButtonPositions(BUTTON_SPACING, BUTTON_HEIGHT, 4) resume_button.setPos(Vec3(0, 0, button_positions[0])) main_menu_button.setPos(Vec3(0, 0, button_positions[1])) options_button.setPos(Vec3(0, 0, button_positions[2])) exit_button.setPos(Vec3(0, 0, button_positions[3])) self.guiElements.append(resume_button) self.guiElements.append(main_menu_button) self.guiElements.append(options_button) self.guiElements.append(exit_button) def buildMainMenu(self): self.toggleCursor(False) start_game_button = DirectButton(text="Start", scale=.1, command=None) select_level_button = DirectButton(text="Select Level", scale=.1, command=None) game_options_button = DirectButton(text="Settings", scale=.1, command=None) exit_button = DirectButton(text="Exit", scale=.1, command=exit) BUTTON_SPACING = .2 BUTTON_HEIGHT = start_game_button.getSy() button_positions = self.evenButtonPositions(BUTTON_SPACING, BUTTON_HEIGHT, 4) start_game_button.setPos(Vec3(0, 0, button_positions[0])) select_level_button.setPos(Vec3(0, 0, button_positions[1])) game_options_button.setPos(Vec3(0, 0, button_positions[2])) exit_button.setPos(Vec3(0, 0, button_positions[3])) self.guiElements.append(start_game_button) self.guiElements.append(select_level_button) self.guiElements.append(game_options_button) self.guiElements.append(exit_button) particles = Particles() particles.setPoolSize(1000) particles.setBirthRate(.1) particles.setLitterSize(10) particles.setLitterSpread(3) particles.setFactory("PointParticleFactory") particles.setRenderer("PointParticleRenderer") particles.setEmitter("SphereVolumeEmitter") particles.enable() self.effect = ParticleEffect("peffect", particles) self.effect.reparentTo(render) #self.effect.setPos(self.avatar.objectNP.getX(), self.avatar.objectNP.getY(), self.avatar.objectNP.getZ() + 5) self.effect.setPos(-1, 0, 0) self.effect.enable() def buildDeathScreen(self): self.toggleCursor(False) backFrame = DirectFrame(frameColor=(1, 0, 0, .7), frameSize=(-.5, .5, -.3, .3), pos=(0, 0, 0)) deadMessage = DirectLabel(text="MISSION FAILURE", scale=.1, pos=(0, 0, .16), relief=None, text_font=None) restartButton = DirectButton(text="Restart", scale=.1, pos=(0, 0, -.1), command=self.resetLevel) deadMessage.reparentTo(backFrame) restartButton.reparentTo(backFrame) self.guiElements.append(backFrame) self.guiElements.append(deadMessage) self.guiElements.append(restartButton) def cleanupGUI(self): for guiElement in self.guiElements: guiElement.destroy() def loadSpaceTexture(self, level): if level < 10: return 'textures/space#.jpg' elif level < 15: pass def resetLevel(self): self.switchDisplayMode(PLAY) self.loadLevel(True) def loadLevel(self, reset=False): #Resets self.avatarActor = Actor("models/panda", {"walk": "models/panda-walk"}) self.avatarActor.setScale(.5, .5, .5) self.avatarActor.setHpr(180, 0, 0) self.avatarActor.setCollideMask(BitMask32.allOff()) self.asteroidManager = AsteroidManager() self.cTrav = CollisionTraverser() #Alternate modes if int(self.level) == self.level: self.gameMode["play"] = TERRAIN else: self.gameMode["play"] = SPACE #Specifics if self.gameMode["play"] == SPACE: if reset: self.avatar.reset() else: self.avatar = Avatar(self.avatarActor, self.level) self.avatar.objectNP.reparentTo(render) ########## Sky ######### cubeMap = loader.loadCubeMap(self.loadSpaceTexture(self.level)) self.spaceSkyBox = loader.loadModel('models/box') self.spaceSkyBox.setScale(100) self.spaceSkyBox.setBin('background', 0) self.spaceSkyBox.setDepthWrite(0) self.spaceSkyBox.setTwoSided(True) self.spaceSkyBox.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldCubeMap) self.spaceSkyBox.setTexture(cubeMap, 1) parentNP = render.attachNewNode('parent') self.spaceSkyBox.reparentTo(parentNP) self.spaceSkyBox.setPos(-self.spaceSkyBox.getSx() / 2, -self.spaceSkyBox.getSy() / 2, -self.spaceSkyBox.getSz() / 2) ########## Collisions ######### bound = self.avatarActor.getBounds() self.pandaBodySphere = CollisionSphere( bound.getCenter()[0] / self.avatar.objectNP.getSx() - self.avatar.objectNP.getX(), bound.getCenter()[1] / self.avatar.objectNP.getSx() - self.avatar.objectNP.getY(), bound.getCenter()[2] / self.avatar.objectNP.getSx() - self.avatar.objectNP.getZ(), 5) self.pandaBodySphere.setRadius(bound.getRadius() + 1) self.pandaBodySphereNode = CollisionNode("playerBodyRay") self.pandaBodySphereNode.addSolid(self.pandaBodySphere) self.pandaBodySphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaBodySphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaBodySphereNodepath = self.avatar.objectNP.attachNewNode( self.pandaBodySphereNode) self.pandaBodySphereNodepath.show() self.collisionNotifier = CollisionHandlerEvent() self.collisionNotifier.addInPattern("%fn-in") self.collisionNotifier.addOutPattern("%fn-out") self.cTrav.addCollider(self.pandaBodySphereNodepath, self.collisionNotifier) self.accept("playerGroundRayJumping-in", self.avatar.handleCollisionEvent, ["in"]) self.accept("playerGroundRayJumping-out", self.avatar.handleCollisionEvent, ["out"]) self.accept("playerBodyRay-in", self.avatar.handleCollisionEvent, ["in"]) self.asteroidManager.initialize(self.level) elif self.gameMode["play"] == TERRAIN: ########## Terrain ######### #self.environ = loader.loadModel("../mystuff/test.egg") self.environ = loader.loadModel("models/environment") self.environ.setName("terrain") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) self.environ.setCollideMask(BitMask32.bit(0)) ######### Physics ######### self.enableParticles() gravityForce = LinearVectorForce(0, 0, -9.81) gravityForce.setMassDependent(False) gravityFN = ForceNode("world-forces") gravityFN.addForce(gravityForce) render.attachNewNode(gravityFN) base.physicsMgr.addLinearForce(gravityForce) self.avatarPhysicsActorNP = render.attachNewNode( ActorNode("player")) self.avatarPhysicsActorNP.node().getPhysicsObject().setMass(50.) self.avatarActor.reparentTo(self.avatarPhysicsActorNP) base.physicsMgr.attachPhysicalNode( self.avatarPhysicsActorNP.node()) self.avatarPhysicsActorNP.setPos(15, 10, 5) ######### Game objects ######### self.avatar = Avatar(self.avatarPhysicsActorNP, self.level) ######### Collisions ######### self.pandaBodySphere = CollisionSphere(0, 0, 4, 3) self.pandaBodySphereNode = CollisionNode("playerBodySphere") self.pandaBodySphereNode.addSolid(self.pandaBodySphere) self.pandaBodySphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaBodySphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaBodySphereNodepath = self.avatar.objectNP.attachNewNode( self.pandaBodySphereNode) self.pandaBodySphereNodepath.show() self.pandaBodyCollisionHandler = PhysicsCollisionHandler() self.pandaBodyCollisionHandler.addCollider( self.pandaBodySphereNodepath, self.avatar.objectNP) #Keep player on ground self.pandaGroundSphere = CollisionSphere(0, 0, 1, 1) self.pandaGroundSphereNode = CollisionNode("playerGroundRay") self.pandaGroundSphereNode.addSolid(self.pandaGroundSphere) self.pandaGroundSphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaGroundSphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaGroundSphereNodepath = self.avatar.objectNP.attachNewNode( self.pandaGroundSphereNode) self.pandaGroundSphereNodepath.show() self.pandaGroundCollisionHandler = PhysicsCollisionHandler() self.pandaGroundCollisionHandler.addCollider( self.pandaGroundSphereNodepath, self.avatar.objectNP) #Notify when player lands self.pandaGroundRayJumping = CollisionSphere(0, 0, 1, 1) self.pandaGroundRayNodeJumping = CollisionNode( "playerGroundRayJumping") self.pandaGroundRayNodeJumping.addSolid(self.pandaGroundRayJumping) self.pandaGroundRayNodeJumping.setFromCollideMask(BitMask32.bit(0)) self.pandaGroundRayNodeJumping.setIntoCollideMask( BitMask32.allOff()) self.pandaGroundRayNodepathJumping = self.avatar.objectNP.attachNewNode( self.pandaGroundRayNodeJumping) self.pandaGroundRayNodepathJumping.show() self.collisionNotifier = CollisionHandlerEvent() self.collisionNotifier.addInPattern("%fn-in") self.collisionNotifier.addOutPattern("%fn-out") self.cTrav.addCollider(self.pandaGroundSphereNodepath, self.pandaGroundCollisionHandler) self.cTrav.addCollider(self.pandaGroundRayNodepathJumping, self.collisionNotifier) self.cTrav.addCollider(self.pandaBodySphereNodepath, self.pandaBodyCollisionHandler) self.accept("playerGroundRayJumping-in", self.avatar.handleCollisionEvent, ["in"]) self.accept("playerGroundRayJumping-out", self.avatar.handleCollisionEvent, ["out"]) self.accept("playerBodyRay-in", self.avatar.handleCollisionEvent, ["in"]) def togglePhysicsPause(self): if (self._GCLK == None): self.disableParticles() self._GCLK = ClockObject.getGlobalClock() self._FT = self._GCLK.getFrameTime() self._GCLK.setMode(ClockObject.MSlave) else: self._GCLK.setRealTime(self._FT) self._GCLK.setMode(ClockObject.MNormal) self.enableParticles() self._GCLK = None def gameLoop(self, task): dt = globalClock.getDt() self.processKeys() if self.gameMode["display"] == MAIN_MENU: if not self.mode_initialized: self.buildMainMenu() self.mode_initialized = True if self.gameMode["display"] == IN_GAME_MENU: if not self.mode_initialized: #Fog out background inGameMenuFogColor = (50, 150, 50) inGameMenuFog = Fog("inGameMenuFog") inGameMenuFog.setMode(Fog.MExponential) inGameMenuFog.setColor(*inGameMenuFogColor) inGameMenuFog.setExpDensity(.01) render.setFog(inGameMenuFog) self.buildInGameMenu() self.mode_initialized = True if self.gameMode["display"] == DEAD: if not self.mode_initialized: self.buildDeathScreen() self.mode_initialized = True if self.gameMode["display"] == PLAY: alive = self.avatar.states["alive"] if not self.mode_initialized: self.toggleCursor(True) self.last_mouse_x = self.win.getPointer(0).getX() self.last_mouse_y = self.win.getPointer(0).getY() self.mode_initialized = True if self.gameMode["play"] == TERRAIN: if alive: self.maintainTurrets() self.avatar.move(dt) else: self.switchDisplayMode(DEAD) elif self.gameMode["play"] == SPACE: if alive: self.asteroidManager.maintainAsteroidField( self.avatar.objectNP.getPos(), self.avatar.speed, Camera.AVATAR_DIST, dt) else: self.switchDisplayMode(DEAD) if alive: #Handle keyboard input self.avatar.handleKeys(self.keys, self.gameMode["play"]) ########## Mouse-based viewpoint rotation ########## mouse_pos = self.win.getPointer(0) current_mouse_x = mouse_pos.getX() current_mouse_y = mouse_pos.getY() #Side to side if self.gameMode["play"] == TERRAIN: mouse_shift_x = current_mouse_x - self.last_mouse_x self.last_mouse_x = current_mouse_x if current_mouse_x < 5 or current_mouse_x >= ( self.win_center_x * 1.5): base.win.movePointer(0, self.win_center_x, current_mouse_y) self.last_mouse_x = self.win_center_x yaw_shift = -((mouse_shift_x) * Camera.ROT_RATE[0]) self.avatar.yawRot += yaw_shift self.avatar.objectNP.setH(self.avatar.yawRot) #Up and down mouse_shift_y = current_mouse_y - self.last_mouse_y self.last_mouse_y = current_mouse_y if current_mouse_y < 5 or current_mouse_y >= ( self.win_center_y * 1.5): base.win.movePointer(0, current_mouse_x, self.win_center_y) self.last_mouse_y = self.win_center_y pitch_shift = -((mouse_shift_y) * Camera.ROT_RATE[1]) self.mainCamera.pitchRot += pitch_shift if self.mainCamera.pitchRot > Camera.FLEX_ROT_BOUND[0]: self.mainCamera.pitchRot = Camera.FLEX_ROT_BOUND[0] elif self.mainCamera.pitchRot < -Camera.FLEX_ROT_BOUND[0]: self.mainCamera.pitchRot = -Camera.FLEX_ROT_BOUND[0] xy_plane_cam_dist = Camera.AVATAR_DIST cam_x_adjust = xy_plane_cam_dist * sin( radians(self.avatar.yawRot)) cam_y_adjust = xy_plane_cam_dist * cos( radians(self.avatar.yawRot)) cam_z_adjust = Camera.ELEVATION self.mainCamera.camObject.setH(self.avatar.yawRot) self.mainCamera.camObject.setP(self.mainCamera.pitchRot) self.mainCamera.camObject.setPos( self.avatar.objectNP.getX() + cam_x_adjust, self.avatar.objectNP.getY() - cam_y_adjust, self.avatar.objectNP.getZ() + cam_z_adjust) #Find collisions self.cTrav.traverse(render) return Task.cont