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 __initCollisions(self): collSphere = CollisionSphere(0, 0, 0, Globals.PlayerCollisionRadius) collSphere.setTangible(0) self.mazeCollisionName = Globals.LocalPlayerCollisionName collNode = CollisionNode(self.mazeCollisionName) collNode.addSolid(collSphere) collNodePath = self.toon.attachNewNode(collNode) collNodePath.hide() handler = CollisionHandlerEvent() handler.addInPattern('%fn-into-%in') base.cTrav.addCollider(collNodePath, handler) self.handler = handler self._collNodePath = collNodePath
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)
class SmartCar(ShowBase): def __init__(self): ShowBase.__init__(self) # Override defaults self.disableMouse() self.setBackgroundColor(VBase3(160, 200, 150) / 255.0) self.setFrameRateMeter(True) # Lights dlight = DirectionalLight("dlight") dlnp = self.render.attachNewNode(dlight) dlnp.setHpr(180.0, -70.0, 0) self.render.setLight(dlnp) alight = AmbientLight("alight") alnp = self.render.attachNewNode(alight) alight.setColor(VBase4(0.4, 0.4, 0.4, 1)) self.render.setLight(alnp) # Collision traverser self.cTrav = CollisionTraverser("collisionTraverser") # Collision handlers self.carCollisionHandler = CollisionHandlerEvent() self.carCollisionHandler.addInPattern("%fn-into-%in") # Camera controls self.cameraController = CameraController(self, 400, math.pi / 4.0, math.pi / 4.0) # Load the track self.track = self.loader.loadModel("models/trackValencia") checkpointsCollision = self.track.find("checkpoints").node() checkpointsCollision.setIntoCollideMask(BitMask32(0xF0)) self.numCheckpoints = checkpointsCollision.getNumSolids() self.track.reparentTo(self.render) # Load the car self.car = NeuralNetworkCar(self) self.cameraController.follow(self.car.getNodePath()) # Reposition the car # self.car.getNodePath().setH(180.0) # Register car collisions with track self.cTrav.addCollider(self.car.carCollider, self.carCollisionHandler) self.accept("carCollider-into-trackCollision", self.car.onCrash) self.accept("carCollider-into-checkpoints", self.car.onCheckpoint)
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 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 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 Game(DirectObject): def __init__(self, showbase, usersData, gameData): DirectObject.__init__(self) self.showbase = showbase self.usersData = usersData self.gameData = gameData random.seed(self.gameData.randSeed) # Initialize the collision traverser. self.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.world = World(showbase) self.ambientLight = showbase.render.attachNewNode( AmbientLight("ambientLight")) # Set the color of the ambient light self.ambientLight.node().setColor((.1, .1, .1, 1)) # add the newly created light to the lightAttrib # showbase.render.setLight(self.ambientLight) self.spotlight = None numberOfPlayers = len(self.usersData) for index, user in enumerate(self.usersData): user.centipede = Centipede(showbase, index, numberOfPlayers, self.addToCollisions) if user.thisPlayer: self.centipede = user.centipede self.centipede.attachRing(showbase) self.spotlight = self.centipede.head.attachNewNode( PointLight("playerSpotlight")) self.spotlight.setPos(LVector3(0, 0, 8)) # Now we create a spotlight. Spotlights light objects in a given cone # They are good for simulating things like flashlights self.spotlight.node().setAttenuation( LVector3(.025, 0.0005, 0.0001)) self.spotlight.node().setColor((0.35, 0.35, .35, 1)) self.spotlight.node().setSpecularColor((0.01, 0.01, 0.01, 1)) showbase.render.setLight(self.spotlight) self.perPixelEnabled = True self.shadowsEnabled = True #if self.spotlight: # self.spotlight.node().setShadowCaster(True, 512, 512) showbase.render.setShaderAuto() self.foods = [] for i in range(self.gameData.maxFoods): self.foods.append(Food(self.showbase, i, self.addToCollisions)) def destroy(self): self.ignoreAll() self.collHandEvent.clear() self.ambientLight.removeNode() if self.spotlight: self.showbase.render.clearLight(self.spotlight) self.spotlight.removeNode() self.world.destroy() for user in self.usersData: user.centipede.destroy() for food in self.foods: food.destroy() def runTick(self, dt, tick): # run each of the centipedes simulations for user in self.usersData: user.centipede.update(dt) headPosition = user.centipede.head.getPos() if abs(headPosition.x) > 123 or abs(headPosition.y) > 123: user.centipede.reset() if len(user.centipede.body) > 10: return False for food in self.foods: food.update(dt) self.cTrav.traverse(self.showbase.render) # Return true if game is still not over (false to end game) return True def collideInto(self, collEntry): print "collide into" fromInto = collEntry.getFromNodePath().node().getIntoCollideMask() intoInto = collEntry.getIntoNodePath().node().getIntoCollideMask() fromIntoIndex = fromInto.getLowestOnBit() - 1 intoIntoIndex = intoInto.getLowestOnBit() - 1 # Collision was with a Food! if intoIntoIndex == -1: # TODO: Get food better for food in self.foods: if collEntry.getIntoNodePath() == food.model.collisionNode[0]: user = self.usersData[fromIntoIndex] user.centipede.addLength(self.showbase) food.reset() print "om nommed a food" return # Centipede eating themself if fromIntoIndex == intoIntoIndex: print "hitting self" user = self.usersData[fromIntoIndex] if len(user.centipede.body) > 2: if collEntry.getIntoNodePath( ) == user.centipede.tail.collisionNode[0]: user.centipede.reset() print "dieded self tail" return for i in range(len(user.centipede.body) - 1 - 2): if collEntry.getIntoNodePath() == user.centipede.body[ i + 2].collisionNode[0]: user.centipede.reset() print "dieded self body", i return else: # TODO: Check for both heads # if bothHeads: # one will survive if it's angle to the other node is greater than 90degrees from straight ahead # Centipede eating another centipede crasher = self.usersData[fromIntoIndex] crasher.centipede.reset() # Give crashee a point on behalf of crasher crashee = self.usersData[intoIntoIndex] print "Player", intoIntoIndex, " gets a point!" # crashee.point += 1 def addToCollisions(self, item): # Add this object to the traverser. self.cTrav.addCollider(item[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + str(item[1]), self.collideInto)
class CogdoMazeLocalPlayer(CogdoMazePlayer): notify = directNotify.newCategory('CogdoMazeLocalPlayer') def __init__(self, id, toon, game, guiMgr): CogdoMazePlayer.__init__(self, id, toon) self.disableGagCollision() self.game = game self.maze = self.game.maze self._guiMgr = guiMgr self.cameraMgr = CogdoMazeCameraManager(self.toon, self.maze, camera, render) self._proximityRadius = self.maze.cellWidth * Globals.CameraRemoteToonRadius orthoDrive = OrthoDrive( Globals.ToonRunSpeed, maxFrameMove=self.maze.cellWidth / 2, customCollisionCallback=self.maze.doOrthoCollisions, wantSound=True) self.orthoWalk = OrthoWalk(orthoDrive) self._audioMgr = base.cogdoGameAudioMgr self._getMemoSfx = self._audioMgr.createSfx('getMemo', source=self.toon) self._waterCoolerFillSfx = self._audioMgr.createSfx('waterCoolerFill', source=self.toon) self._hitByDropSfx = self._audioMgr.createSfx('toonHitByDrop', source=self.toon) self._winSfx = self._audioMgr.createSfx('win') self._loseSfx = self._audioMgr.createSfx('lose') self.enabled = False self.pickupCount = 0 self.numEntered = 0 self.throwPending = False self.coolDownAfterHitInterval = Sequence( Wait(Globals.HitCooldownTime), Func(self.setInvulnerable, False), name='coolDownAfterHitInterval-%i' % self.toon.doId) self.invulnerable = False self.gagHandler = CollisionHandlerEvent() self.gagHandler.addInPattern('%fn-into-%in') self.exited = False self.hints = { 'find': False, 'throw': False, 'squashed': False, 'boss': False, 'minion': False } self.accept('control', self.controlKeyPressed) def destroy(self): self.toon.showName() self.ignoreAll() self.coolDownAfterHitInterval.clearToInitial() del self.coolDownAfterHitInterval del self._getMemoSfx del self._waterCoolerFillSfx del self._hitByDropSfx del self._winSfx self.orthoWalk.stop() self.orthoWalk.destroy() del self.orthoWalk CogdoMazePlayer.destroy(self) def __initCollisions(self): collSphere = CollisionSphere(0, 0, 0, Globals.PlayerCollisionRadius) collSphere.setTangible(0) self.mazeCollisionName = Globals.LocalPlayerCollisionName collNode = CollisionNode(self.mazeCollisionName) collNode.addSolid(collSphere) collNodePath = self.toon.attachNewNode(collNode) collNodePath.hide() handler = CollisionHandlerEvent() handler.addInPattern('%fn-into-%in') base.cTrav.addCollider(collNodePath, handler) self.handler = handler self._collNodePath = collNodePath def clearCollisions(self): self.handler.clear() def __disableCollisions(self): self._collNodePath.removeNode() del self._collNodePath def _isNearPlayer(self, player): return self.toon.getDistance(player.toon) <= self._proximityRadius def update(self, dt): if self.getCurrentOrNextState() != 'Off': self._updateCamera(dt) def _updateCamera(self, dt): numPlayers = 0.0 for player in self.game.players: if player != self and player.toon and self._isNearPlayer(player): numPlayers += 1 d = clamp( Globals.CameraMinDistance + numPlayers / (CogdoGameConsts.MaxPlayers - 1) * (Globals.CameraMaxDistance - Globals.CameraMinDistance), Globals.CameraMinDistance, Globals.CameraMaxDistance) self.cameraMgr.setCameraTargetDistance(d) self.cameraMgr.update(dt) def enterOff(self): CogdoMazePlayer.enterOff(self) def exitOff(self): CogdoMazePlayer.exitOff(self) self.toon.hideName() def enterReady(self): CogdoMazePlayer.enterReady(self) self.cameraMgr.enable() def exitReady(self): CogdoMazePlayer.enterReady(self) def enterNormal(self): CogdoMazePlayer.enterNormal(self) self.orthoWalk.start() def exitNormal(self): CogdoMazePlayer.exitNormal(self) self.orthoWalk.stop() def enterHit(self, elapsedTime=0.0): CogdoMazePlayer.enterHit(self, elapsedTime) self.setInvulnerable(True) def exitHit(self): CogdoMazePlayer.exitHit(self) self.coolDownAfterHitInterval.clearToInitial() self.coolDownAfterHitInterval.start() def enterDone(self): CogdoMazePlayer.enterDone(self) self._guiMgr.hideQuestArrow() self.ignore('control') self._guiMgr.setMessage('') if self.exited == False: self.lostMemos() def exitDone(self): CogdoMazePlayer.exitDone(self) def hitByDrop(self): if self.equippedGag is not None and not self.hints['squashed']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeSquashHint, Globals.HintTimeout) self.hints['squashed'] = True self._hitByDropSfx.play() CogdoMazePlayer.hitByDrop(self) return def equipGag(self): CogdoMazePlayer.equipGag(self) self._waterCoolerFillSfx.play() messenger.send(Globals.WaterCoolerHideEventName, []) if not self.hints['throw']: self._guiMgr.setMessage(TTLocalizer.CogdoMazeThrowHint) self.hints['throw'] = True def hitSuit(self, suitType): if suitType == Globals.SuitTypes.Boss and not self.hints['boss']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeBossHint, Globals.HintTimeout) self.hints['boss'] = True if suitType != Globals.SuitTypes.Boss and not self.hints['minion']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeMinionHint, Globals.HintTimeout) self.hints['minion'] = True def createThrowGag(self, gag): throwGag = CogdoMazePlayer.createThrowGag(self, gag) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = Globals.GagCollisionName collNode = CollisionNode(name) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = throwGag.attachNewNode(collNode) base.cTrav.addCollider(colNp, self.gagHandler) return throwGag def showToonThrowingGag(self, heading, pos): self._guiMgr.clearMessage() return CogdoMazePlayer.showToonThrowingGag(self, heading, pos) def removeGag(self): if self.equippedGag is None: return CogdoMazePlayer.removeGag(self) self.throwPending = False messenger.send(Globals.WaterCoolerShowEventName, []) return def controlKeyPressed(self): if self.game.finished or self.throwPending or self.getCurrentOrNextState( ) == 'Hit' or self.equippedGag == None: return self.throwPending = True heading = self.toon.getH() pos = self.toon.getPos() self.game.requestUseGag(pos.getX(), pos.getY(), heading) return def completeThrow(self): self.clearCollisions() CogdoMazePlayer.completeThrow(self) def shakeCamera(self, strength): self.cameraMgr.shake(strength) def getCameraShake(self): return self.cameraMgr.shakeStrength def setInvulnerable(self, bool): self.invulnerable = bool def handleGameStart(self): self.numEntered = len(self.game.players) self.__initCollisions() self._guiMgr.startGame(TTLocalizer.CogdoMazeFindHint) self.hints['find'] = True self.notify.info( 'toonId:%d laff:%d/%d %d player(s) started maze game' % (self.toon.doId, self.toon.hp, self.toon.maxHp, len(self.game.players))) def handleGameExit(self): self.cameraMgr.disable() self.__disableCollisions() def handlePickUp(self, toonId): if toonId == self.toon.doId: self.pickupCount += 1 self._guiMgr.setPickupCount(self.pickupCount) if self.pickupCount == 1: self._guiMgr.showPickupCounter() self._getMemoSfx.play() def handleOpenDoor(self, door): self._guiMgr.setMessage(TTLocalizer.CogdoMazeGameDoorOpens) self._guiMgr.showQuestArrow(self.toon, door, Point3(0, 0, self.toon.getHeight() + 2)) def handleTimeAlert(self): self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameTimeAlert) def handleToonRevealsDoor(self, toonId, door): if toonId == self.toon.doId: self._guiMgr.setMessageTemporary( TTLocalizer.CogdoMazeGameLocalToonFoundExit) def handleToonEntersDoor(self, toonId, door): self.exited = True message = '' if door.getPlayerCount() < len(self.game.players): message = TTLocalizer.CogdoMazeGameWaitingForToons if toonId == self.toon.doId: self._guiMgr.setMessage(message) self._winSfx.play() self._audioMgr.stopMusic() self.notify.info( 'toonId:%d laff:%d/%d %d player(s) succeeded in maze game. Going to the executive suit building.' % (toonId, self.toon.hp, self.toon.maxHp, len(self.game.players))) if self.numEntered > len(self.game.players): self.notify.info('%d player(s) failed in maze game' % (self.numEntered - len(self.game.players))) def lostMemos(self): self.pickupCount = 0 self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameTimeOut) self._guiMgr.setPickupCount(self.pickupCount) self.notify.info( 'toonId:%d laff:%d/%d %d player(s) failed in maze game' % (self.toon.doId, self.toon.hp, self.toon.maxHp, len(self.game.players)))
class World(DirectObject): def __init__(self): #--Collision Handler------------------------------------------------------ self.collHandler = CollisionHandlerEvent() self.collHandler.addInPattern('%fn-into-%in') base.cTrav = CollisionTraverser('world traverser') #--Mouse Control---------------------------------------------------------- base.disableMouse() self.properties = WindowProperties() self.properties.setCursorHidden(True) base.win.requestProperties(self.properties) #--Register Hud Elements-------------------------------------------------- self.instruction1 = self.addInstruction("[click] to Shoot", 2) self.instruction2 = self.addInstruction("[a] to accelerate", 1) self.instruction3 = self.addInstruction("[esc] to quit", 0) self.scoreHud = self.addHudElement("", 0) self.accuracy = self.addHudElement("", 1) self.speedHud = self.addHudElement("", 2) self.bigHud = OnscreenText(text="", style=1, fg=(1, 1, 1, 1), pos=(0, 0), align=TextNode.ACenter, scale=.1) #--Load Objects and Models------------------------------------------------ self.ship = Ship(self.collHandler) self.loadSkyBox() game.camera.reparentTo(self.ship.getModel()) #--Start Game------------------------------------------------------------- self.asteroids = [] self.resetGame() #--Controls -------------------------------------------------------------- self.keysDown = {'a': 0} self.controlTask = taskMgr.add(self.gameLoop, "game-control-task") self.controlTask.lastTime = 0 self.accept("escape", sys.exit, [0]) self.accept("a", self.keyDown, ['a']) self.accept("a-up", self.keyUp, ['a']) self.accept("mouse1", self.shoot) self.accept("space", self.shoot) self.accept("resetgame", self.gameOver) if (DEBUG_CONTROLS): self.accept("0", self.ship.stop) self.accept("9", self.ship.getModel().setHpr, [0, 0, 0]) #--Register CollisionEvent Handlers--------------------------------------- self.accept('asteroid-into-bullet', self.bulletAsteroidCollision) ### # World.shoot: # # Dispatch method that overloads the use of the mouse button ## def shoot(self): if (self.ship.isAlive()): self.ship.fireBullet() self.shots += 1 else: self.resetGame() ### # World.gameOver() # # Displays "Game Over: <SCORE>" then resets game after 5 seconds def gameOver(self): self.bigHud.setText("GAME OVER: " + str(self.score)) taskMgr.doMethodLater(GAME_OVER_DELAY, self.resetGame, "reset_game", []) ### # World.resetGame # # Resets anything that might change during play essentially reloading ## def resetGame(self): for asteroid in self.asteroids: asteroid.remove() self.score = 0 self.shots = 0 self.hits = 0 self.lifeLength = 0 self.ship.reset() self.scoreHud.setText("Score : " + str(self.score)) self.accuracy.setText("Hit/Fired : 0/0") self.speedHud.setText("Speed : 0") self.bigHud.setText("") self.loadAsteroids() ### # World.bulletAsteroidCollision: # # Event Handler for collision From Asteroid Into Bullet # Triggers the "explosion" of an Asteroid and appends replacments ## def bulletAsteroidCollision(self, entry): bullet = entry.getIntoNodePath().getParent().getPythonTag("owner") asteroid = entry.getFromNodePath().getParent().getPythonTag("owner") self.ship.removeBullet(bullet) self.asteroids.extend(asteroid.registerHit()) self.asteroids.remove(asteroid) self.score += 100 self.hits += 1 asteroid.remove() ### # World.keyDown: # # Register the given key as being held down ## def keyDown(self, key): self.keysDown[key] = 1 ### # World.keyUp: # # Register the given key as no longer being held down ## def keyUp(self, key): self.keysDown[key] = 0 ### # World.addHudElement(msg, row) # # Displays the given string msg in the top left with a row offset of row ## def addHudElement(self, msg, row): return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-1.3, .95 - (.05 * row)), align=TextNode.ALeft, scale=.05) ### # World.addInstruction(msg, row) # # Displays the given string msg in the top right with a row offset of row ## def addInstruction(self, msg, row): return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(1.3, .95 - (.05 * row)), align=TextNode.ARight, scale=.05) ### # World.loadSkyBox: # # Helper method that loads the skybox, sets size and other factors and # parents to ship, while keeping a compass effect so it will spin around the # ship ## def loadSkyBox(self): self.skybox = game.loader.loadModel("Models/skybox.egg") self.skybox.setScale(100.0, 100.0, 100.0) self.skybox.setPos(0, 0, 0) self.skybox.reparentTo(self.ship.getModel()) # Roots the skybox with relation to the render node, making it stationary # even though its parented to the ship self.skybox.setEffect(CompassEffect.make(render, CompassEffect.PRot)) ### # gameLoop # # Task for managing the input from the mouse and keys. In addition updating # the game world. ## def gameLoop(self, task): md = base.win.getPointer(0) x = md.getX() y = md.getY() # Get the delta in time since last frame (allows us to ratelimit rotation # and acceleration dt = task.time - task.lastTime task.lastTime = task.time self.lifeLength += dt # Calculate how far the mouse moved, generate a rotation offest and send # to the ship to rotate if base.win.movePointer(0, MOUSE_OFFSET, MOUSE_OFFSET): self.ship.rotate( Vec3(-((x - MOUSE_OFFSET) * ROTATION_RATE), INVERTED_MOUSE * ((y - MOUSE_OFFSET) * ROTATION_RATE), 0)) #--Allows Holding of A key------------------------------------------------ if (self.keysDown['a'] == 1): self.ship.accelerate(dt) #--Update Asteroid Positions---------------------------------------------- for asteroid in self.asteroids: asteroid.updatePos(dt) #--Update HUD------------------------------------------------------------- if (self.shots != 0): self.accuracy.setText("Hit/Fired : " + str(self.hits) + "/" + str(self.shots)) self.scoreHud.setText("Score : " + str(self.score)) self.speedHud.setText("Speed : " + str(self.ship.getVel())) return Task.cont ### # World.loadAsteroids # # Helper method for creating the asteroids ## def loadAsteroids(self): self.asteroids = [] for i in range(ASTEROID_START_COUNT): x = choice([-1, 1]) * choice( range(ASTEROID_SPAWN_MIN, ASTEROID_SPAWN_MAX)) y = choice([-1, 1]) * choice( range(ASTEROID_SPAWN_MIN, ASTEROID_SPAWN_MAX)) z = choice([-1, 1]) * choice( range(ASTEROID_SPAWN_MIN, ASTEROID_SPAWN_MAX)) self.asteroids.append(Asteroid(Vec3(x, y, z), self.collHandler))
class Game: def __init__(self, base, game_quit_cb): self.base = base self.game_quit_cb = game_quit_cb def run(self, root_node, restart_scene_cb): self.restart_scene_cb = restart_scene_cb self.root_node = root_node self.base.accept("escape", sys.exit) # Escape quits self.base.camera.set_pos(0, 0, 90) self.base.camera.set_hpr(0, -90, 0) self.score = Scores(self.game_end, self.game_quit_cb, self.restart_game) self.game_ended = False lens = OrthographicLens() lens.set_film_size(40 * win_aspect, 40) self.base.cam.node().setLens(lens) self.gc = GameControls(self.base, self.move_player, mouse_magnitude=7) self.base.disable_mouse() # debug camera movement # self.fm = FlyMove(self) # self.camera.set_pos(-20, 0, 10) # self.camera.set_hpr(-90, -50, 0) self.base.cTrav = CollisionTraverser() self.coll_hand_event = CollisionHandlerEvent() self.coll_hand_event.addInPattern('into-%in') paddle_path = 'models/paddle' self.player_paddle = pp = self.load_and_render(paddle_path) pp.set_pos(-20, 0, 0) pp.set_hpr((90, 0, 0)) self.ai_paddle = aip = self.load_and_render(paddle_path, copy=True) aip.set_pos(20, 0, 0) aip.set_hpr((90, 0, 0)) self.ball = self.load_and_render('models/ball') collision_ball = CollisionSphere(0, 0, 0, 1) cnodePath = self.ball.attachNewNode(CollisionNode('ball')) cnodePath.node().addSolid(collision_ball) self.base.cTrav.add_collider(cnodePath, self.coll_hand_event) # ball movement self.reset_ball() self.ball_speed_scale = 0.30 self.base.task_mgr.add(self.ball_move_task, 'ball-move') # set up boundaries on the top and bottom self.border_distance = border_distance = 20 self.top_boundary = self.load_and_render(paddle_path, copy=True) self.top_boundary.set_sx(5) self.top_boundary.set_y(border_distance) self.bottom_boundary = self.load_and_render(paddle_path, copy=True) self.bottom_boundary.set_sx(5) self.bottom_boundary.set_y(-1 * border_distance) horizontal_distance = 30 self.player_side_plane = CollisionPlane( Plane(LVector3f(1, 0, 0), LPoint3f(-1 * horizontal_distance, 0, 0))) self.player_side_cnode = self.root_node.attachNewNode( CollisionNode('pplane')) self.player_side_cnode.node().add_solid(self.player_side_plane) self.ai_side_plane = CollisionPlane( Plane(LVector3f(-1, 0, 0), LPoint3f(horizontal_distance, 0, 0))) self.ai_side_cnode = self.root_node.attachNewNode( CollisionNode('aiplane')) self.ai_side_cnode.node().add_solid(self.ai_side_plane) # add collision to paddles and walls, everything the ball can reflect off of for np in [pp, aip, self.bottom_boundary, self.top_boundary]: cs = CollisionBox((0, 0, 0), 5, 0.25, 8) cnodePath = np.attachNewNode(CollisionNode('wall')) cnodePath.node().addSolid(cs) self.base.cTrav.add_collider(cnodePath, self.coll_hand_event) self.base.accept('into-wall', self.ball_collision) self.base.accept('into-pplane', self.player_side_goal) self.base.accept('into-aiplane', self.ai_side_goal) self.ai = PongAI(self.base, self.ai_paddle, self.ball, border_distance) def game_end(self): self.game_ended = True self.base.task_mgr.remove("ball-move") self.gc.stop() self.ai.stop() def player_side_goal(self, entry): self.score.ai_scored() self.reset_ball() def ai_side_goal(self, entry): self.score.player_scored() self.reset_ball() def restart_game(self): self.restart_scene_cb() def reset_ball(self): if self.game_ended: return side = randint(0, 1) angle = randint(0, 90) angle += side * 180 # possibly flip which player it's going to angle = (angle - 45) * (pi / 180) self.ai_paddle.set_y(0) self.player_paddle.set_y(0) self.ball_v = LVector3f(cos(angle), sin(angle), 0) self.ball.set_pos((0, 0, 0)) def ball_collision(self, entry): norm = entry.get_surface_normal(self.root_node) * -1 in_vec = self.ball_v / self.ball_v.length() self.ball_v = (norm * norm.dot(in_vec * -1) * 2) + in_vec def ball_move_task(self, task): self.ball.set_pos(self.ball.get_pos() + self.ball_v * self.ball_speed_scale) return task.cont def load_and_render(self, model_path, copy=False): if copy: model = self.base.loader.loadModelCopy(model_path) else: model = self.base.loader.loadModel(model_path) model.reparent_to(self.root_node) return model def move_player(self, dy): self.player_paddle.set_y( max(-1 * self.border_distance, min(self.border_distance, self.player_paddle.get_y() + dy)))
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 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
if status == 'up': pickingEnabledOject.setScale(1.0) #** 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:
class SillyWorld(DirectObject): def __init__(self): # start Panda3d base = ShowBase() # CollisionTraverser instance must be attached to base, # and must be called cTrav base.cTrav = CollisionTraverser() self.cHand = CollisionHandlerEvent() self.cHand.addInPattern('into-%in') # load smiley, which we will control # notice this is a little trickery. If we parent everything except smiley # to the camera, and the player is controlling the camera, then everything # stays fixed in the same place relative to the camera, and when the camera # moves, the player is given the illusion that he is moving smiley, rather than # the camera and the rest of the scene. self.smiley = base.loader.loadModel('smiley') self.smiley.reparentTo(render) self.smiley.setName('Smiley') # Setup a collision solid for this model. Our initCollisionSphere method returns # the cNodepath and the string representing it. We will use the cNodepath for # adding to the traverser, and the string to accept it for event handling. #sColl = self.initCollisionSphere(self.smiley) sColl = self.initCollisionSphere(self.smiley, True) print 'smiley', sColl[0] print 'smiley', sColl[1] # Add this object to the traverser. base.cTrav.addCollider(sColl[0], self.cHand) # load frowney self.frowney = base.loader.loadModel('frowney') self.frowney.setName('Frowney') self.frowney.reparentTo(camera) # Setup a collision solid for this model. fColl = self.initCollisionSphere(self.frowney, True) #print 'frowney', fColl[0] #print 'frowney', fColl[1] # Add this object to the traverser. base.cTrav.addCollider(fColl[0], self.cHand) # Accept the events sent by the collisions. # smiley is the object we are 'moving', so by convention # it is the from object. # If we instead put smiley as the into object here, # it would work fine, but then smiley would disappear # when we collided them. self.accept('into-' + fColl[1], self.collide) # set the initial positions of smiley and frowney self.set_initial_positions() def set_initial_positions(self): self.smiley.setPos(0, 25, 0) self.frowney.setPos(5, 25, 0) def collide(self, collEntry): #print('collision') #print collEntry.getIntoNodePath().getParent() collEntry.getIntoNodePath().getParent().stash() #print self.frowney.isStashed() # if instead of making frowney disappear, you wanted to # change some aspect of one or both colliding objects, # you could do soemthing like this: colliderFROM = collEntry.getFromNodePath().getParent() #colliderINTO = collEntry.getIntoNodePath().getParent() # Note that for it to work, you have to # we now may change the aspect of the two colliding objects #colliderINTO.setColor(1,1,1,1) colliderFROM.setScale(1.5) def initCollisionSphere(self, obj, show=False): # Get the size of the object for the collision sphere. bounds = obj.getChild(0).getBounds() center = bounds.getCenter() # We are making our radius bigger than our object. It will look strange # if we don't show the collision sphere, because frowney will disappear # before the objects appear to touch, but this shows you how you can # change the sphere separately from the actual object. Of course, you # can make it the same size as the object if you want. radius = bounds.getRadius() * 1.1 # Create a collision sphere and name it something understandable. collSphereStr = 'CollisionHull' + "_" + obj.getName() 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 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 MyApp(ShowBase): def center_mouse(self): self.win.movePointer(0,self.win.getXSize()/2,self.win.getYSize()/2) def __init__(self): #Game variables self.health = 100 self.panda_kill_count = 0 self.level = 0 #Implementation variables #self.color = [Vec4((204.0/255), (255.0/255), (204/255), 0.1),Vec4((0/255), (255.0/255), (255.0/255), 0.1),Vec4((255.0/255), (51.0/255), (255.0/255), 0.1),Vec4((153.0/255), (255.0/255), (153.0/255), 0.1),Vec4((255.0/255), (178.0/255), (102.0/255), 0.1),Vec4((229.0/255), (204.0/255), (255.0/255), 0.1)] self.color = [Vec4(0.4,0.4,0.4,0.1)] self.mirror=False self.paused=False self.displayed=False self.game_started=False self.randomthings_ = randomthings.RandomThings(self) self.shifted_cam=False self.is_firstP=False self.old_anim2 = None self.old_anim=None self.timeout=False (self.r,self.f,self.b,self.l)=(0,0,0,0) self.inside_level=False self.move_anim_queue=[] self.anim_queue=[] self.prev_time=0.0 self.bullets = [] self.rightspeed=0 self.forwardspeed=0 ShowBase.__init__(self) self.makeDefaultPipe() bb=self.pipe.getDisplayHeight() aa=self.pipe.getDisplayWidth() self.openDefaultWindow(size=(aa, bb)) import layer2d self.layer2d = layer2d self.layer2d.update_info('Loading...') self.keyreader= ReadKeys(self,layer2d) #Sounds self.gunshot = self.loader.loadSfx("sounds/gunshot_se.ogg") self.gunshot.setLoop(False) self.music = self.loader.loadSfx("sounds/music.ogg") self.music.setLoop(True) self.zombie_die = self.loader.loadSfx('sounds/zombie_die.ogg') self.zombie_die.setLoop(False) self.kicked = self.loader.loadSfx('sounds/kicked.ogg') self.kicked.setLoop(False) self.hurt_sound = self.loader.loadSfx('sounds/hurt.ogg') self.hurt_sound.setLoop(False) self.dead_sound = self.loader.loadSfx('sounds/dead.ogg') self.dead_sound.setLoop(False) self.intro_sound = self.loader.loadSfx('sounds/intro.ogg') self.intro_sound.setLoop(False) self.intro_sound.play() self.enableParticles() self.center_mouse() #self.disableMouse() self.prev_pos = None if base.mouseWatcherNode.hasMouse(): x=base.mouseWatcherNode.getMouseX() y=base.mouseWatcherNode.getMouseY() self.prev_pos = (x,y) #Hide cursor props = WindowProperties() props.setCursorHidden(True) self.win.requestProperties(props) self.environ = self.loader.loadModel('models/ourworld') self.environ.setPos(0,0,0) self.environ.reparentTo(self.render) self.pandaActor = Actor("models/hero_anim", {'kick':'models/hero_anim-kick','unready_to_shoot':'models/hero_anim-unready_to_shoot','jump':'models/hero_anim-jump',"shooting":"models/hero_anim-shooting","ready_to_shoot":"models/hero_anim-ready_to_shoot","ready_to_walk":"models/hero_anim-ready_to_run","ready_to_run":"models/hero_anim-ready_to_run","walk4":"models/hero_anim-walk1", "breathe": "models/hero_anim-breathe", "run": "models/hero_anim-walk"}) self.pandaActor.setPlayRate(3,'ready_to_shoot') self.pandaActor.setPlayRate(-1.0,"ready_to_walk") self.pandaActor.setPlayRate(1.5,'run') self.pandaActor.setPlayRate(1.5,'ready_to_run') self.pandaActor.reparentTo(self.render) self.pandaActor.setPos(self.environ,0,0,100) self.pandaActor.loop("breathe") self.phy = NodePath("PhysicsNode") self.phy.reparentTo(self.render) self.pandaAN = ActorNode("PandaActor") self.pandaActorPhysicsP = self.phy.attachNewNode(self.pandaAN) self.physicsMgr.attachPhysicalNode(self.pandaAN) self.pandaActor.reparentTo(self.pandaActorPhysicsP) #set mass of panda self.pandaAN.getPhysicsObject().setMass(100) #apply gravity self.gravityFN=ForceNode('world-forces') self.gravityFNP=self.environ.attachNewNode(self.gravityFN) self.gravityForce=LinearVectorForce(0,0,-30.81) #gravity acceleration self.gravityFN.addForce(self.gravityForce) self.physicsMgr.addLinearForce(self.gravityForce) #camera stuff self.camera.reparentTo(self.pandaActor) self.camera.lookAt(self.pandaActor) self.taskMgr.add(self.spinCameraTask, "zombieTask_SpinCameraTask") self.taskMgr.doMethodLater(0.01,self.movePandaTask,"zombieTask_movePandaTask") #Collision Handling self.cTrav = CollisionTraverser() self.collisionHandler = CollisionHandlerEvent() #Add collider for terrain self.groundCollider = self.environ.find("**/terrain") #Add walker for panda self.collision_sphere = CollisionSphere(0,0,1,1) self.collNode = CollisionNode('pandaWalker') self.cnodePath = self.pandaActor.attachNewNode(self.collNode) self.cnodePath.node().addSolid(self.collision_sphere) #AddZombieDetector for panda self.zombie_sphere = CollisionSphere(0,0,3,1) self.zomb_detector_node = CollisionNode('zombieDetector') self.zomb_detector_NP = self.pandaActor.attachNewNode(self.zomb_detector_node) self.zomb_detector_NP.node().addSolid(self.zombie_sphere) #self.zomb_detector_NP.show() #Add pusher against gravity self.pusher = PhysicsCollisionHandler() self.pusher.addCollider(self.cnodePath, self.pandaActorPhysicsP) self.pusher.addCollider(self.zomb_detector_NP,self.pandaActorPhysicsP) self.cTrav.addCollider(self.cnodePath,self.pusher) self.cTrav.addCollider(self.zomb_detector_NP,self.pusher) self.pusher.addInPattern('%fn-into-%in') self.pusher.addAgainPattern('%fn-again-%in') #Add collision handler patterns self.collisionHandler.addInPattern('%fn-into-%in') self.collisionHandler.addAgainPattern('%fn-again-%in') self.abientLight = AmbientLight("ambientLight") self.abientLight.setColor(Vec4(0.1, 0.1, 0.1, 1)) self.directionalLight = DirectionalLight("directionalLight") self.directionalLight.setDirection(Vec3(-5, -5, -5)) self.directionalLight.setColor(Vec4((229.0/255), (204.0/255), (255.0/255), 0.7)) self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1)) self.directionalLight.setShadowCaster(True,512,512) self.render.setLight(self.render.attachNewNode(self.abientLight)) self.render.setLight(self.render.attachNewNode(self.directionalLight)) self.render.setShaderAuto() #create zombie land self.zombieland = zombie.Zombies(self) self.taskMgr.doMethodLater(0.01,self.zombieland.moveZombie, "zombieTask_ZombieMover") layer2d.incBar(self.health) self.taskMgr.add(self.game_monitor,"zombieTask_gameMonitor") self.taskMgr.doMethodLater(2.7,self.music_play, "zombieTask_music") #Add random useless things: self.randomthings_.add_random_things() def music_play(self,task): self.music.play() return Task.done #def get_color(self): # return self.color[min(len(self.color)-1,self.level)] #GameMonitor def game_monitor(self,task): if self.paused: return Task.cont #Update Score self.layer2d.update_score(self.panda_kill_count) #Check for health of actor if self.health <= 0: self.dead_sound.play() self.pandaActor.detachNode() print "LOL u ded" self.info = """Game Over.. Score: """ + str(self.panda_kill_count) + """ Press alt+f4 to quit the game. """ self.layer2d.update_info(self.info) self.taskMgr.removeTasksMatching('zombieTask_*') if self.game_started<>True: if not self.displayed: self.display_information() self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100))) return Task.cont #Check if user is inside some level. if yes, pass. if self.inside_level or self.timeout: return Task.cont self.inside_level = True #self.health=100 self.timeout=True print ".." #The next lines will be executed only when the user is in between two levels (or at the beginning of the game) #Display information based on game level self.display_information() print "HUEHUEHUEHUE" #Schedule wave of zombies self.taskMgr.doMethodLater(10,self.addWave, "zombieTask_ZombieAdder") return Task.cont def addWave(self,task): ##add a wave of 5 zombies, depending on the level. ##speed of zombie increases with each level ##durability of zombie increases with each level. ##Wave ends when all zombies die. self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1)) self.layer2d.update_info("level"+str(self.level)) self.timeout=False self.zombieland.add(5) return Task.done #information displayer def display_information(self): #display information based on levels. print self.game_started self.displayed=True if self.game_started==False: info = """ Welcome to PandaLand. Once upon a time, there used to be these cute little creatures called Pandas. They were lazy, funny, and adorable. But that is what we humans thought. Pandas are actually an evil alien race that spread from planet to planet, spreading destruction and terror everywhere. They ruled earth several billion years ago. But our super ancestors (Dinosaurs) fought agaisnt them with great valour and selflessness; and managed to save planet Earth from doom. But the pandas went into hiding (and became cute); until few days back! Now they seek to kill all. You, the Joker, are our only hope,since Batman has retired. Go Kill Pandas.For Mother Earth! """ self.layer2d.information['bg'] = (0,0,0,0.8) else: self.layer2d.update_info('') if self.level==0: info=""" Your game will start in a few seconds. This is the first level. Pandas will spawn and follow you. Shoot to kill. Test out your controls while they are still cute and harmless :) Jump: Space Shoot: LeftClick Kick: RightClick Walk: A/W/S/D For more information, press P. """ self.layer2d.information['bg'] = (0,0,0,0.6) elif self.level==1: info=""" Level 0 Completed! Starting Level 1. Pandas have turned evil and stronger. They will try to eat you up. To run: Press Shift + A/S/W/D """ elif self.level==2: info=""" Level 1 Completed! Starting Level 2. Pandas are even stronger now. They will get stronger by each level. Your automatic shooting speed has also improved due to experience gained. """ elif self.level==3: info=""" Level 2 Completed! Starting Level 3. Pandas also move faster by each level. They really want to eat you. But don't worry, you also run faster as the levels proceed. """ else: info = """ Level """ + str(self.level-1) + """ Completed! Starting """ + str(self.level) + """ . Well done! Keep fighting, our fate lies in your hands. """ self.layer2d.update_info(info) #self.create_bullet() def create_bullet(self): self.bullet = self.loader.loadModel('models/gun/bullet') self.gunshot.play() self.bulletAN = ActorNode("BulletNode") self.bulletActorPhysicsP = self.phy.attachNewNode(self.bulletAN) self.physicsMgr.attachPhysicalNode(self.bulletAN) self.bullet.reparentTo(self.bulletActorPhysicsP) self.bulletAN.getPhysicsObject().setMass(1) self.bullet.setPos(self.pandaActor,0,-3,3.5) self.bullet.setScale(0.1,0.1,0.1) self.bullet.setHpr(self.pandaActor,0,90,0) self.bullet.setP(self.camera.getP()+90) self.bullet_sphere = CollisionSphere(0,0,0,0.2) self.bullet_collNode = CollisionNode('bullet') self.bullet_cnodePath = self.bullet.attachNewNode(self.bullet_collNode) self.bullet_cnodePath.node().addSolid(self.bullet_sphere) #self.pusher.addCollider(self.bullet_cnodePath,self.bulletActorPhysicsP) self.cTrav.addCollider(self.bullet_cnodePath,self.collisionHandler) #self.bullet_cnodePath.show() self.bullets += [self.bullet] def bulletKiller(self,task): if self.paused: return Task.cont self.bullets[0].remove_node() self.bullets = self.bullets[1:] return Task.done def bulletThrower(self,task): if self.paused: return Task.cont #make bullet move if self.pandaActor.getCurrentAnim()<>'shooting' and self.pandaActor.getCurrentAnim()<>'ready_to_shoot': self.pandaActor.play('shooting') print "loL" self.create_bullet() self.bulletAN.getPhysicsObject().setVelocity(self.render.getRelativeVector(self.camera,Vec3(0,200,0))) self.taskMgr.doMethodLater(max(0.05,0.1*(5-self.level)),self.bulletThrower, "zombieTask_bulletThrower") self.taskMgr.doMethodLater(0.5,self.bulletKiller, "zombieTask_bulletKiller") self.prev=True if self.old_anim2==None: self.old_anim2='breathe' if self.old_anim2 not in ['run','walk4']: self.old_anim2='breathe' self.anim_queue = [(self.pandaActor,True,'unready_to_shoot'),(self.pandaActor,False,self.old_anim2)] return Task.done def movePandaTask(self,task): if self.paused: return Task.cont tempos = self.pandaActor.getPos() speed = 0.1 if self.run_: speed+=0.3*self.level self.rightspeed = -(self.r-self.l)*speed self.forwardspeed = -(self.f-self.b)*speed if (self.r-self.l)<>0 and (self.f-self.b)<>0: #print self.forwardspeed #print self.rightspeed #sys.exit(0) self.rightspeed *= 0.7 self.forwardspeed *= 0.7 self.pandaActor.setPos(self.pandaActor,self.rightspeed, self.forwardspeed,0) return Task.again def spinCameraTask(self, task): if self.paused: return Task.cont if self.render.getRelativePoint(self.pandaActorPhysicsP,self.pandaActor.getPos())[2] < -10: self.pandaAN.getPhysicsObject().setVelocity(0,0,30) #self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100))) self.prev_time=task.time #play queued animations: for x in self.move_anim_queue+self.anim_queue: if x[0].getCurrentAnim()==None: if x[1]: x[0].play(x[2]) else: x[0].loop(x[2]) if x in self.move_anim_queue: self.move_anim_queue.remove(x) elif x in self.anim_queue: self.anim_queue.remove(x) #Do other stuff if self.mouseWatcherNode.hasMouse(): x=base.mouseWatcherNode.getMouseX() y=base.mouseWatcherNode.getMouseY() if self.prev_pos==None: self.prev_pos = (x,y) xx = self.prev_pos[0] - x yy = self.prev_pos[1] + y self.prev_pos = (xx,yy) self.pandaActor.setHpr(self.pandaActor,-20*(pi/2.0)*x,0,0) #self.camera.setHpr(self.pandaActor, 20*(pi/2.0)*x, 20*(pi/2.0)*yy, 0) if self.is_firstP: self.camera.lookAt(self.pandaActor) self.camera.setPos(self.pandaActor,0,0,4) self.camera.setHpr(self.camera,180,0,0) else: self.camera.setPos(self.pandaActor,0,8,5) self.camera.lookAt(self.pandaActor) if self.mirror: self.camera.setY(-self.camera.getY()) self.camera.lookAt(self.pandaActor) self.camera.setHpr(self.camera,0,20*(pi/2.0)*yy,0) self.center_mouse() #zombie collisions return Task.cont #User Actions: def meelee(self): #Make actor stomp here. or something #Load animation self.zombieland.meelee() self.anim_queue += [(self.pandaActor,True,self.pandaActor.getCurrentAnim())] self.pandaActor.play('kick') #pass def ranged_start(self): #put animation here self.old_anim = self.pandaActor.getCurrentAnim() if self.old_anim not in ['shooting','unready_to_shoot','ready_to_shoot'] : self.old_anim2 = self.old_anim if self.old_anim not in ['ready_to_shoot','shooting','unready_to_shoot']: self.pandaActor.play('ready_to_shoot') self.taskMgr.add(self.bulletThrower, "zombieTask_bulletThrower") def ranged_stop(self,task=None): if self.paused: return Task.cont #stop animation here if self.pandaActor.getCurrentAnim()<>'shooting' and task==None: self.pandaActor.play('shooting') self.taskMgr.remove("zombieTask_bulletThrower") self.taskMgr.doMethodLater(0.5,self.ranged_stop,'zombieTask_rangedStop') return Task.done self.taskMgr.remove("zombieTask_bulletThrower") return Task.done
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 SmartCar(ShowBase): def __init__(self): ShowBase.__init__(self) # Override defaults self.disableMouse() self.setBackgroundColor(VBase3(160, 200, 150) / 255.0) self.setFrameRateMeter(True) # Lights dlight = DirectionalLight("dlight") dlnp = self.render.attachNewNode(dlight) dlnp.setHpr(180.0, -70.0, 0) self.render.setLight(dlnp) alight = AmbientLight("alight") alnp = self.render.attachNewNode(alight) alight.setColor(VBase4(0.4, 0.4, 0.4, 1)) self.render.setLight(alnp) # Collision traverser self.cTrav = CollisionTraverser("collisionTraverser") #self.cTrav.showCollisions(self.render) # Collision handlers self.carCollisionHandler = CollisionHandlerEvent() self.carCollisionHandler.addInPattern("%fn-into-%in") # Camera controls self.cameraController = CameraController(self, 250, math.pi / 4.0, math.pi / 4.0) #self.cameraController = CameraController(self, 300, -math.pi, math.pi / 4.0) # Load the track self.track = self.loader.loadModel("models/trackMotegi") checkpointsCollision = self.track.find("checkpoints").node() checkpointsCollision.setIntoCollideMask(BitMask32(0xF0)) self.numCheckpoints = checkpointsCollision.getNumSolids() self.track.reparentTo(self.render) # Load the car #self.car = KeyboardCar(self) self.car = NeuralNetworkCar(self) self.cameraController.follow(self.car.getNodePath()) #self.cameraController.setTarget(self.car.getNodePath()) # Reposition the car #self.car.getNodePath().setH(180.0) # Register car collisions with track self.cTrav.addCollider(self.car.carCollider, self.carCollisionHandler) self.accept("carCollider-into-trackCollision", self.car.onCrash) self.accept("carCollider-into-checkpoints", self.car.onCheckpoint) # State logger self.loggingActive = False self.log = [] self.accept("l", self.toggleStateLogger) def toggleStateLogger(self): if not self.loggingActive: print "LOG: started." self.taskMgr.add(self.stateLogger, "StateLoggerTask") else: self.taskMgr.remove("StateLoggerTask") self.writeLog("data/log.csv") self.loggingActive = not self.loggingActive def stateLogger(self, task): row = [self.car.speed, self.car.steerAngle] row.extend(self.car.sensorDistances) row.append(float(self.car.arrowUpDown)) row.append(float(self.car.arrowLeftDown)) row.append(float(self.car.arrowRightDown)) self.log.append(row) return task.again def writeLog(self, filename): with open(filename, 'wb') as file: wr = csv.writer(file) wr.writerows(self.log) print "LOG: written."
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 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 LearnNeuroevolution(ShowBase): def __init__(self): ShowBase.__init__(self) # Override defaults self.disableMouse() self.setBackgroundColor(VBase3(160, 200, 150) / 255.0) self.setFrameRateMeter(True) # Lights dlight = DirectionalLight("dlight") dlnp = self.render.attachNewNode(dlight) dlnp.setHpr(180.0, -70.0, 0) self.render.setLight(dlnp) alight = AmbientLight("alight") alnp = self.render.attachNewNode(alight) alight.setColor(VBase4(0.4, 0.4, 0.4, 1)) self.render.setLight(alnp) # Collision traverser self.cTrav = CollisionTraverser("collisionTraverser") # Collision handlers self.carCollisionHandler = CollisionHandlerEvent() self.carCollisionHandler.addInPattern("%fn-into-%in") # Camera controls self.cameraController = CameraController(self, 600, math.radians(45), math.radians(60)) # Load the track self.track = self.loader.loadModel("models/trackMotegi") # self.track = self.loader.loadModel("models/trackValencia") checkpointsCollision = self.track.find("checkpoints").node() checkpointsCollision.setIntoCollideMask(BitMask32(0xF0)) self.numCheckpoints = checkpointsCollision.getNumSolids() self.track.reparentTo(self.render) # Neuroevolution self.inputLayerSize = 9 self.hiddenLayer1Size = 5 self.hiddenLayer2Size = 5 self.numLabels = 2 self.thetaSizes = [(5, 10), (5, 6), (2, 6)] self.generationSize = 20 self.weightInit = 0.12 self.replaceRatio = 0.05 self.scaleRatio = 0.05 self.addRatio = 0.05 self.generationCount = 1 self.cars = [] for i in range(self.generationSize): car = NeuroevolutionCar(self, i, 9) # Register car collisions with track self.cTrav.addCollider(car.carCollider, self.carCollisionHandler) self.accept("carCollider{}-into-trackCollision".format(i), car.onCrash) self.accept("carCollider{}-into-checkpoints".format(i), car.onCheckpoint) self.cars.append(car) # Initial generation np.random.seed(3) for i in range(self.generationSize): theta1 = self.randWeights(5, 10, self.weightInit) theta2 = self.randWeights(5, 6, self.weightInit) theta3 = self.randWeights(2, 6, self.weightInit) self.cars[i].startSimulation(theta1, theta2, theta3) # Run learning task self.taskMgr.add(self.neuroevolution, "NeuroevolutionTask") # DEBUG self.txtGen = OnscreenText(text='', pos=(0.0, -0.04), scale=0.05, align=TextNode.ALeft, fg=(1, 1, 1, 1), bg=(0, 0, 0, .4)) self.txtGen.reparentTo(self.a2dTopLeft) def neuroevolution(self, task): generationDone = True for car in self.cars: if not car.simulationDone: generationDone = False if generationDone: # Compute fitness scores fitness = np.zeros(self.generationSize) for i in range(self.generationSize): fitness[i] = self.fitnessFunction(self.cars[i].checkpointCount, self.cars[i].timeAlive) prob = fitness / np.sum(fitness) # Generate new generation nextGenTheta1 = [] nextGenTheta2 = [] nextGenTheta3 = [] for i in range(self.generationSize): # Selection (p1_i, p2_i) = np.random.choice(self.generationSize, 2, replace=False, p=prob) if fitness[p1_i] < fitness[p2_i]: p1_i, p2_i = p2_i, p1_i # Crossover fit1 = fitness[p1_i] fit2 = fitness[p2_i] crossoverRatio = fit2 / (fit1 + fit2) theta1 = np.copy(self.cars[p1_i].theta1) mask1 = np.random.rand(5, 10) < crossoverRatio theta1[mask1] = self.cars[p2_i].theta1[mask1] theta2 = np.copy(self.cars[p1_i].theta2) mask2 = np.random.rand(5, 6) < crossoverRatio theta2[mask2] = self.cars[p2_i].theta2[mask2] theta3 = np.copy(self.cars[p1_i].theta3) mask3 = np.random.rand(2, 6) < crossoverRatio theta3[mask3] = self.cars[p2_i].theta3[mask3] # Mutation # replace maskReplace = np.random.rand(5, 10) < self.replaceRatio sz = np.sum(maskReplace) theta1[maskReplace] = np.random.rand( sz) * 2 * self.weightInit - self.weightInit maskReplace = np.random.rand(5, 6) < self.replaceRatio sz = np.sum(maskReplace) theta2[maskReplace] = np.random.rand( sz) * 2 * self.weightInit - self.weightInit maskReplace = np.random.rand(2, 6) < self.replaceRatio sz = np.sum(maskReplace) theta3[maskReplace] = np.random.rand( sz) * 2 * self.weightInit - self.weightInit # scale maskScale = np.random.rand(5, 10) < self.scaleRatio sz = np.sum(maskScale) theta1[maskScale] = theta1[maskScale] * (np.random.rand(sz) + 0.5) maskScale = np.random.rand(5, 6) < self.scaleRatio sz = np.sum(maskScale) theta2[maskScale] = theta2[maskScale] * (np.random.rand(sz) + 0.5) maskScale = np.random.rand(2, 6) < self.scaleRatio sz = np.sum(maskScale) theta3[maskScale] = theta3[maskScale] * (np.random.rand(sz) + 0.5) # add maskAdd = np.random.rand(5, 10) < self.addRatio sz = np.sum(maskAdd) theta1[maskAdd] = theta1[maskAdd] + (np.random.rand(sz) - 0.5) * 2.0 maskAdd = np.random.rand(5, 6) < self.addRatio sz = np.sum(maskAdd) theta2[maskAdd] = theta2[maskAdd] + (np.random.rand(sz) - 0.5) * 2.0 maskAdd = np.random.rand(2, 6) < self.addRatio sz = np.sum(maskAdd) theta3[maskAdd] = theta3[maskAdd] + (np.random.rand(sz) - 0.5) * 2.0 nextGenTheta1.append(theta1) nextGenTheta2.append(theta2) nextGenTheta3.append(theta3) # Run new generation for i in range(self.generationSize): self.cars[i].startSimulation(nextGenTheta1[i], nextGenTheta2[i], nextGenTheta3[i]) self.generationCount += 1 self.txtGen.setText('Gen: {}'.format(self.generationCount)) return task.cont def fitnessFunction(self, checkpointCount, timeAlive): f = 100 * checkpointCount + timeAlive + 1 return f def randWeights(self, rows, cols, weightInit): w = np.random.rand(rows, cols) * 2 * weightInit - weightInit return w
class DistributedIceGame(DistributedMinigame.DistributedMinigame, DistributedIceWorld.DistributedIceWorld): notify = directNotify.newCategory('DistributedIceGame') MaxLocalForce = 100 MaxPhysicsForce = 25000 def __init__(self, cr): DistributedMinigame.DistributedMinigame.__init__(self, cr) DistributedIceWorld.DistributedIceWorld.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedIceGame', [ State.State('off', self.enterOff, self.exitOff, ['inputChoice']), State.State( 'inputChoice', self.enterInputChoice, self.exitInputChoice, ['waitServerChoices', 'moveTires', 'displayVotes', 'cleanup']), State.State('waitServerChoices', self.enterWaitServerChoices, self.exitWaitServerChoices, ['moveTires', 'cleanup']), State.State('moveTires', self.enterMoveTires, self.exitMoveTires, ['synch', 'cleanup']), State.State('synch', self.enterSynch, self.exitSynch, ['inputChoice', 'scoring', 'cleanup']), State.State('scoring', self.enterScoring, self.exitScoring, ['cleanup', 'finalResults', 'inputChoice']), State.State('finalResults', self.enterFinalResults, self.exitFinalResults, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, []) ], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.cameraThreeQuarterView = (0, -22, 45, 0, -62.89, 0) self.tireDict = {} self.forceArrowDict = {} self.canDrive = False self.timer = None self.timerStartTime = None self.curForce = 0 self.curHeading = 0 self.headingMomentum = 0.0 self.forceMomentum = 0.0 self.allTireInputs = None self.curRound = 0 self.curMatch = 0 self.controlKeyWarningLabel = DirectLabel( text=TTLocalizer.IceGameControlKeyWarning, text_fg=VBase4(1, 0, 0, 1), relief=None, pos=(0.0, 0, 0), scale=0.15) self.controlKeyWarningLabel.hide() self.waitingMoveLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForPlayersToFinishMove, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.6, 0, -0.75), scale=0.075) self.waitingMoveLabel.hide() self.waitingSyncLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForAISync, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.6, 0, -0.75), scale=0.075) self.waitingSyncLabel.hide() self.infoLabel = DirectLabel(text='', text_fg=VBase4(0, 0, 0, 1), relief=None, pos=(0.0, 0, 0.7), scale=0.075) self.updateInfoLabel() self.lastForceArrowUpdateTime = 0 self.sendForceArrowUpdateAsap = False self.treasures = [] self.penalties = [] self.obstacles = [] self.controlKeyPressed = False self.controlKeyWarningIval = None return def delete(self): DistributedIceWorld.DistributedIceWorld.delete(self) DistributedMinigame.DistributedMinigame.delete(self) if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningLabel.destroy() del self.controlKeyWarningLabel self.waitingMoveLabel.destroy() del self.waitingMoveLabel self.waitingSyncLabel.destroy() del self.waitingSyncLabel self.infoLabel.destroy() del self.infoLabel for treasure in self.treasures: treasure.destroy() del self.treasures for penalty in self.penalties: penalty.destroy() del self.penalties for obstacle in self.obstacles: obstacle.removeNode() del self.obstacles del self.gameFSM return def announceGenerate(self): DistributedMinigame.DistributedMinigame.announceGenerate(self) DistributedIceWorld.DistributedIceWorld.announceGenerate(self) self.debugTaskName = self.uniqueName('debugTask') def getTitle(self): return TTLocalizer.IceGameTitle def getInstructions(self): szId = self.getSafezoneId() numPenalties = IceGameGlobals.NumPenalties[szId] result = TTLocalizer.IceGameInstructions if numPenalties == 0: result = TTLocalizer.IceGameInstructionsNoTnt return result def getMaxDuration(self): return 0 def load(self): self.notify.debug('load') DistributedMinigame.DistributedMinigame.load(self) self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_IceGame.ogg') self.gameBoard = loader.loadModel( 'phase_4/models/minigames/ice_game_icerink') background = loader.loadModel('phase_4/models/minigames/ice_game_2d') backgroundWide = loader.loadModel( 'phase_4/models/minigames/iceslide_ground') background.reparentTo(self.gameBoard) backgroundWide.reparentTo(self.gameBoard) backgroundWide.setPos(0, -0.3, -0.5) self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.setupSimulation() index = 0 for avId in self.avIdList: self.setupTire(avId, index) self.setupForceArrow(avId) index += 1 for index in xrange(len(self.avIdList), 4): self.setupTire(-index, index) self.setupForceArrow(-index) self.showForceArrows(realPlayersOnly=True) self.westWallModel = NodePath() if not self.westWallModel.isEmpty(): self.westWallModel.reparentTo(self.gameBoard) self.westWallModel.setPos(IceGameGlobals.MinWall[0], IceGameGlobals.MinWall[1], 0) self.westWallModel.setScale(4) self.eastWallModel = NodePath() if not self.eastWallModel.isEmpty(): self.eastWallModel.reparentTo(self.gameBoard) self.eastWallModel.setPos(IceGameGlobals.MaxWall[0], IceGameGlobals.MaxWall[1], 0) self.eastWallModel.setScale(4) self.eastWallModel.setH(180) self.arrowKeys = ArrowKeys.ArrowKeys() self.target = loader.loadModel('phase_3/models/misc/sphere') self.target.setScale(0.01) self.target.reparentTo(self.gameBoard) self.target.setPos(0, 0, 0) self.scoreCircle = loader.loadModel( 'phase_4/models/minigames/ice_game_score_circle') self.scoreCircle.setScale(0.01) self.scoreCircle.reparentTo(self.gameBoard) self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0) self.scoreCircle.setAlphaScale(0.5) self.scoreCircle.setTransparency(1) self.scoreCircle.hide() self.treasureModel = loader.loadModel( 'phase_4/models/minigames/ice_game_barrel') self.penaltyModel = loader.loadModel( 'phase_4/models/minigames/ice_game_tnt2') self.penaltyModel.setScale(0.75, 0.75, 0.7) szId = self.getSafezoneId() obstacles = IceGameGlobals.Obstacles[szId] index = 0 cubicObstacle = IceGameGlobals.ObstacleShapes[szId] for pos in obstacles: newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius) newObstacle = self.createObstacle(newPos, index, cubicObstacle) self.obstacles.append(newObstacle) index += 1 self.countSound = loader.loadSfx( 'phase_3.5/audio/sfx/tick_counter.ogg') self.treasureGrabSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_vine_game_bananas.ogg') self.penaltyGrabSound = loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_fire_alt.ogg') self.tireSounds = [] for tireIndex in xrange(4): tireHit = loader.loadSfx( 'phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') wallHit = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg') obstacleHit = loader.loadSfx( 'phase_4/audio/sfx/Golf_Hit_Barrier_2.ogg') self.tireSounds.append({ 'tireHit': tireHit, 'wallHit': wallHit, 'obstacleHit': obstacleHit }) self.arrowRotateSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_rotate.ogg') self.arrowUpSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.ogg') self.arrowDownSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.ogg') self.scoreCircleSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_scoring_1.ogg') def unload(self): self.notify.debug('unload') DistributedMinigame.DistributedMinigame.unload(self) del self.music self.gameBoard.removeNode() del self.gameBoard for forceArrow in self.forceArrowDict.values(): forceArrow.removeNode() del self.forceArrowDict self.scoreCircle.removeNode() del self.scoreCircle del self.countSound def onstage(self): self.notify.debug('onstage') DistributedMinigame.DistributedMinigame.onstage(self) self.gameBoard.reparentTo(render) self.__placeToon(self.localAvId) self.moveCameraToTop() self.scorePanels = [] base.playMusic(self.music, looping=1, volume=0.8) def offstage(self): self.notify.debug('offstage') self.music.stop() self.gameBoard.hide() self.infoLabel.hide() for avId in self.tireDict: self.tireDict[avId]['tireNodePath'].hide() for panel in self.scorePanels: panel.cleanup() del self.scorePanels for obstacle in self.obstacles: obstacle.hide() for treasure in self.treasures: treasure.nodePath.hide() for penalty in self.penalties: penalty.nodePath.hide() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() taskMgr.remove(self.uniqueName('aimtask')) self.arrowKeys.destroy() del self.arrowKeys DistributedMinigame.DistributedMinigame.offstage(self) def handleDisabledAvatar(self, avId): self.notify.debug('handleDisabledAvatar') self.notify.debug('avatar ' + str(avId) + ' disabled') DistributedMinigame.DistributedMinigame.handleDisabledAvatar( self, avId) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.DistributedMinigame.setGameReady(self): return for index in xrange(self.numPlayers): avId = self.avIdList[index] toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.forwardSpeed = 0 toon.rotateSpeed = False toon.dropShadow.hide() toon.setAnimState('Sit') if avId in self.tireDict: tireNp = self.tireDict[avId]['tireNodePath'] toon.reparentTo(tireNp) toon.setY(1.0) toon.setZ(-3) toon.startLookAround() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() self.scores = [0] * self.numPlayers spacing = 0.4 for i in xrange(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel( avId, avName) scorePanel.setScale(0.9) scorePanel.setPos(-0.583 - spacing * (self.numPlayers - 1 - i), 0.0, -0.15) scorePanel.reparentTo(base.a2dTopRight) scorePanel.makeTransparent(0.75) self.scorePanels.append(scorePanel) self.arrowKeys.setPressHandlers([ self.__upArrowPressed, self.__downArrowPressed, self.__leftArrowPressed, self.__rightArrowPressed, self.__controlPressed ]) def isInPlayState(self): if not self.gameFSM.getCurrentState(): return False if not self.gameFSM.getCurrentState().getName() == 'play': return False return True def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterInputChoice(self): self.notify.debug('enterInputChoice') self.forceLocalToonToTire() self.controlKeyPressed = False if self.curRound == 0: self.setupStartOfMatch() else: self.notify.debug('self.curRound = %s' % self.curRound) self.timer = ToontownTimer.ToontownTimer() self.timer.hide() if self.timerStartTime != None: self.startTimer() self.showForceArrows(realPlayersOnly=True) self.localForceArrow().setPosHpr(0, 0, -1.0, 0, 0, 0) self.localForceArrow().reparentTo(self.localTireNp()) self.localForceArrow().setY(IceGameGlobals.TireRadius) self.localTireNp().headsUp(self.target) self.notify.debug('self.localForceArrow() heading = %s' % self.localForceArrow().getH()) self.curHeading = self.localTireNp().getH() self.curForce = 25 self.updateLocalForceArrow() for avId in self.forceArrowDict: forceArrow = self.forceArrowDict[avId] forceArrow.setPosHpr(0, 0, -1.0, 0, 0, 0) tireNp = self.tireDict[avId]['tireNodePath'] forceArrow.reparentTo(tireNp) forceArrow.setY(IceGameGlobals.TireRadius) tireNp.headsUp(self.target) self.updateForceArrow(avId, tireNp.getH(), 25) taskMgr.add(self.__aimTask, self.uniqueName('aimtask')) if base.localAvatar.laffMeter: base.localAvatar.laffMeter.stop() self.sendForceArrowUpdateAsap = False return def exitInputChoice(self): if not self.controlKeyPressed: if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningIval = Sequence( Func(self.controlKeyWarningLabel.show), self.controlKeyWarningLabel.colorScaleInterval( 10, VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.controlKeyWarningLabel.hide)) self.controlKeyWarningIval.start() if self.timer != None: self.timer.destroy() self.timer = None self.timerStartTime = None self.hideForceArrows() self.arrowRotateSound.stop() self.arrowUpSound.stop() self.arrowDownSound.stop() taskMgr.remove(self.uniqueName('aimtask')) return def enterWaitServerChoices(self): self.waitingMoveLabel.show() self.showForceArrows(True) def exitWaitServerChoices(self): self.waitingMoveLabel.hide() self.hideForceArrows() def enterMoveTires(self): for key in self.tireDict: body = self.tireDict[key]['tireBody'] body.setAngularVel(0, 0, 0) body.setLinearVel(0, 0, 0) for index in xrange(len(self.allTireInputs)): input = self.allTireInputs[index] avId = self.avIdList[index] body = self.getTireBody(avId) degs = input[1] + 90 tireNp = self.getTireNp(avId) tireH = tireNp.getH() self.notify.debug('tireH = %s' % tireH) radAngle = deg2Rad(degs) foo = NodePath('foo') dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0) self.notify.debug('dirVector is now=%s' % dirVector) inputForce = input[0] inputForce /= self.MaxLocalForce inputForce *= self.MaxPhysicsForce force = dirVector * inputForce self.notify.debug('adding force %s to %d' % (force, avId)) body.addForce(force) self.enableAllTireBodies() self.totalPhysicsSteps = 0 self.startSim() taskMgr.add(self.__moveTiresTask, self.uniqueName('moveTiresTtask')) def exitMoveTires(self): self.forceLocalToonToTire() self.disableAllTireBodies() self.stopSim() self.notify.debug('total Physics steps = %d' % self.totalPhysicsSteps) taskMgr.remove(self.uniqueName('moveTiresTtask')) def enterSynch(self): self.waitingSyncLabel.show() def exitSynch(self): self.waitingSyncLabel.hide() def enterScoring(self): sortedByDistance = [] for avId in self.avIdList: np = self.getTireNp(avId) pos = np.getPos() pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoreMovie = Sequence() curScale = 0.01 curTime = 0 self.scoreCircle.setScale(0.01) self.scoreCircle.show() self.notify.debug('newScores = %s' % self.newScores) circleStartTime = 0 for index in xrange(len(sortedByDistance)): distance = sortedByDistance[index][1] avId = sortedByDistance[index][0] scorePanelIndex = self.avIdList.index(avId) time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec if time < 0: time = 0.01 scaleXY = distance + IceGameGlobals.TireRadius self.notify.debug('circleStartTime = %s' % circleStartTime) self.scoreMovie.append( Parallel( LerpScaleInterval(self.scoreCircle, time, Point3(scaleXY, scaleXY, 1.0)), SoundInterval(self.scoreCircleSound, duration=time, startTime=circleStartTime))) circleStartTime += time startScore = self.scorePanels[scorePanelIndex].getScore() destScore = self.newScores[scorePanelIndex] self.notify.debug('for avId %d, startScore=%d, newScores=%d' % (avId, startScore, destScore)) def increaseScores(t, scorePanelIndex=scorePanelIndex, startScore=startScore, destScore=destScore): oldScore = self.scorePanels[scorePanelIndex].getScore() diff = destScore - startScore newScore = int(startScore + diff * t) if newScore > oldScore: base.playSfx(self.countSound) self.scorePanels[scorePanelIndex].setScore(newScore) self.scores[scorePanelIndex] = newScore duration = (destScore - startScore) * IceGameGlobals.ScoreCountUpRate tireNp = self.tireDict[avId]['tireNodePath'] self.scoreMovie.append( Parallel( LerpFunctionInterval(increaseScores, duration), Sequence( LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1))))) curScale += distance self.scoreMovie.append( Func(self.sendUpdate, 'reportScoringMovieDone', [])) self.scoreMovie.start() def exitScoring(self): self.scoreMovie.finish() self.scoreMovie = None self.scoreCircle.hide() return def enterFinalResults(self): lerpTrack = Parallel() lerpDur = 0.5 tY = 0.6 bY = -.05 lX = -.5 cX = 0 rX = 0.5 scorePanelLocs = (((cX, bY), ), ((lX, bY), (rX, bY)), ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY), (lX, bY), (rX, bY))) scorePanelLocs = scorePanelLocs[self.numPlayers - 1] for i in xrange(self.numPlayers): panel = self.scorePanels[i] pos = scorePanelLocs[i] panel.wrtReparentTo(aspect2d) lerpTrack.append( Parallel( LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType='easeInOut'), LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType='easeInOut'))) self.showScoreTrack = Parallel( lerpTrack, Sequence(Wait(IceGameGlobals.ShowScoresDuration), Func(self.gameOver))) self.showScoreTrack.start() def exitFinalResults(self): self.showScoreTrack.pause() del self.showScoreTrack def enterCleanup(self): self.notify.debug('enterCleanup') if base.localAvatar.laffMeter: base.localAvatar.laffMeter.start() def exitCleanup(self): pass def __placeToon(self, avId): toon = self.getAvatar(avId) if toon: toon.setPos(0, 0, 0) toon.setHpr(0, 0, 0) def moveCameraToTop(self): camera.reparentTo(render) p = self.cameraThreeQuarterView camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5]) def setupTire(self, avId, index): tireNp, tireBody, tireOdeGeom = self.createTire(index) self.tireDict[avId] = { 'tireNodePath': tireNp, 'tireBody': tireBody, 'tireOdeGeom': tireOdeGeom } if avId <= 0: tireBlocker = tireNp.find('**/tireblockermesh') if not tireBlocker.isEmpty(): tireBlocker.hide() if avId == self.localAvId: tireNp = self.tireDict[avId]['tireNodePath'] self.treasureSphereName = 'treasureCollider' self.treasureCollSphere = CollisionSphere( 0, 0, 0, IceGameGlobals.TireRadius) self.treasureCollSphere.setTangible(0) self.treasureCollNode = CollisionNode(self.treasureSphereName) self.treasureCollNode.setFromCollideMask( ToontownGlobals.PieBitmask) self.treasureCollNode.addSolid(self.treasureCollSphere) self.treasureCollNodePath = tireNp.attachNewNode( self.treasureCollNode) self.treasureHandler = CollisionHandlerEvent() self.treasureHandler.addInPattern('%fn-intoTreasure') base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler) eventName = '%s-intoTreasure' % self.treasureCollNodePath.getName() self.notify.debug('eventName = %s' % eventName) self.accept(eventName, self.toonHitSomething) def setupForceArrow(self, avId): arrow = loader.loadModel('phase_4/models/minigames/ice_game_arrow') priority = 0 if avId < 0: priority = -avId else: priority = self.avIdList.index(avId) if avId == self.localAvId: priority = 10 self.forceArrowDict[avId] = arrow def hideForceArrows(self): for forceArrow in self.forceArrowDict.values(): forceArrow.hide() def showForceArrows(self, realPlayersOnly=True): for avId in self.forceArrowDict: if realPlayersOnly: if avId > 0: self.forceArrowDict[avId].show() else: self.forceArrowDict[avId].hide() else: self.forceArrowDict[avId].show() def localForceArrow(self): if self.localAvId in self.forceArrowDict: return self.forceArrowDict[self.localAvId] else: return None return None def setChoices(self, input0, input1, input2, input3): pass def startDebugTask(self): taskMgr.add(self.debugTask, self.debugTaskName) def stopDebugTask(self): taskMgr.remove(self.debugTaskName) def debugTask(self, task): if self.canDrive and localAvatar.doId in self.tireDict: dt = globalClock.getDt() forceMove = 25000 forceMoveDt = forceMove tireBody = self.tireDict[localAvatar.doId]['tireBody'] if self.arrowKeys.upPressed() and not tireBody.isEnabled(): x = 0 y = 1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.downPressed() and not tireBody.isEnabled(): x = 0 y = -1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.leftPressed() and not tireBody.isEnabled(): x = -1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.rightPressed() and not tireBody.isEnabled(): x = 1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) return task.cont def __upArrowPressed(self): pass def __downArrowPressed(self): pass def __leftArrowPressed(self): pass def __rightArrowPressed(self): pass def __controlPressed(self): if self.gameFSM.getCurrentState().getName() == 'inputChoice': self.sendForceArrowUpdateAsap = True self.updateLocalForceArrow() self.controlKeyPressed = True self.sendUpdate('setAvatarChoice', [self.curForce, self.curHeading]) self.gameFSM.request('waitServerChoices') def startTimer(self): now = globalClock.getFrameTime() elapsed = now - self.timerStartTime self.timer.posInTopRightCorner() self.timer.setTime(IceGameGlobals.InputTimeout) self.timer.countdown(IceGameGlobals.InputTimeout - elapsed, self.handleChoiceTimeout) self.timer.show() def setTimerStartTime(self, timestamp): if not self.hasLocalToon: return self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp) if self.timer != None: self.startTimer() return def handleChoiceTimeout(self): self.sendUpdate('setAvatarChoice', [0, 0]) self.gameFSM.request('waitServerChoices') def localTireNp(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]['tireNodePath'] return ret def localTireBody(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]['tireBody'] return ret def getTireBody(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]['tireBody'] return ret def getTireNp(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]['tireNodePath'] return ret def updateForceArrow(self, avId, curHeading, curForce): forceArrow = self.forceArrowDict[avId] tireNp = self.tireDict[avId]['tireNodePath'] tireNp.setH(curHeading) tireBody = self.tireDict[avId]['tireBody'] tireBody.setQuaternion(tireNp.getQuat()) self.notify.debug('curHeading = %s' % curHeading) yScale = curForce / 100.0 yScale *= 1 headY = yScale * 15 xScale = (yScale - 1) / 2.0 + 1.0 shaft = forceArrow.find('**/arrow_shaft') head = forceArrow.find('**/arrow_head') shaft.setScale(xScale, yScale, 1) head.setPos(0, headY, 0) head.setScale(xScale, xScale, 1) def updateLocalForceArrow(self): avId = self.localAvId self.b_setForceArrowInfo(avId, self.curHeading, self.curForce) def __aimTask(self, task): if not hasattr(self, 'arrowKeys'): return task.done dt = globalClock.getDt() headingMomentumChange = dt * 60.0 forceMomentumChange = dt * 160.0 arrowUpdate = False arrowRotating = False arrowUp = False arrowDown = False if self.arrowKeys.upPressed() and not self.arrowKeys.downPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce += self.forceMomentum * dt arrowUpdate = True if oldForce < self.MaxLocalForce: arrowUp = True elif self.arrowKeys.downPressed() and not self.arrowKeys.upPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce -= self.forceMomentum * dt arrowUpdate = True if oldForce > 0.01: arrowDown = True else: self.forceMomentum = 0 if self.arrowKeys.leftPressed() and not self.arrowKeys.rightPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading += self.headingMomentum * dt arrowUpdate = True arrowRotating = True elif self.arrowKeys.rightPressed( ) and not self.arrowKeys.leftPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading -= self.headingMomentum * dt arrowUpdate = True arrowRotating = True else: self.headingMomentum = 0 if arrowUpdate: self.normalizeHeadingAndForce() self.updateLocalForceArrow() if arrowRotating: if not self.arrowRotateSound.status( ) == self.arrowRotateSound.PLAYING: base.playSfx(self.arrowRotateSound, looping=True) else: self.arrowRotateSound.stop() if arrowUp: if not self.arrowUpSound.status() == self.arrowUpSound.PLAYING: base.playSfx(self.arrowUpSound, looping=False) else: self.arrowUpSound.stop() if arrowDown: if not self.arrowDownSound.status() == self.arrowDownSound.PLAYING: base.playSfx(self.arrowDownSound, looping=False) else: self.arrowDownSound.stop() return task.cont def normalizeHeadingAndForce(self): if self.curForce > self.MaxLocalForce: self.curForce = self.MaxLocalForce if self.curForce < 0.01: self.curForce = 0.01 def setTireInputs(self, tireInputs): if not self.hasLocalToon: return self.allTireInputs = tireInputs self.gameFSM.request('moveTires') def enableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]['tireBody'].enable() def disableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]['tireBody'].disable() def areAllTiresDisabled(self): for avId in self.tireDict.keys(): if self.tireDict[avId]['tireBody'].isEnabled(): return False return True def __moveTiresTask(self, task): if self.areAllTiresDisabled(): self.sendTirePositions() self.gameFSM.request('synch') return task.done return task.cont def sendTirePositions(self): tirePositions = [] for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) self.sendUpdate('endingPositions', [tirePositions]) def setFinalPositions(self, finalPos): if not self.hasLocalToon: return for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) def updateInfoLabel(self): self.infoLabel['text'] = TTLocalizer.IceGameInfo % { 'curMatch': self.curMatch + 1, 'numMatch': IceGameGlobals.NumMatches, 'curRound': self.curRound + 1, 'numRound': IceGameGlobals.NumRounds } def setMatchAndRound(self, match, round): if not self.hasLocalToon: return self.curMatch = match self.curRound = round self.updateInfoLabel() def setScores(self, match, round, scores): if not self.hasLocalToon: return self.newMatch = match self.newRound = round self.newScores = scores def setNewState(self, state): if not self.hasLocalToon: return self.notify.debug('setNewState gameFSM=%s newState=%s' % (self.gameFSM, state)) self.gameFSM.request(state) def putAllTiresInStartingPositions(self): for index in xrange(len(self.avIdList)): avId = self.avIdList[index] np = self.tireDict[avId]['tireNodePath'] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]['tireBody'] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) for index in xrange(len(self.avIdList), 4): avId = -index np = self.tireDict[avId]['tireNodePath'] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]['tireBody'] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) def b_setForceArrowInfo(self, avId, force, heading): self.setForceArrowInfo(avId, force, heading) self.d_setForceArrowInfo(avId, force, heading) def d_setForceArrowInfo(self, avId, force, heading): sendIt = False curTime = self.getCurrentGameTime() if self.sendForceArrowUpdateAsap: sendIt = True elif curTime - self.lastForceArrowUpdateTime > 0.2: sendIt = True if sendIt: self.sendUpdate('setForceArrowInfo', [avId, force, heading]) self.sendForceArrowUpdateAsap = False self.lastForceArrowUpdateTime = self.getCurrentGameTime() def setForceArrowInfo(self, avId, force, heading): if not self.hasLocalToon: return self.updateForceArrow(avId, force, heading) def setupStartOfMatch(self): self.putAllTiresInStartingPositions() szId = self.getSafezoneId() self.numTreasures = IceGameGlobals.NumTreasures[szId] if self.treasures: for treasure in self.treasures: treasure.destroy() self.treasures = [] index = 0 treasureMargin = IceGameGlobals.TireRadius + 1.0 while len(self.treasures) < self.numTreasures: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newTreasure = IceTreasure.IceTreasure(self.treasureModel, pos, index, self.doId, penalty=False) goodSpot = True for obstacle in self.obstacles: if newTreasure.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newTreasure.nodePath.getDistance( treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.treasures.append(newTreasure) index += 1 else: newTreasure.destroy() self.numPenalties = IceGameGlobals.NumPenalties[szId] if self.penalties: for penalty in self.penalties: penalty.destroy() self.penalties = [] index = 0 while len(self.penalties) < self.numPenalties: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newPenalty = IceTreasure.IceTreasure(self.penaltyModel, pos, index, self.doId, penalty=True) goodSpot = True for obstacle in self.obstacles: if newPenalty.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newPenalty.nodePath.getDistance( treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: for penalty in self.penalties: if newPenalty.nodePath.getDistance( penalty.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.penalties.append(newPenalty) index += 1 else: newPenalty.destroy() def toonHitSomething(self, entry): self.notify.debug('---- treasure Enter ---- ') self.notify.debug('%s' % entry) name = entry.getIntoNodePath().getName() parts = name.split('-') if len(parts) < 3: self.notify.debug('collided with %s, but returning' % name) return if not int(parts[1]) == self.doId: self.notify.debug("collided with %s, but doId doesn't match" % name) return treasureNum = int(parts[2]) if 'penalty' in parts[0]: self.__penaltyGrabbed(treasureNum) else: self.__treasureGrabbed(treasureNum) def __treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.treasureGrabSound.play() self.sendUpdate('claimTreasure', [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return self.notify.debug('treasure %s grabbed by %s' % (treasureNum, avId)) if avId != self.localAvId: self.treasures[treasureNum].showGrab() i = self.avIdList.index(avId) self.scores[i] += 1 self.scorePanels[i].setScore(self.scores[i]) def __penaltyGrabbed(self, penaltyNum): self.penalties[penaltyNum].showGrab() self.sendUpdate('claimPenalty', [penaltyNum]) def setPenaltyGrabbed(self, avId, penaltyNum): if not self.hasLocalToon: return self.notify.debug('penalty %s grabbed by %s' % (penaltyNum, avId)) if avId != self.localAvId: self.penalties[penaltyNum].showGrab() i = self.avIdList.index(avId) self.scores[i] -= 1 self.scorePanels[i].setScore(self.scores[i]) def postStep(self): DistributedIceWorld.DistributedIceWorld.postStep(self) if not self.colCount: return for count in xrange(self.colCount): c0, c1 = self.getOrderedContacts(count) if c1 in self.tireCollideIds: tireIndex = self.tireCollideIds.index(c1) if c0 in self.tireCollideIds: self.tireSounds[tireIndex]['tireHit'].play() elif c0 == self.wallCollideId: self.tireSounds[tireIndex]['wallHit'].play() elif c0 == self.obstacleCollideId: self.tireSounds[tireIndex]['obstacleHit'].play() def forceLocalToonToTire(self): toon = localAvatar if toon and self.localAvId in self.tireDict: tireNp = self.tireDict[self.localAvId]['tireNodePath'] toon.reparentTo(tireNp) toon.setPosHpr(0, 0, 0, 0, 0, 0) toon.setY(1.0) toon.setZ(-3)
class LearnNeuroevolution(ShowBase): def __init__(self): ShowBase.__init__(self) # Override defaults self.disableMouse() self.setBackgroundColor(VBase3(160, 200, 150) / 255.0) self.setFrameRateMeter(True) # Lights dlight = DirectionalLight("dlight") dlnp = self.render.attachNewNode(dlight) dlnp.setHpr(180.0, -70.0, 0) self.render.setLight(dlnp) alight = AmbientLight("alight") alnp = self.render.attachNewNode(alight) alight.setColor(VBase4(0.4, 0.4, 0.4, 1)) self.render.setLight(alnp) # Collision traverser self.cTrav = CollisionTraverser("collisionTraverser") # self.cTrav.showCollisions(self.render) # Collision handlers self.carCollisionHandler = CollisionHandlerEvent() self.carCollisionHandler.addInPattern("%fn-into-%in") # Camera controls self.cameraController = CameraController(self, 600, math.radians(45), math.radians(60)) # Load the track self.track = self.loader.loadModel("models/trackMotegi") # self.track = self.loader.loadModel("models/trackValencia") checkpointsCollision = self.track.find("checkpoints").node() checkpointsCollision.setIntoCollideMask(BitMask32(0xF0)) self.numCheckpoints = checkpointsCollision.getNumSolids() self.track.reparentTo(self.render) # Enemy cars enemyColor = LColor(204 / 255.0, 72 / 255.0, 63 / 255.0, 1.0) self.enemyPos = [(-150, -110, 60), (113, -233, 45), (-255, -264, 20), (-364, -237, -90), (-204, -46, 230)] self.enemyCars = [] for pos in self.enemyPos: car = NeuralNetworkCar(self) car.getNodePath().setColor(enemyColor) car.getNodePath().setX(pos[0]) car.getNodePath().setY(pos[1]) car.getNodePath().setH(pos[2]) self.enemyCars.append(car) # Neuroevolution # self.loggingActive = False self.inputLayerSize = 9 self.hiddenLayer1Size = 5 self.hiddenLayer2Size = 5 self.numLabels = 2 self.thetaSizes = [(self.hiddenLayer1Size, self.inputLayerSize + 1), (self.hiddenLayer2Size, self.hiddenLayer1Size + 1), (self.numLabels, self.hiddenLayer2Size + 1)] self.generationSize = 15 self.weightInit = 0.12 self.replaceRatio = 0.02 self.scaleRatio = 0.02 self.addRatio = 0.02 self.generationCount = 1 self.cars = [] for i in range(self.generationSize): car = NeuroevolutionCar(self, i, self.inputLayerSize) # Register car collisions with track self.cTrav.addCollider(car.carCollider, self.carCollisionHandler) self.accept("carCollider{}-into-carCollider".format(i), car.onCrash) self.accept("carCollider{}-into-trackCollision".format(i), car.onCrash) self.accept("carCollider{}-into-checkpoints".format(i), car.onCheckpoint) self.cars.append(car) # Initial generation np.random.seed(0) for i in range(self.generationSize): theta1 = self.randWeights(self.thetaSizes[0], self.weightInit) theta2 = self.randWeights(self.thetaSizes[1], self.weightInit) theta3 = self.randWeights(self.thetaSizes[2], self.weightInit) self.cars[i].startSimulation(theta1, theta2, theta3) # Run learning task self.taskMgr.add(self.neuroevolution, "NeuroevolutionTask") # DEBUG self.accept("l", self.logGeneration) self.txtGen = OnscreenText(text='', pos=(0.0, -0.04), scale=0.05, align=TextNode.ALeft, fg=(1, 1, 1, 1), bg=(0, 0, 0, .4)) self.txtGen.reparentTo(self.a2dTopLeft) def logGeneration(self): # Write generation to log for i in range(self.generationSize): car = self.cars[i] filename = "data/generations_log/gen_{}_car_{}_theta_1".format( self.generationCount, i) with open(filename, 'wb') as csvfile: wr = csv.writer(csvfile) wr.writerows(car.theta1) filename = "data/generations_log/gen_{}_car_{}_theta_2".format( self.generationCount, i) with open(filename, 'wb') as csvfile: wr = csv.writer(csvfile) wr.writerows(car.theta2) filename = "data/generations_log/gen_{}_car_{}_theta_3".format( self.generationCount, i) with open(filename, 'wb') as csvfile: wr = csv.writer(csvfile) wr.writerows(car.theta3) print "LOG: Generation {} logged.".format(self.generationCount) def neuroevolution(self, task): generationDone = True for car in self.cars: if not car.simulationDone: generationDone = False if generationDone: # Compute fitness scores fitness = np.zeros(self.generationSize) for i in range(self.generationSize): fitness[i] = self.fitnessFunction(self.cars[i].checkpointCount, self.cars[i].timeAlive) prob = fitness / np.sum(fitness) # Generate new generation nextGenTheta1 = [] nextGenTheta2 = [] nextGenTheta3 = [] for i in range(self.generationSize): # Selection (p1_i, p2_i) = np.random.choice(self.generationSize, 2, replace=False, p=prob) if fitness[p1_i] < fitness[p2_i]: p1_i, p2_i = p2_i, p1_i r1, c1 = self.cars[p1_i].theta1.shape r2, c2 = self.cars[p1_i].theta2.shape r3, c3 = self.cars[p1_i].theta3.shape # Crossover fit1 = fitness[p1_i] fit2 = fitness[p2_i] crossoverRatio = fit2 / (fit1 + fit2) theta1 = np.copy(self.cars[p1_i].theta1) mask1 = np.random.rand(r1, c1) < crossoverRatio theta1[mask1] = self.cars[p2_i].theta1[mask1] theta2 = np.copy(self.cars[p1_i].theta2) mask2 = np.random.rand(r2, c2) < crossoverRatio theta2[mask2] = self.cars[p2_i].theta2[mask2] theta3 = np.copy(self.cars[p1_i].theta3) mask3 = np.random.rand(r3, c3) < crossoverRatio theta3[mask3] = self.cars[p2_i].theta3[mask3] # Mutation # replace maskReplace = np.random.rand(r1, c1) < self.replaceRatio sz = np.sum(maskReplace) theta1[maskReplace] = np.random.rand( sz) * 2 * self.weightInit - self.weightInit maskReplace = np.random.rand(r2, c2) < self.replaceRatio sz = np.sum(maskReplace) theta2[maskReplace] = np.random.rand( sz) * 2 * self.weightInit - self.weightInit maskReplace = np.random.rand(r3, c3) < self.replaceRatio sz = np.sum(maskReplace) theta3[maskReplace] = np.random.rand( sz) * 2 * self.weightInit - self.weightInit # scale maskScale = np.random.rand(r1, c1) < self.scaleRatio sz = np.sum(maskScale) theta1[maskScale] = theta1[maskScale] * (np.random.rand(sz) + 0.5) maskScale = np.random.rand(r2, c2) < self.scaleRatio sz = np.sum(maskScale) theta2[maskScale] = theta2[maskScale] * (np.random.rand(sz) + 0.5) maskScale = np.random.rand(r3, c3) < self.scaleRatio sz = np.sum(maskScale) theta3[maskScale] = theta3[maskScale] * (np.random.rand(sz) + 0.5) # add maskAdd = np.random.rand(r1, c1) < self.addRatio sz = np.sum(maskAdd) theta1[maskAdd] = theta1[maskAdd] + (np.random.rand(sz) - 0.5) * 2.0 maskAdd = np.random.rand(r2, c2) < self.addRatio sz = np.sum(maskAdd) theta2[maskAdd] = theta2[maskAdd] + (np.random.rand(sz) - 0.5) * 2.0 maskAdd = np.random.rand(r3, c3) < self.addRatio sz = np.sum(maskAdd) theta3[maskAdd] = theta3[maskAdd] + (np.random.rand(sz) - 0.5) * 2.0 nextGenTheta1.append(theta1) nextGenTheta2.append(theta2) nextGenTheta3.append(theta3) # Run new generation for i in range(self.generationSize): self.cars[i].startSimulation(nextGenTheta1[i], nextGenTheta2[i], nextGenTheta3[i]) self.generationCount += 1 self.txtGen.setText('Gen: {}'.format(self.generationCount)) # Reset enemies for i, car in enumerate(self.enemyCars): pos = self.enemyPos[i] car.getNodePath().setX(pos[0]) car.getNodePath().setY(pos[1]) car.getNodePath().setH(pos[2]) return task.cont def fitnessFunction(self, checkpointCount, timeAlive): # f = (10 * checkpointCount) ** 2 + timeAlive + 1 f = (100 * checkpointCount) + timeAlive + 1 return f def randWeights(self, size, weightInit): w = np.random.rand(size[0], size[1]) * 2 * weightInit - weightInit return w
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
class LearnNeuroevolution(ShowBase): def __init__(self): ShowBase.__init__(self) # Override defaults self.disableMouse() self.setBackgroundColor(VBase3(160, 200, 150) / 255.0) self.setFrameRateMeter(True) # Lights dlight = DirectionalLight("dlight") dlnp = self.render.attachNewNode(dlight) dlnp.setHpr(180.0, -70.0, 0) self.render.setLight(dlnp) alight = AmbientLight("alight") alnp = self.render.attachNewNode(alight) alight.setColor(VBase4(0.4, 0.4, 0.4, 1)) self.render.setLight(alnp) # Collision traverser self.cTrav = CollisionTraverser("collisionTraverser") # Collision handlers self.carCollisionHandler = CollisionHandlerEvent() self.carCollisionHandler.addInPattern("%fn-into-%in") # Camera controls self.cameraController = CameraController(self, 400, math.pi / 4.0, math.pi / 4.0) # Load the track self.track = self.loader.loadModel("models/trackMotegi") #self.track = self.loader.loadModel("models/trackValencia") checkpointsCollision = self.track.find("checkpoints").node() checkpointsCollision.setIntoCollideMask(BitMask32(0xF0)) self.numCheckpoints = checkpointsCollision.getNumSolids() self.track.reparentTo(self.render) # Neuroevolution self.generationCount = 0 self.generationSize = 20 self.cars = [] for i in range(self.generationSize): car = NeuroevolutionCar(self, i) # Register car collisions with track self.cTrav.addCollider(car.carCollider, self.carCollisionHandler) self.accept("carCollider{}-into-trackCollision".format(i), car.onCrash) self.accept("carCollider{}-into-checkpoints".format(i), car.onCheckpoint) self.cars.append(car) # Run learning task self.taskMgr.add(self.neuroevolution, "NeuroevolutionTask") # DEBUG self.txtGen = OnscreenText(text='', pos=(0.0, -0.04), scale=0.05, align=TextNode.ALeft, fg=(1, 1, 1, 1), bg=(0, 0, 0, .4)) self.txtGen.reparentTo(self.a2dTopLeft) def neuroevolution(self, task): generationDone = True for car in self.cars: if not car.simulationDone: generationDone = False if generationDone: self.generationCount += 1 self.txtGen.setText('Gen: {}'.format(self.generationCount)) # Compute fitness functions for i in range(self.generationSize): theta1 = self.randWeights(5, 10) theta2 = self.randWeights(5, 6) theta3 = self.randWeights(2, 6) self.cars[i].startSimulation(theta1, theta2, theta3) return task.cont def randWeights(self, rows, cols): epsilonInit = 0.12 w = np.random.rand(rows, cols) * 2 * epsilonInit - epsilonInit return w
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 World(DirectObject): def __init__(self): #--Collision Handler------------------------------------------------------ self.collHandler = CollisionHandlerEvent() self.collHandler.addInPattern('%fn-into-%in') base.cTrav = CollisionTraverser('world traverser') #--Mouse Control---------------------------------------------------------- base.disableMouse() self.properties = WindowProperties() self.properties.setCursorHidden(True) base.win.requestProperties(self.properties) #--Register Hud Elements-------------------------------------------------- self.instruction1 = self.addInstruction("[click] to Shoot",2) self.instruction2 = self.addInstruction("[a] to accelerate", 1) self.instruction3 = self.addInstruction("[esc] to quit", 0) self.scoreHud = self.addHudElement("", 0) self.accuracy = self.addHudElement("", 1) self.speedHud = self.addHudElement("", 2) self.bigHud = OnscreenText(text="", style=1, fg=(1,1,1,1), pos=(0,0), align=TextNode.ACenter, scale = .1) #--Load Objects and Models------------------------------------------------ self.ship = Ship(self.collHandler) self.loadSkyBox() game.camera.reparentTo(self.ship.getModel()) #--Start Game------------------------------------------------------------- self.asteroids = [] self.resetGame() #--Controls -------------------------------------------------------------- self.keysDown = {'a': 0} self.controlTask = taskMgr.add(self.gameLoop, "game-control-task") self.controlTask.lastTime = 0 self.accept("escape", sys.exit, [0]) self.accept("a", self.keyDown, ['a']) self.accept("a-up", self.keyUp, ['a']) self.accept("mouse1", self.shoot) self.accept("space", self.shoot) self.accept("resetgame", self.gameOver) if(DEBUG_CONTROLS): self.accept("0", self.ship.stop) self.accept("9", self.ship.getModel().setHpr, [0,0,0]) #--Register CollisionEvent Handlers--------------------------------------- self.accept('asteroid-into-bullet', self.bulletAsteroidCollision) ### # World.shoot: # # Dispatch method that overloads the use of the mouse button ## def shoot(self): if(self.ship.isAlive()): self.ship.fireBullet() self.shots += 1 else: self.resetGame() ### # World.gameOver() # # Displays "Game Over: <SCORE>" then resets game after 5 seconds def gameOver(self): self.bigHud.setText("GAME OVER: " + str(self.score)) taskMgr.doMethodLater(GAME_OVER_DELAY, self.resetGame, "reset_game", []) ### # World.resetGame # # Resets anything that might change during play essentially reloading ## def resetGame(self): for asteroid in self.asteroids: asteroid.remove() self.score = 0 self.shots = 0 self.hits = 0 self.lifeLength = 0 self.ship.reset() self.scoreHud.setText("Score : " + str(self.score)) self.accuracy.setText("Hit/Fired : 0/0") self.speedHud.setText("Speed : 0") self.bigHud.setText("") self.loadAsteroids() ### # World.bulletAsteroidCollision: # # Event Handler for collision From Asteroid Into Bullet # Triggers the "explosion" of an Asteroid and appends replacments ## def bulletAsteroidCollision(self, entry): bullet = entry.getIntoNodePath().getParent().getPythonTag("owner") asteroid = entry.getFromNodePath().getParent().getPythonTag("owner") self.ship.removeBullet(bullet) self.asteroids.extend(asteroid.registerHit()) self.asteroids.remove(asteroid) self.score += 100 self.hits += 1 asteroid.remove() ### # World.keyDown: # # Register the given key as being held down ## def keyDown(self, key): self.keysDown[key] = 1 ### # World.keyUp: # # Register the given key as no longer being held down ## def keyUp(self, key): self.keysDown[key] = 0 ### # World.addHudElement(msg, row) # # Displays the given string msg in the top left with a row offset of row ## def addHudElement(self, msg, row): return OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-1.3,.95 - (.05 * row)), align=TextNode.ALeft, scale = .05) ### # World.addInstruction(msg, row) # # Displays the given string msg in the top right with a row offset of row ## def addInstruction(self, msg, row): return OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(1.3,.95 - (.05 * row)), align=TextNode.ARight, scale = .05) ### # World.loadSkyBox: # # Helper method that loads the skybox, sets size and other factors and # parents to ship, while keeping a compass effect so it will spin around the # ship ## def loadSkyBox(self): self.skybox = game.loader.loadModel("Models/skybox.egg") self.skybox.setScale(100.0,100.0,100.0) self.skybox.setPos(0,0,0) self.skybox.reparentTo(self.ship.getModel()) # Roots the skybox with relation to the render node, making it stationary # even though its parented to the ship self.skybox.setEffect(CompassEffect.make(render, CompassEffect.PRot)) ### # gameLoop # # Task for managing the input from the mouse and keys. In addition updating # the game world. ## def gameLoop(self, task): md = base.win.getPointer(0) x = md.getX() y = md.getY() # Get the delta in time since last frame (allows us to ratelimit rotation # and acceleration dt = task.time - task.lastTime task.lastTime = task.time self.lifeLength += dt # Calculate how far the mouse moved, generate a rotation offest and send # to the ship to rotate if base.win.movePointer(0, MOUSE_OFFSET, MOUSE_OFFSET): self.ship.rotate(Vec3(-((x-MOUSE_OFFSET) * ROTATION_RATE), INVERTED_MOUSE*((y-MOUSE_OFFSET) * ROTATION_RATE), 0)) #--Allows Holding of A key------------------------------------------------ if(self.keysDown['a'] == 1): self.ship.accelerate(dt) #--Update Asteroid Positions---------------------------------------------- for asteroid in self.asteroids: asteroid.updatePos(dt) #--Update HUD------------------------------------------------------------- if(self.shots !=0): self.accuracy.setText("Hit/Fired : " + str(self.hits) + "/" + str(self.shots)) self.scoreHud.setText("Score : " + str(self.score)) self.speedHud.setText("Speed : " + str(self.ship.getVel())) return Task.cont ### # World.loadAsteroids # # Helper method for creating the asteroids ## def loadAsteroids(self): self.asteroids = [] for i in range(ASTEROID_START_COUNT): x = choice([-1,1]) * choice(range(ASTEROID_SPAWN_MIN, ASTEROID_SPAWN_MAX)) y = choice([-1,1]) * choice(range(ASTEROID_SPAWN_MIN, ASTEROID_SPAWN_MAX)) z = choice([-1,1]) * choice(range(ASTEROID_SPAWN_MIN, ASTEROID_SPAWN_MAX)) self.asteroids.append(Asteroid(Vec3(x,y,z), self.collHandler))
class Starfox(ShowBase): def __init__(self): super().__init__(self) self.scene = self.loader.loadModel("models/world.egg") playerTexture = self.loader.loadTexture('models/starfoxShip.jpg') enemyTexture = self.loader.loadTexture('models/enemyShip.jpg') bulletTexture = loader.loadTexture('models/shot.png') self.scene.reparentTo(self.render) self.player = self.scene.find("player") self.player.setTexture(playerTexture) self.player.setPythonTag("ObjectController", Player(self.player)) #self.player.setPos(20,20,20) self.dynamic_enemy = self.scene.find("enemy1") self.dynamic_enemy.setTexture(enemyTexture) #self.dynamic_enemy.setPos(6,6,6) self.building_enemy = self.scene.find("building_enemy") #self.building_enemy.setPos(20,20,20) self.taskMgr.add(self.update, "update") InputManager.initWith(self, [ InputManager.arrowUp, InputManager.arrowDown, InputManager.arrowLeft, InputManager.arrowRight, InputManager.space, InputManager.keyX, InputManager.keyV ]) base.cTrav = CollisionTraverser() self.CollisionHandlerEvent = CollisionHandlerEvent() self.CollisionHandlerEvent.addInPattern('into-%in') self.CollisionHandlerEvent.addInPattern('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) base.cTrav.showCollisions(self.render) self.rails = self.scene.attachNewNode("rails") #self.scene.find("basePlane").setPos(self.scene,0,0,-10) self.scene.find("basePlane").setHpr(70, 0, 0) self.scene.setPos(self.scene, 0, 0, 0) self.player.reparentTo(self.rails) self.player.setPos(self.rails, 0, 0, 0) self.createStaticEnemy(self.building_enemy, 0, 50, 0) self.createStaticEnemy(self.building_enemy, -50, 40, 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.scene, self.dynamic_enemy, Vec3(-230, 140, 10), base.cTrav, self.CollisionHandlerEvent) 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) def crash(self, evt): print(evt) def update(self, evt): rails_pos = self.rails.getPos(self.scene) new_y = rails_pos.y + globalClock.getDt() * 10 self.rails.setPos(Path.getXOfY(new_y), new_y, 12) self.rails.setHpr(Path.getHeading(new_y), 0, 0) #self.camera.lookAt(self.player) self.camera.setHpr(Path.getHeading(new_y), 0, 0) relX, relZ = self.player.getPythonTag("ObjectController").update( self.rails, globalClock.getDt()) self.camera.setPos(self.rails, relX, -30, relZ) enemies = self.scene.findAllMatches(DynamicEnemy.dynamic_enemy_name) for e in enemies: e.getPythonTag("ObjectController").update(self.scene, globalClock.getDt(), self.player) return Task.cont
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 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 DistributedIceGame(DistributedMinigame.DistributedMinigame, DistributedIceWorld.DistributedIceWorld): notify = directNotify.newCategory('DistributedIceGame') MaxLocalForce = 100 MaxPhysicsForce = 25000 def __init__(self, cr): DistributedMinigame.DistributedMinigame.__init__(self, cr) DistributedIceWorld.DistributedIceWorld.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedIceGame', [State.State('off', self.enterOff, self.exitOff, ['inputChoice']), State.State('inputChoice', self.enterInputChoice, self.exitInputChoice, ['waitServerChoices', 'moveTires', 'displayVotes', 'cleanup']), State.State('waitServerChoices', self.enterWaitServerChoices, self.exitWaitServerChoices, ['moveTires', 'cleanup']), State.State('moveTires', self.enterMoveTires, self.exitMoveTires, ['synch', 'cleanup']), State.State('synch', self.enterSynch, self.exitSynch, ['inputChoice', 'scoring', 'cleanup']), State.State('scoring', self.enterScoring, self.exitScoring, ['cleanup', 'finalResults', 'inputChoice']), State.State('finalResults', self.enterFinalResults, self.exitFinalResults, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.cameraThreeQuarterView = (0, -22, 45, 0, -62.89, 0) self.tireDict = {} self.forceArrowDict = {} self.canDrive = False self.timer = None self.timerStartTime = None self.curForce = 0 self.curHeading = 0 self.headingMomentum = 0.0 self.forceMomentum = 0.0 self.allTireInputs = None self.curRound = 0 self.curMatch = 0 self.controlKeyWarningLabel = DirectLabel(text=TTLocalizer.IceGameControlKeyWarning, text_fg=VBase4(1, 0, 0, 1), relief=None, pos=(0.0, 0, 0), scale=0.15) self.controlKeyWarningLabel.hide() self.waitingMoveLabel = DirectLabel(text=TTLocalizer.IceGameWaitingForPlayersToFinishMove, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.6, 0, -0.75), scale=0.075) self.waitingMoveLabel.hide() self.waitingSyncLabel = DirectLabel(text=TTLocalizer.IceGameWaitingForAISync, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.6, 0, -0.75), scale=0.075) self.waitingSyncLabel.hide() self.infoLabel = DirectLabel(text='', text_fg=VBase4(0, 0, 0, 1), relief=None, pos=(0.0, 0, 0.7), scale=0.075) self.updateInfoLabel() self.lastForceArrowUpdateTime = 0 self.sendForceArrowUpdateAsap = False self.treasures = [] self.penalties = [] self.obstacles = [] self.controlKeyPressed = False self.controlKeyWarningIval = None return def delete(self): DistributedIceWorld.DistributedIceWorld.delete(self) DistributedMinigame.DistributedMinigame.delete(self) if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningLabel.destroy() del self.controlKeyWarningLabel self.waitingMoveLabel.destroy() del self.waitingMoveLabel self.waitingSyncLabel.destroy() del self.waitingSyncLabel self.infoLabel.destroy() del self.infoLabel for treasure in self.treasures: treasure.destroy() del self.treasures for penalty in self.penalties: penalty.destroy() del self.penalties for obstacle in self.obstacles: obstacle.removeNode() del self.obstacles del self.gameFSM return def announceGenerate(self): DistributedMinigame.DistributedMinigame.announceGenerate(self) DistributedIceWorld.DistributedIceWorld.announceGenerate(self) self.debugTaskName = self.uniqueName('debugTask') def getTitle(self): return TTLocalizer.IceGameTitle def getInstructions(self): szId = self.getSafezoneId() numPenalties = IceGameGlobals.NumPenalties[szId] result = TTLocalizer.IceGameInstructions if numPenalties == 0: result = TTLocalizer.IceGameInstructionsNoTnt return result def getMaxDuration(self): return 0 def load(self): self.notify.debug('load') DistributedMinigame.DistributedMinigame.load(self) self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_IceGame.ogg') self.gameBoard = loader.loadModel('phase_4/models/minigames/ice_game_icerink') background = loader.loadModel('phase_4/models/minigames/ice_game_2d') backgroundWide = loader.loadModel('phase_4/models/minigames/iceslide_ground') background.reparentTo(self.gameBoard) backgroundWide.reparentTo(self.gameBoard) backgroundWide.setPos(0, -0.3, -0.5) self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.setupSimulation() index = 0 for avId in self.avIdList: self.setupTire(avId, index) self.setupForceArrow(avId) index += 1 for index in xrange(len(self.avIdList), 4): self.setupTire(-index, index) self.setupForceArrow(-index) self.showForceArrows(realPlayersOnly=True) self.westWallModel = NodePath() if not self.westWallModel.isEmpty(): self.westWallModel.reparentTo(self.gameBoard) self.westWallModel.setPos(IceGameGlobals.MinWall[0], IceGameGlobals.MinWall[1], 0) self.westWallModel.setScale(4) self.eastWallModel = NodePath() if not self.eastWallModel.isEmpty(): self.eastWallModel.reparentTo(self.gameBoard) self.eastWallModel.setPos(IceGameGlobals.MaxWall[0], IceGameGlobals.MaxWall[1], 0) self.eastWallModel.setScale(4) self.eastWallModel.setH(180) self.arrowKeys = ArrowKeys.ArrowKeys() self.target = loader.loadModel('phase_3/models/misc/sphere') self.target.setScale(0.01) self.target.reparentTo(self.gameBoard) self.target.setPos(0, 0, 0) self.scoreCircle = loader.loadModel('phase_4/models/minigames/ice_game_score_circle') self.scoreCircle.setScale(0.01) self.scoreCircle.reparentTo(self.gameBoard) self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0) self.scoreCircle.setAlphaScale(0.5) self.scoreCircle.setTransparency(1) self.scoreCircle.hide() self.treasureModel = loader.loadModel('phase_4/models/minigames/ice_game_barrel') self.penaltyModel = loader.loadModel('phase_4/models/minigames/ice_game_tnt2') self.penaltyModel.setScale(0.75, 0.75, 0.7) szId = self.getSafezoneId() obstacles = IceGameGlobals.Obstacles[szId] index = 0 cubicObstacle = IceGameGlobals.ObstacleShapes[szId] for pos in obstacles: newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius) newObstacle = self.createObstacle(newPos, index, cubicObstacle) self.obstacles.append(newObstacle) index += 1 self.countSound = loader.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') self.treasureGrabSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_vine_game_bananas.ogg') self.penaltyGrabSound = loader.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.ogg') self.tireSounds = [] for tireIndex in xrange(4): tireHit = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') wallHit = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg') obstacleHit = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_2.ogg') self.tireSounds.append({'tireHit': tireHit, 'wallHit': wallHit, 'obstacleHit': obstacleHit}) self.arrowRotateSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_force_rotate.ogg') self.arrowUpSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.ogg') self.arrowDownSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.ogg') self.scoreCircleSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_scoring_1.ogg') def unload(self): self.notify.debug('unload') DistributedMinigame.DistributedMinigame.unload(self) del self.music self.gameBoard.removeNode() del self.gameBoard for forceArrow in self.forceArrowDict.values(): forceArrow.removeNode() del self.forceArrowDict self.scoreCircle.removeNode() del self.scoreCircle del self.countSound def onstage(self): self.notify.debug('onstage') DistributedMinigame.DistributedMinigame.onstage(self) self.gameBoard.reparentTo(render) self.__placeToon(self.localAvId) self.moveCameraToTop() self.scorePanels = [] base.playMusic(self.music, looping=1, volume=0.8) def offstage(self): self.notify.debug('offstage') self.music.stop() self.gameBoard.hide() self.infoLabel.hide() for avId in self.tireDict: self.tireDict[avId]['tireNodePath'].hide() for panel in self.scorePanels: panel.cleanup() del self.scorePanels for obstacle in self.obstacles: obstacle.hide() for treasure in self.treasures: treasure.nodePath.hide() for penalty in self.penalties: penalty.nodePath.hide() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() taskMgr.remove(self.uniqueName('aimtask')) self.arrowKeys.destroy() del self.arrowKeys DistributedMinigame.DistributedMinigame.offstage(self) def handleDisabledAvatar(self, avId): self.notify.debug('handleDisabledAvatar') self.notify.debug('avatar ' + str(avId) + ' disabled') DistributedMinigame.DistributedMinigame.handleDisabledAvatar(self, avId) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.DistributedMinigame.setGameReady(self): return for index in xrange(self.numPlayers): avId = self.avIdList[index] toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.forwardSpeed = 0 toon.rotateSpeed = False toon.dropShadow.hide() toon.setAnimState('Sit') if avId in self.tireDict: tireNp = self.tireDict[avId]['tireNodePath'] toon.reparentTo(tireNp) toon.setY(1.0) toon.setZ(-3) toon.startLookAround() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() self.scores = [0] * self.numPlayers spacing = 0.4 for i in xrange(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(avId, avName) scorePanel.setScale(0.9) scorePanel.setPos(-0.583 - spacing * (self.numPlayers - 1 - i), 0.0, -0.15) scorePanel.reparentTo(base.a2dTopRight) scorePanel.makeTransparent(0.75) self.scorePanels.append(scorePanel) self.arrowKeys.setPressHandlers([self.__upArrowPressed, self.__downArrowPressed, self.__leftArrowPressed, self.__rightArrowPressed, self.__controlPressed]) def isInPlayState(self): if not self.gameFSM.getCurrentState(): return False if not self.gameFSM.getCurrentState().getName() == 'play': return False return True def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterInputChoice(self): self.notify.debug('enterInputChoice') self.forceLocalToonToTire() self.controlKeyPressed = False if self.curRound == 0: self.setupStartOfMatch() else: self.notify.debug('self.curRound = %s' % self.curRound) self.timer = ToontownTimer.ToontownTimer() self.timer.hide() if self.timerStartTime != None: self.startTimer() self.showForceArrows(realPlayersOnly=True) self.localForceArrow().setPosHpr(0, 0, -1.0, 0, 0, 0) self.localForceArrow().reparentTo(self.localTireNp()) self.localForceArrow().setY(IceGameGlobals.TireRadius) self.localTireNp().headsUp(self.target) self.notify.debug('self.localForceArrow() heading = %s' % self.localForceArrow().getH()) self.curHeading = self.localTireNp().getH() self.curForce = 25 self.updateLocalForceArrow() for avId in self.forceArrowDict: forceArrow = self.forceArrowDict[avId] forceArrow.setPosHpr(0, 0, -1.0, 0, 0, 0) tireNp = self.tireDict[avId]['tireNodePath'] forceArrow.reparentTo(tireNp) forceArrow.setY(IceGameGlobals.TireRadius) tireNp.headsUp(self.target) self.updateForceArrow(avId, tireNp.getH(), 25) taskMgr.add(self.__aimTask, self.uniqueName('aimtask')) if base.localAvatar.laffMeter: base.localAvatar.laffMeter.stop() self.sendForceArrowUpdateAsap = False return def exitInputChoice(self): if not self.controlKeyPressed: if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningIval = Sequence(Func(self.controlKeyWarningLabel.show), self.controlKeyWarningLabel.colorScaleInterval(10, VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.controlKeyWarningLabel.hide)) self.controlKeyWarningIval.start() if self.timer != None: self.timer.destroy() self.timer = None self.timerStartTime = None self.hideForceArrows() self.arrowRotateSound.stop() self.arrowUpSound.stop() self.arrowDownSound.stop() taskMgr.remove(self.uniqueName('aimtask')) return def enterWaitServerChoices(self): self.waitingMoveLabel.show() self.showForceArrows(True) def exitWaitServerChoices(self): self.waitingMoveLabel.hide() self.hideForceArrows() def enterMoveTires(self): for key in self.tireDict: body = self.tireDict[key]['tireBody'] body.setAngularVel(0, 0, 0) body.setLinearVel(0, 0, 0) for index in xrange(len(self.allTireInputs)): input = self.allTireInputs[index] avId = self.avIdList[index] body = self.getTireBody(avId) degs = input[1] + 90 tireNp = self.getTireNp(avId) tireH = tireNp.getH() self.notify.debug('tireH = %s' % tireH) radAngle = deg2Rad(degs) foo = NodePath('foo') dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0) self.notify.debug('dirVector is now=%s' % dirVector) inputForce = input[0] inputForce /= self.MaxLocalForce inputForce *= self.MaxPhysicsForce force = dirVector * inputForce self.notify.debug('adding force %s to %d' % (force, avId)) body.addForce(force) self.enableAllTireBodies() self.totalPhysicsSteps = 0 self.startSim() taskMgr.add(self.__moveTiresTask, self.uniqueName('moveTiresTtask')) def exitMoveTires(self): self.forceLocalToonToTire() self.disableAllTireBodies() self.stopSim() self.notify.debug('total Physics steps = %d' % self.totalPhysicsSteps) taskMgr.remove(self.uniqueName('moveTiresTtask')) def enterSynch(self): self.waitingSyncLabel.show() def exitSynch(self): self.waitingSyncLabel.hide() def enterScoring(self): sortedByDistance = [] for avId in self.avIdList: np = self.getTireNp(avId) pos = np.getPos() pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoreMovie = Sequence() curScale = 0.01 curTime = 0 self.scoreCircle.setScale(0.01) self.scoreCircle.show() self.notify.debug('newScores = %s' % self.newScores) circleStartTime = 0 for index in xrange(len(sortedByDistance)): distance = sortedByDistance[index][1] avId = sortedByDistance[index][0] scorePanelIndex = self.avIdList.index(avId) time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec if time < 0: time = 0.01 scaleXY = distance + IceGameGlobals.TireRadius self.notify.debug('circleStartTime = %s' % circleStartTime) self.scoreMovie.append(Parallel(LerpScaleInterval(self.scoreCircle, time, Point3(scaleXY, scaleXY, 1.0)), SoundInterval(self.scoreCircleSound, duration=time, startTime=circleStartTime))) circleStartTime += time startScore = self.scorePanels[scorePanelIndex].getScore() destScore = self.newScores[scorePanelIndex] self.notify.debug('for avId %d, startScore=%d, newScores=%d' % (avId, startScore, destScore)) def increaseScores(t, scorePanelIndex = scorePanelIndex, startScore = startScore, destScore = destScore): oldScore = self.scorePanels[scorePanelIndex].getScore() diff = destScore - startScore newScore = int(startScore + diff * t) if newScore > oldScore: base.playSfx(self.countSound) self.scorePanels[scorePanelIndex].setScore(newScore) self.scores[scorePanelIndex] = newScore duration = (destScore - startScore) * IceGameGlobals.ScoreCountUpRate tireNp = self.tireDict[avId]['tireNodePath'] self.scoreMovie.append(Parallel(LerpFunctionInterval(increaseScores, duration), Sequence(LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1))))) curScale += distance self.scoreMovie.append(Func(self.sendUpdate, 'reportScoringMovieDone', [])) self.scoreMovie.start() def exitScoring(self): self.scoreMovie.finish() self.scoreMovie = None self.scoreCircle.hide() return def enterFinalResults(self): lerpTrack = Parallel() lerpDur = 0.5 tY = 0.6 bY = -.05 lX = -.5 cX = 0 rX = 0.5 scorePanelLocs = (((cX, bY),), ((lX, bY), (rX, bY)), ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY), (lX, bY), (rX, bY))) scorePanelLocs = scorePanelLocs[self.numPlayers - 1] for i in xrange(self.numPlayers): panel = self.scorePanels[i] pos = scorePanelLocs[i] panel.wrtReparentTo(aspect2d) lerpTrack.append(Parallel(LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType='easeInOut'), LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType='easeInOut'))) self.showScoreTrack = Parallel(lerpTrack, Sequence(Wait(IceGameGlobals.ShowScoresDuration), Func(self.gameOver))) self.showScoreTrack.start() def exitFinalResults(self): self.showScoreTrack.pause() del self.showScoreTrack def enterCleanup(self): self.notify.debug('enterCleanup') if base.localAvatar.laffMeter: base.localAvatar.laffMeter.start() def exitCleanup(self): pass def __placeToon(self, avId): toon = self.getAvatar(avId) if toon: toon.setPos(0, 0, 0) toon.setHpr(0, 0, 0) def moveCameraToTop(self): camera.reparentTo(render) p = self.cameraThreeQuarterView camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5]) def setupTire(self, avId, index): tireNp, tireBody, tireOdeGeom = self.createTire(index) self.tireDict[avId] = {'tireNodePath': tireNp, 'tireBody': tireBody, 'tireOdeGeom': tireOdeGeom} if avId <= 0: tireBlocker = tireNp.find('**/tireblockermesh') if not tireBlocker.isEmpty(): tireBlocker.hide() if avId == self.localAvId: tireNp = self.tireDict[avId]['tireNodePath'] self.treasureSphereName = 'treasureCollider' self.treasureCollSphere = CollisionSphere(0, 0, 0, IceGameGlobals.TireRadius) self.treasureCollSphere.setTangible(0) self.treasureCollNode = CollisionNode(self.treasureSphereName) self.treasureCollNode.setFromCollideMask(ToontownGlobals.PieBitmask) self.treasureCollNode.addSolid(self.treasureCollSphere) self.treasureCollNodePath = tireNp.attachNewNode(self.treasureCollNode) self.treasureHandler = CollisionHandlerEvent() self.treasureHandler.addInPattern('%fn-intoTreasure') base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler) eventName = '%s-intoTreasure' % self.treasureCollNodePath.getName() self.notify.debug('eventName = %s' % eventName) self.accept(eventName, self.toonHitSomething) def setupForceArrow(self, avId): arrow = loader.loadModel('phase_4/models/minigames/ice_game_arrow') priority = 0 if avId < 0: priority = -avId else: priority = self.avIdList.index(avId) if avId == self.localAvId: priority = 10 self.forceArrowDict[avId] = arrow def hideForceArrows(self): for forceArrow in self.forceArrowDict.values(): forceArrow.hide() def showForceArrows(self, realPlayersOnly = True): for avId in self.forceArrowDict: if realPlayersOnly: if avId > 0: self.forceArrowDict[avId].show() else: self.forceArrowDict[avId].hide() else: self.forceArrowDict[avId].show() def localForceArrow(self): if self.localAvId in self.forceArrowDict: return self.forceArrowDict[self.localAvId] else: return None return None def setChoices(self, input0, input1, input2, input3): pass def startDebugTask(self): taskMgr.add(self.debugTask, self.debugTaskName) def stopDebugTask(self): taskMgr.remove(self.debugTaskName) def debugTask(self, task): if self.canDrive and localAvatar.doId in self.tireDict: dt = globalClock.getDt() forceMove = 25000 forceMoveDt = forceMove tireBody = self.tireDict[localAvatar.doId]['tireBody'] if self.arrowKeys.upPressed() and not tireBody.isEnabled(): x = 0 y = 1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.downPressed() and not tireBody.isEnabled(): x = 0 y = -1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.leftPressed() and not tireBody.isEnabled(): x = -1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.rightPressed() and not tireBody.isEnabled(): x = 1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) return task.cont def __upArrowPressed(self): pass def __downArrowPressed(self): pass def __leftArrowPressed(self): pass def __rightArrowPressed(self): pass def __controlPressed(self): if self.gameFSM.getCurrentState().getName() == 'inputChoice': self.sendForceArrowUpdateAsap = True self.updateLocalForceArrow() self.controlKeyPressed = True self.sendUpdate('setAvatarChoice', [self.curForce, self.curHeading]) self.gameFSM.request('waitServerChoices') def startTimer(self): now = globalClock.getFrameTime() elapsed = now - self.timerStartTime self.timer.posInTopRightCorner() self.timer.setTime(IceGameGlobals.InputTimeout) self.timer.countdown(IceGameGlobals.InputTimeout - elapsed, self.handleChoiceTimeout) self.timer.show() def setTimerStartTime(self, timestamp): if not self.hasLocalToon: return self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp) if self.timer != None: self.startTimer() return def handleChoiceTimeout(self): self.sendUpdate('setAvatarChoice', [0, 0]) self.gameFSM.request('waitServerChoices') def localTireNp(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]['tireNodePath'] return ret def localTireBody(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]['tireBody'] return ret def getTireBody(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]['tireBody'] return ret def getTireNp(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]['tireNodePath'] return ret def updateForceArrow(self, avId, curHeading, curForce): forceArrow = self.forceArrowDict[avId] tireNp = self.tireDict[avId]['tireNodePath'] tireNp.setH(curHeading) tireBody = self.tireDict[avId]['tireBody'] tireBody.setQuaternion(tireNp.getQuat()) self.notify.debug('curHeading = %s' % curHeading) yScale = curForce / 100.0 yScale *= 1 headY = yScale * 15 xScale = (yScale - 1) / 2.0 + 1.0 shaft = forceArrow.find('**/arrow_shaft') head = forceArrow.find('**/arrow_head') shaft.setScale(xScale, yScale, 1) head.setPos(0, headY, 0) head.setScale(xScale, xScale, 1) def updateLocalForceArrow(self): avId = self.localAvId self.b_setForceArrowInfo(avId, self.curHeading, self.curForce) def __aimTask(self, task): if not hasattr(self, 'arrowKeys'): return task.done dt = globalClock.getDt() headingMomentumChange = dt * 60.0 forceMomentumChange = dt * 160.0 arrowUpdate = False arrowRotating = False arrowUp = False arrowDown = False if self.arrowKeys.upPressed() and not self.arrowKeys.downPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce += self.forceMomentum * dt arrowUpdate = True if oldForce < self.MaxLocalForce: arrowUp = True elif self.arrowKeys.downPressed() and not self.arrowKeys.upPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce -= self.forceMomentum * dt arrowUpdate = True if oldForce > 0.01: arrowDown = True else: self.forceMomentum = 0 if self.arrowKeys.leftPressed() and not self.arrowKeys.rightPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading += self.headingMomentum * dt arrowUpdate = True arrowRotating = True elif self.arrowKeys.rightPressed() and not self.arrowKeys.leftPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading -= self.headingMomentum * dt arrowUpdate = True arrowRotating = True else: self.headingMomentum = 0 if arrowUpdate: self.normalizeHeadingAndForce() self.updateLocalForceArrow() if arrowRotating: if not self.arrowRotateSound.status() == self.arrowRotateSound.PLAYING: base.playSfx(self.arrowRotateSound, looping=True) else: self.arrowRotateSound.stop() if arrowUp: if not self.arrowUpSound.status() == self.arrowUpSound.PLAYING: base.playSfx(self.arrowUpSound, looping=False) else: self.arrowUpSound.stop() if arrowDown: if not self.arrowDownSound.status() == self.arrowDownSound.PLAYING: base.playSfx(self.arrowDownSound, looping=False) else: self.arrowDownSound.stop() return task.cont def normalizeHeadingAndForce(self): if self.curForce > self.MaxLocalForce: self.curForce = self.MaxLocalForce if self.curForce < 0.01: self.curForce = 0.01 def setTireInputs(self, tireInputs): if not self.hasLocalToon: return self.allTireInputs = tireInputs self.gameFSM.request('moveTires') def enableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]['tireBody'].enable() def disableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]['tireBody'].disable() def areAllTiresDisabled(self): for avId in self.tireDict.keys(): if self.tireDict[avId]['tireBody'].isEnabled(): return False return True def __moveTiresTask(self, task): if self.areAllTiresDisabled(): self.sendTirePositions() self.gameFSM.request('synch') return task.done return task.cont def sendTirePositions(self): tirePositions = [] for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) self.sendUpdate('endingPositions', [tirePositions]) def setFinalPositions(self, finalPos): if not self.hasLocalToon: return for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) def updateInfoLabel(self): self.infoLabel['text'] = TTLocalizer.IceGameInfo % {'curMatch': self.curMatch + 1, 'numMatch': IceGameGlobals.NumMatches, 'curRound': self.curRound + 1, 'numRound': IceGameGlobals.NumRounds} def setMatchAndRound(self, match, round): if not self.hasLocalToon: return self.curMatch = match self.curRound = round self.updateInfoLabel() def setScores(self, match, round, scores): if not self.hasLocalToon: return self.newMatch = match self.newRound = round self.newScores = scores def setNewState(self, state): if not self.hasLocalToon: return self.notify.debug('setNewState gameFSM=%s newState=%s' % (self.gameFSM, state)) self.gameFSM.request(state) def putAllTiresInStartingPositions(self): for index in xrange(len(self.avIdList)): avId = self.avIdList[index] np = self.tireDict[avId]['tireNodePath'] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]['tireBody'] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) for index in xrange(len(self.avIdList), 4): avId = -index np = self.tireDict[avId]['tireNodePath'] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]['tireBody'] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) def b_setForceArrowInfo(self, avId, force, heading): self.setForceArrowInfo(avId, force, heading) self.d_setForceArrowInfo(avId, force, heading) def d_setForceArrowInfo(self, avId, force, heading): sendIt = False curTime = self.getCurrentGameTime() if self.sendForceArrowUpdateAsap: sendIt = True elif curTime - self.lastForceArrowUpdateTime > 0.2: sendIt = True if sendIt: self.sendUpdate('setForceArrowInfo', [avId, force, heading]) self.sendForceArrowUpdateAsap = False self.lastForceArrowUpdateTime = self.getCurrentGameTime() def setForceArrowInfo(self, avId, force, heading): if not self.hasLocalToon: return self.updateForceArrow(avId, force, heading) def setupStartOfMatch(self): self.putAllTiresInStartingPositions() szId = self.getSafezoneId() self.numTreasures = IceGameGlobals.NumTreasures[szId] if self.treasures: for treasure in self.treasures: treasure.destroy() self.treasures = [] index = 0 treasureMargin = IceGameGlobals.TireRadius + 1.0 while len(self.treasures) < self.numTreasures: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newTreasure = IceTreasure.IceTreasure(self.treasureModel, pos, index, self.doId, penalty=False) goodSpot = True for obstacle in self.obstacles: if newTreasure.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newTreasure.nodePath.getDistance(treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.treasures.append(newTreasure) index += 1 else: newTreasure.destroy() self.numPenalties = IceGameGlobals.NumPenalties[szId] if self.penalties: for penalty in self.penalties: penalty.destroy() self.penalties = [] index = 0 while len(self.penalties) < self.numPenalties: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newPenalty = IceTreasure.IceTreasure(self.penaltyModel, pos, index, self.doId, penalty=True) goodSpot = True for obstacle in self.obstacles: if newPenalty.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newPenalty.nodePath.getDistance(treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: for penalty in self.penalties: if newPenalty.nodePath.getDistance(penalty.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.penalties.append(newPenalty) index += 1 else: newPenalty.destroy() def toonHitSomething(self, entry): self.notify.debug('---- treasure Enter ---- ') self.notify.debug('%s' % entry) name = entry.getIntoNodePath().getName() parts = name.split('-') if len(parts) < 3: self.notify.debug('collided with %s, but returning' % name) return if not int(parts[1]) == self.doId: self.notify.debug("collided with %s, but doId doesn't match" % name) return treasureNum = int(parts[2]) if 'penalty' in parts[0]: self.__penaltyGrabbed(treasureNum) else: self.__treasureGrabbed(treasureNum) def __treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.treasureGrabSound.play() self.sendUpdate('claimTreasure', [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return self.notify.debug('treasure %s grabbed by %s' % (treasureNum, avId)) if avId != self.localAvId: self.treasures[treasureNum].showGrab() i = self.avIdList.index(avId) self.scores[i] += 1 self.scorePanels[i].setScore(self.scores[i]) def __penaltyGrabbed(self, penaltyNum): self.penalties[penaltyNum].showGrab() self.sendUpdate('claimPenalty', [penaltyNum]) def setPenaltyGrabbed(self, avId, penaltyNum): if not self.hasLocalToon: return self.notify.debug('penalty %s grabbed by %s' % (penaltyNum, avId)) if avId != self.localAvId: self.penalties[penaltyNum].showGrab() i = self.avIdList.index(avId) self.scores[i] -= 1 self.scorePanels[i].setScore(self.scores[i]) def postStep(self): DistributedIceWorld.DistributedIceWorld.postStep(self) if not self.colCount: return for count in xrange(self.colCount): c0, c1 = self.getOrderedContacts(count) if c1 in self.tireCollideIds: tireIndex = self.tireCollideIds.index(c1) if c0 in self.tireCollideIds: self.tireSounds[tireIndex]['tireHit'].play() elif c0 == self.wallCollideId: self.tireSounds[tireIndex]['wallHit'].play() elif c0 == self.obstacleCollideId: self.tireSounds[tireIndex]['obstacleHit'].play() def forceLocalToonToTire(self): toon = localAvatar if toon and self.localAvId in self.tireDict: tireNp = self.tireDict[self.localAvId]['tireNodePath'] toon.reparentTo(tireNp) toon.setPosHpr(0, 0, 0, 0, 0, 0) toon.setY(1.0) toon.setZ(-3)
class DistributedGolfSpot(DistributedObject.DistributedObject, FSM.FSM): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGolfSpot') positions = ((-45, 100, GolfGlobals.GOLF_BALL_RADIUS), (-15, 100, GolfGlobals.GOLF_BALL_RADIUS), (15, 100, GolfGlobals.GOLF_BALL_RADIUS), (45, 100, GolfGlobals.GOLF_BALL_RADIUS)) toonGolfOffsetPos = Point3(-2, 0, -GolfGlobals.GOLF_BALL_RADIUS) toonGolfOffsetHpr = Point3(-90, 0, 0) rotateSpeed = 20 golfPowerSpeed = base.config.GetDouble('golf-power-speed', 3) golfPowerExponent = base.config.GetDouble('golf-power-exponent', 0.75) def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedGolfSpot') self.boss = None self.index = None self.avId = 0 self.toon = None self.golfSpotSmoother = SmoothMover() self.golfSpotSmoother.setSmoothMode(SmoothMover.SMOn) self.smoothStarted = 0 self.__broadcastPeriod = 0.2 if self.index > len(self.positions): self.notify.error('Invalid index %d' % index) self.fadeTrack = None self.setupPowerBar() self.aimStart = None self.golfSpotAdviceLabel = None self.changeSeq = 0 self.lastChangeSeq = 0 self.controlKeyAllowed = False self.flyBallTracks = {} self.splatTracks = {} self.__flyBallBubble = None self.flyBallHandler = None self.__flyBallSequenceNum = 0 self.swingInterval = None self.lastHitSequenceNum = -1 self.goingToReward = False self.gotHitByBoss = False self.releaseTrack = None self.grabTrack = None self.restoreScaleTrack = None return def setBossCogId(self, bossCogId): self.bossCogId = bossCogId self.boss = base.cr.doId2do[bossCogId] self.boss.setGolfSpot(self, self.index) def setIndex(self, index): self.index = index def disable(self): DistributedObject.DistributedObject.disable(self) self.ignoreAll() def delete(self): DistributedObject.DistributedObject.delete(self) self.ignoreAll() self.boss = None return def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) self.triggerName = self.uniqueName('trigger') self.triggerEvent = 'enter%s' % self.triggerName self.smoothName = self.uniqueName('golfSpotSmooth') self.golfSpotAdviceName = self.uniqueName('golfSpotAdvice') self.posHprBroadcastName = self.uniqueName('golfSpotBroadcast') self.ballPowerTaskName = self.uniqueName('updateGolfPower') self.adjustClubTaskName = self.uniqueName('adjustClub') self.loadAssets() self.accept('flyBallHit-%d' % self.index, self.__flyBallHit) def loadAssets(self): self.root = render.attachNewNode('golfSpot-%d' % self.index) self.root.setPos(*self.positions[self.index]) self.ballModel = loader.loadModel('phase_6/models/golf/golf_ball') self.ballColor = VBase4(1, 1, 1, 1) if self.index < len(GolfGlobals.PlayerColors): self.ballColor = VBase4(*GolfGlobals.PlayerColors[self.index]) self.ballModel.setColorScale(self.ballColor) self.ballModel.reparentTo(self.root) self.club = loader.loadModel('phase_6/models/golf/putter') self.clubLookatSpot = self.root.attachNewNode('clubLookat') self.clubLookatSpot.setY(-(GolfGlobals.GOLF_BALL_RADIUS + 0.1)) cs = CollisionSphere(0, 0, 0, 1) cs.setTangible(0) cn = CollisionNode(self.triggerName) cn.addSolid(cs) cn.setIntoCollideMask(ToontownGlobals.WallBitmask) self.trigger = self.root.attachNewNode(cn) self.trigger.stash() self.hitBallSfx = loader.loadSfx('phase_6/audio/sfx/Golf_Hit_Ball.ogg') def cleanup(self): if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if self.releaseTrack: self.releaseTrack.finish() self.releaseTrack = None flyTracks = self.flyBallTracks.values() for track in flyTracks: track.finish() if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None if self.restoreScaleTrack: self.restoreScaleTrack.finish() self.restoreScaleTrack = None self.root.removeNode() self.ballModel.removeNode() self.club.removeNode() if self.powerBar: self.powerBar.destroy() self.powerBar = None taskMgr.remove(self.triggerName) self.boss = None return def setState(self, state, avId, extraInfo): if not self.isDisabled(): self.gotHitByBoss = extraInfo if state == 'C': self.demand('Controlled', avId) elif state == 'F': self.demand('Free') elif state == 'O': self.demand('Off') else: self.notify.error('Invalid state from AI: %s' % state) def enterOff(self): pass def exitOff(self): pass def enterFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack = Sequence(Wait(6), self.getRestoreScaleInterval(), name='restoreScaleTrack') self.restoreScaleTrack.start() if self.avId == localAvatar.doId: if not self.isDisabled(): self.ballModel.setAlphaScale(0.3) self.ballModel.setTransparency(1) taskMgr.doMethodLater(5, self.__allowDetect, self.triggerName) self.fadeTrack = Sequence(Func(self.ballModel.setTransparency, 1), self.ballModel.colorScaleInterval(0.2, VBase4(1, 1, 1, 0.3)), name='fadeTrack-enterFree') self.fadeTrack.start() else: self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) self.avId = 0 return def exitFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack.finish() self.restoreScaleTrack = None taskMgr.remove(self.triggerName) self.ballModel.clearTransparency() self.trigger.stash() self.ignore(self.triggerEvent) return def enterControlled(self, avId): self.avId = avId toon = base.cr.doId2do.get(avId) if not toon: return self.enableControlKey() self.toon = toon self.grabTrack = self.makeToonGrabInterval(toon) if avId == localAvatar.doId: self.boss.toCraneMode() camera.reparentTo(self.root) camera.setPosHpr(0, -10, 3, 0, 0, 0) localAvatar.setPos(self.root, self.toonGolfOffsetPos) localAvatar.setHpr(self.root, self.toonGolfOffsetHpr) localAvatar.sendCurrentPosition() self.__enableControlInterface() self.startPosHprBroadcast() self.accept('exitCrane', self.gotBossZapped) self.grabTrack.start() def exitControlled(self): self.grabTrack.finish() del self.grabTrack if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if not self.ballModel.isEmpty(): if self.ballModel.isHidden(): self.notify.debug('ball is hidden scale =%s' % self.ballModel.getScale()) else: self.notify.debug('ball is showing scale=%s' % self.ballModel.getScale()) if self.toon and not self.toon.isDisabled(): self.toon.startSmooth() self.releaseTrack = self.makeToonReleaseInterval(self.toon) self.stopPosHprBroadcast() self.stopSmooth() if self.avId == localAvatar.doId: self.__disableControlInterface() if not self.goingToReward: camera.reparentTo(base.localAvatar) camera.setPos(base.localAvatar.cameraPositions[0][0]) camera.setHpr(0, 0, 0) self.stopAdjustClubTask() self.releaseTrack.start() self.enableControlKey() return def __allowDetect(self, task): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = Sequence(self.ballModel.colorScaleInterval(0.2, self.ballColor), Func(self.ballModel.clearTransparency), name='fadeTrack-allowDetect') self.fadeTrack.start() self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) def __hitTrigger(self, event): self.d_requestControl() def getRestoreScaleInterval(self): return Sequence() def d_requestControl(self): self.sendUpdate('requestControl') def d_requestFree(self, gotHitByBoss): self.sendUpdate('requestFree', [gotHitByBoss]) def makeToonGrabInterval(self, toon): origPos = toon.getPos(self.root) origHpr = toon.getHpr(self.root) a = self.accomodateToon(toon) newPos = toon.getPos() newHpr = toon.getHpr() origHpr.setX(PythonUtil.fitSrcAngle2Dest(origHpr[0], newHpr[0])) self.notify.debug('toon.setPosHpr %s %s' % (origPos, origHpr)) toon.setPosHpr(origPos, origHpr) walkTime = 0.2 reach = Sequence() if reach.getDuration() < walkTime: reach = Sequence(ActorInterval(toon, 'walk', loop=1, duration=walkTime - reach.getDuration()), reach) i = Sequence(Parallel(toon.posInterval(walkTime, newPos, origPos), toon.hprInterval(walkTime, newHpr, origHpr), reach), Func(toon.stopLookAround)) if toon == base.localAvatar: i.append(Func(self.switchToAnimState, 'GolfPuttLoop')) i.append(Func(self.startAdjustClubTask)) i = Parallel(i, a) return i def accomodateToon(self, toon): toon.wrtReparentTo(self.root) toon.setPos(self.toonGolfOffsetPos) toon.setHpr(self.toonGolfOffsetHpr) return Sequence() def switchToAnimState(self, animStateName, forced = False): curAnimState = base.localAvatar.animFSM.getCurrentState() curAnimStateName = '' if curAnimState: curAnimStateName = curAnimState.getName() if curAnimStateName != animStateName or forced: base.localAvatar.b_setAnimState(animStateName) def __enableControlInterface(self): gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=2, text=TTLocalizer.BossbotGolfSpotLeave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(1.05, 0, -0.82), command=self.__exitGolfSpot) self.accept('escape', self.__exitGolfSpot) self.accept(base.JUMP, self.__controlPressed) self.accept(base.JUMP + '-up', self.__controlReleased) self.accept('InputState-forward', self.__upArrow) self.accept('InputState-reverse', self.__downArrow) self.accept('InputState-turnLeft', self.__leftArrow) self.accept('InputState-turnRight', self.__rightArrow) taskMgr.add(self.__watchControls, 'watchGolfSpotControls') taskMgr.doMethodLater(5, self.__displayGolfSpotAdvice, self.golfSpotAdviceName) self.arrowVert = 0 self.arrowHorz = 0 if self.powerBar: self.powerBar.show() return def __disableControlInterface(self): if self.closeButton: self.closeButton.destroy() self.closeButton = None self.__cleanupGolfSpotAdvice() self.ignore('escape') self.ignore(base.JUMP) self.ignore('control-up') self.ignore('InputState-forward') self.ignore('InputState-reverse') self.ignore('InputState-turnLeft') self.ignore('InputState-turnRight') self.arrowVert = 0 self.arrowHorz = 0 taskMgr.remove('watchGolfSpotControls') if self.powerBar: self.powerBar.hide() else: self.notify.debug('self.powerBar is none') return def setupPowerBar(self): self.powerBar = DirectWaitBar(pos=(0.0, 0, -0.94), relief=DGG.SUNKEN, frameSize=(-2.0, 2.0, -0.2, 0.2), borderWidth=(0.02, 0.02), scale=0.25, range=100, sortOrder=50, frameColor=(0.5, 0.5, 0.5, 0.5), barColor=(1.0, 0.0, 0.0, 1.0), text='', text_scale=0.26, text_fg=(1, 1, 1, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05)) self.power = 0 self.powerBar['value'] = self.power self.powerBar.hide() def resetPowerBar(self): self.power = 0 self.powerBar['value'] = self.power self.powerBar['text'] = '' def __displayGolfSpotAdvice(self, task): if self.golfSpotAdviceLabel == None: self.golfSpotAdviceLabel = DirectLabel(text=TTLocalizer.BossbotGolfSpotAdvice, text_fg=VBase4(1, 1, 1, 1), text_align=TextNode.ACenter, relief=None, pos=(0, 0, 0.69), scale=0.1) return def __cleanupGolfSpotAdvice(self): if self.golfSpotAdviceLabel: self.golfSpotAdviceLabel.destroy() self.golfSpotAdviceLabel = None taskMgr.remove(self.golfSpotAdviceName) return def showExiting(self): if self.closeButton: self.closeButton.destroy() self.closeButton = DirectLabel(relief=None, text=TTLocalizer.BossbotGolfSpotLeaving, pos=(1.05, 0, -0.88), text_pos=(0, 0), text_scale=0.06, text_fg=VBase4(1, 1, 1, 1)) self.__cleanupGolfSpotAdvice() return def __exitGolfSpot(self): self.d_requestFree(False) def __controlPressed(self): if self.controlKeyAllowed: self.__beginFireBall() def __controlReleased(self): if self.controlKeyAllowed: self.__endFireBall() def __upArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = 1 elif self.arrowVert > 0: self.arrowVert = 0 def __downArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = -1 elif self.arrowVert < 0: self.arrowVert = 0 def __rightArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = 1 self.switchToAnimState('GolfRotateLeft') elif self.arrowHorz > 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __leftArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = -1 self.switchToAnimState('GolfRotateRight') elif self.arrowHorz < 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __watchControls(self, task): if self.arrowHorz: self.__moveGolfSpot(self.arrowHorz) return Task.cont def __moveGolfSpot(self, xd): dt = globalClock.getDt() h = self.root.getH() - xd * self.rotateSpeed * dt h %= 360 limitH = h self.root.setH(limitH) def __incrementChangeSeq(self): self.changeSeq = self.changeSeq + 1 & 255 def __beginFireBall(self): if self.aimStart != None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return time = globalClock.getFrameTime() self.aimStart = time messenger.send('wakeup') taskMgr.add(self.__updateBallPower, self.ballPowerTaskName) return def __endFireBall(self): if self.aimStart == None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return taskMgr.remove(self.ballPowerTaskName) self.disableControlKey() messenger.send('wakeup') self.aimStart = None power = self.power angle = self.root.getH() self.notify.debug('incrementing self.__flyBallSequenceNum') self.__flyBallSequenceNum = (self.__flyBallSequenceNum + 1) % 255 self.sendSwingInfo(power, angle, self.__flyBallSequenceNum) self.setSwingInfo(power, angle, self.__flyBallSequenceNum) self.resetPowerBar() return def __updateBallPower(self, task): if not self.powerBar: print '### no power bar!!!' return task.done newPower = self.__getBallPower(globalClock.getFrameTime()) self.power = newPower self.powerBar['value'] = newPower return task.cont def __getBallPower(self, time): elapsed = max(time - self.aimStart, 0.0) t = elapsed / self.golfPowerSpeed t = math.pow(t, self.golfPowerExponent) power = int(t * 100) % 200 if power > 100: power = 200 - power return power def stopPosHprBroadcast(self): taskName = self.posHprBroadcastName taskMgr.remove(taskName) def startPosHprBroadcast(self): taskName = self.posHprBroadcastName self.b_clearSmoothing() self.d_sendGolfSpotPos() taskMgr.remove(taskName) taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) def __posHprBroadcast(self, task): self.d_sendGolfSpotPos() taskName = self.posHprBroadcastName taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) return Task.done def d_sendGolfSpotPos(self): timestamp = globalClockDelta.getFrameNetworkTime() self.sendUpdate('setGolfSpotPos', [self.changeSeq, self.root.getH(), timestamp]) def setGolfSpotPos(self, changeSeq, h, timestamp): self.changeSeq = changeSeq if self.smoothStarted: now = globalClock.getFrameTime() local = globalClockDelta.networkToLocalTime(timestamp, now) self.golfSpotSmoother.setH(h) self.golfSpotSmoother.setTimestamp(local) self.golfSpotSmoother.markPosition() else: self.root.setH(h) def b_clearSmoothing(self): self.d_clearSmoothing() self.clearSmoothing() def d_clearSmoothing(self): self.sendUpdate('clearSmoothing', [0]) def clearSmoothing(self, bogus = None): self.golfSpotSmoother.clearPositions(1) def doSmoothTask(self, task): self.golfSpotSmoother.computeAndApplySmoothHpr(self.root) return Task.cont def startSmooth(self): if not self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.reloadPosition() taskMgr.add(self.doSmoothTask, taskName) self.smoothStarted = 1 def stopSmooth(self): if self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.forceToTruePosition() self.smoothStarted = 0 def makeToonReleaseInterval(self, toon): def getSlideToPos(toon = toon): return render.getRelativePoint(toon, Point3(0, -5, 0)) if self.gotHitByBoss: grabIval = Sequence(Func(self.detachClub), name='makeToonReleaseInterval-gotHitByBoss') if not toon.isEmpty(): toonIval = Sequence(Func(toon.wrtReparentTo, render), Parallel(ActorInterval(toon, 'slip-backward'), toon.posInterval(0.5, getSlideToPos, fluid=1)), name='makeToonReleaseInterval-toonIval') grabIval.append(toonIval) else: grabIval = Sequence(Func(self.detachClub)) if not toon.isEmpty(): toonIval = Sequence(Parallel(ActorInterval(toon, 'walk', duration=1.0, playRate=-1.0), LerpPosInterval(toon, duration=1.0, pos=Point3(-10, 0, 0))), Func(toon.wrtReparentTo, render)) grabIval.append(toonIval) if localAvatar.doId == toon.doId: if not self.goingToReward and toon.hp > 0: grabIval.append(Func(self.goToFinalBattle)) grabIval.append(Func(self.notify.debug, 'goingToFinalBattlemode')) grabIval.append(Func(self.safeBossToFinalBattleMode)) return grabIval def safeBossToFinalBattleMode(self): if self.boss: self.boss.toFinalBattleMode() def goToFinalBattle(self): if self.cr: place = self.cr.playGame.getPlace() if place and hasattr(place, 'fsm'): curState = place.fsm.getCurrentState().getName() if place.fsm.getCurrentState().getName() == 'crane': place.setState('finalBattle') else: self.notify.debug('NOT going to final battle, state=%s' % curState) def attachClub(self, avId, pointToBall = False): club = self.club if club: av = base.cr.doId2do.get(avId) if av: av.useLOD(1000) lHand = av.getLeftHands()[0] club.setPos(0, 0, 0) club.reparentTo(lHand) netScale = club.getNetTransform().getScale()[1] counterActToonScale = lHand.find('**/counteractToonScale') if counterActToonScale.isEmpty(): counterActToonScale = lHand.attachNewNode('counteractToonScale') counterActToonScale.setScale(1 / netScale) self.notify.debug('creating counterActToonScale for %s' % av.getName()) club.reparentTo(counterActToonScale) club.setX(-0.25 * netScale) if pointToBall: club.lookAt(self.clubLookatSpot) def detachClub(self): if not self.club.isEmpty(): self.club.reparentTo(self.root) self.club.setZ(-20) self.club.setScale(1) def adjustClub(self): club = self.club if club: distance = club.getDistance(self.clubLookatSpot) scaleFactor = distance / 2.058 club.setScale(1, scaleFactor, 1) def startAdjustClubTask(self): taskMgr.add(self.adjustClubTask, self.adjustClubTaskName) def stopAdjustClubTask(self): taskMgr.remove(self.adjustClubTaskName) def adjustClubTask(self, task): self.attachClub(self.avId, True) self.adjustClub() return task.cont def enableControlKey(self): self.controlKeyAllowed = True def disableControlKey(self): self.controlKeyAllowed = False def sendSwingInfo(self, power, angle, sequenceNum): self.sendUpdate('setSwingInfo', [power, angle, sequenceNum]) def startBallPlayback(self, power, angle, sequenceNum): flyBall = self.ballModel.copyTo(NodePath()) flyBall.setScale(1.0) flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath()) flyBallBubble.reparentTo(flyBall) flyBall.setTag('pieSequence', str(sequenceNum)) flyBall.setTag('throwerId', str(self.avId)) t = power / 100.0 t = 1.0 - t dist = 300 - 200 * t time = 1.5 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(root = self.root, relVel = relVel): return render.getRelativeVector(root, relVel) fly = Sequence(Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel=getVelocity, duration=3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, 'removed collider'), Func(self.flyBallFinishedFlying, sequenceNum)) flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node=self.root), name='flyWithSound') self.notify.debug('starting flyball track') flyWithSound.start() self.flyBallTracks[sequenceNum] = flyWithSound return def setSwingInfo(self, power, angle, sequenceNum): av = base.cr.doId2do.get(self.avId) self.swingInterval = Sequence() if av: self.stopAdjustClubTask() self.swingInterval = Sequence(ActorInterval(av, 'swing-putt', startFrame=0, endFrame=GolfGlobals.BALL_CONTACT_FRAME), Func(self.startBallPlayback, power, angle, sequenceNum), Func(self.ballModel.hide), ActorInterval(av, 'swing-putt', startFrame=GolfGlobals.BALL_CONTACT_FRAME, endFrame=24), Func(self.ballModel.setScale, 0.1), Func(self.ballModel.show), LerpScaleInterval(self.ballModel, 1.0, Point3(1, 1, 1)), Func(self.enableControlKey)) if av == localAvatar: self.swingInterval.append(Func(self.switchToAnimState, 'GolfPuttLoop', True)) self.swingInterval.start() def getFlyBallBubble(self): if self.__flyBallBubble == None: bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS) node = CollisionNode('flyBallBubble') node.addSolid(bubble) node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) node.setIntoCollideMask(BitMask32.allOff()) self.__flyBallBubble = NodePath(node) self.flyBallHandler = CollisionHandlerEvent() self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index) return self.__flyBallBubble def __flyBallHit(self, entry): print entry def flyBallFinishedFlying(self, sequence): if sequence in self.flyBallTracks: del self.flyBallTracks[sequence] def __finishFlyBallTrack(self, sequence): if sequence in self.flyBallTracks: flyBallTrack = self.flyBallTracks[sequence] del self.flyBallTracks[sequence] flyBallTrack.finish() def flyBallFinishedSplatting(self, sequence): if sequence in self.splatTracks: del self.splatTracks[sequence] def __flyBallHit(self, entry): if not entry.hasSurfacePoint() or not entry.hasInto(): return if not entry.getInto().isTangible(): return sequence = int(entry.getFromNodePath().getNetTag('pieSequence')) self.__finishFlyBallTrack(sequence) if sequence in self.splatTracks: splatTrack = self.splatTracks[sequence] del self.splatTracks[sequence] splatTrack.finish() flyBallCode = 0 flyBallCodeStr = entry.getIntoNodePath().getNetTag('pieCode') if flyBallCodeStr: flyBallCode = int(flyBallCodeStr) pos = entry.getSurfacePoint(render) timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32) throwerId = int(entry.getFromNodePath().getNetTag('throwerId')) splat = self.getFlyBallSplatInterval(pos[0], pos[1], pos[2], flyBallCode, throwerId) splat = Sequence(splat, Func(self.flyBallFinishedSplatting, sequence)) self.splatTracks[sequence] = splat splat.start() self.notify.debug('doId=%d into=%s flyBallCode=%d, throwerId=%d' % (self.doId, entry.getIntoNodePath(), flyBallCode, throwerId)) if flyBallCode == ToontownGlobals.PieCodeBossCog and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum self.boss.d_ballHitBoss(1) elif flyBallCode == ToontownGlobals.PieCodeToon and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum avatarDoId = entry.getIntoNodePath().getNetTag('avatarDoId') if avatarDoId == '': self.notify.warning('Toon %s has no avatarDoId tag.' % repr(entry.getIntoNodePath())) return doId = int(avatarDoId) if doId != localAvatar.doId: pass def getFlyBallSplatInterval(self, x, y, z, flyBallCode, throwerId): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps splatName = 'dust' splat = BattleProps.globalPropPool.getProp(splatName) splat.setBillboardPointWorld(2) color = ToontownGlobals.PieCodeColors.get(flyBallCode) if color: splat.setColor(*color) if flyBallCode == ToontownGlobals.PieCodeBossCog: self.notify.debug('changing color to %s' % self.ballColor) splat.setColor(self.ballColor) sound = loader.loadSfx('phase_11/audio/sfx/LB_evidence_miss.ogg') vol = 1.0 if flyBallCode == ToontownGlobals.PieCodeBossCog: sound = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') soundIval = SoundInterval(sound, node=splat, volume=vol) if flyBallCode == ToontownGlobals.PieCodeBossCog and localAvatar.doId == throwerId: vol = 1.0 soundIval = SoundInterval(sound, node=localAvatar, volume=vol) ival = Parallel(Func(splat.reparentTo, render), Func(splat.setPos, x, y, z), soundIval, Sequence(ActorInterval(splat, splatName), Func(splat.detachNode))) return ival def setGoingToReward(self): self.goingToReward = True def gotBossZapped(self): self.showExiting() self.d_requestFree(True)
mpos=base.mouseWatcherNode.getMouse() # 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'])
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 Load(): def __init__(self): # import leap motion self.leap = leapmotion.LeapMotion() # disable mouse control base.disableMouse() render.hide() self.inGame = True # menu music # taken from https://www.youtube.com/watch?v=2iEWbHJDlo4&list=PLzCxunOM5WFIudfMTgJzXkOE-xbVWrpIF&index=7 self.starterMusic = loader.loadMusic( 'musics/starterMenuBackground.ogg') self.starterMusic.setLoop(True) # taken form https://www.youtube.com/watch?v=I0vEzblcnPA&list=PLzCxunOM5WFIudfMTgJzXkOE-xbVWrpIF&index=18 self.endMusic = loader.loadMusic('musics/endMusic.ogg') self.endMusic.setLoop(True) # game music from https://www.youtube.com/watch?v=mNFNOEi9QV4&list=PLzCxunOM5WFK7WGa3wGjlONp_9R66a2zz&index=8 self.gameMusic = loader.loadMusic('musics/gameMusic.ogg') self.gameMusic.setLoop(True) # import flybot, enemy, door, chests, key, and player self.flyBot = FlyBot() self.player = player.Player(self.flyBot) self.enemies = [] self.numbEnemies = 0 keyChest = random.randint(0, 3) # self.key = Key(keyChest) self.door = Door(225, 190, self.flyBot) self.walls = [] self.chests = [] def startGame(self): # Load the map. self.environ = loader.loadModel("models/background_model") # Reparent the model to render. self.environ.reparentTo(render) # Apply scale and position transforms on the model. # image taken from http://motorbikes-passion.info/scary-dark-room.html myTexture = loader.loadTexture("models/backgroundtexture.jpg") self.environ.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldCubeMap) self.environ.setTexture(myTexture) self.environ.setScale(1, 1, 1) self.environ.setPos(0, 0, 0) self.environ.reparentTo(render) # random generate map self.numbWalls = 4 walls = generateRoom([], self.numbWalls) # if random generation fails, input default map if walls == None: walls = [(120, 30, 0), (-100, 80, 90), (-130, -70, 0), (50, -50, 90)] # load wall models in respective location for wall in walls: x, y, angle = wall newWall = Wall(x, y, angle) self.walls.append(newWall) # generate chests in random areas chests = generateChestLocation(walls) for chest in chests: x, y, chestNumb = chest newChest = Chest(self.player, self.flyBot, x, y, chestNumb) self.chests.append(newChest) # display player stats self.display = self.player.displayStats() # run collision settings base.cTrav = CollisionTraverser() # Set up collision for environment self.backgroundCollide = CollisionRay() self.backgroundNode = CollisionNode('backgroundCollider') self.backgroundNode.addSolid(self.backgroundCollide) self.backgroundNode.setFromCollideMask(CollideMask.bit(0)) self.backgroundNode.setIntoCollideMask(CollideMask.allOff()) self.backgroundCollider = self.environ.attachNewNode( self.backgroundNode) # call all functions that deal with collisions taskMgr.add(self.swordHitEnemy, 'killEnemy') self.wallCollisions() taskMgr.add(self.fireballHitPlayer, 'fireballHits') # load sound effects # sound taken from https://bigsoundbank.com/detail-0129-sword.html self.swordCut = loader.loadSfx('musics/0129.ogg') # sound taken from https://bigsoundbank.com/detail-0437-shot-beretta-m12-9-mm.html self.fireballHit = loader.loadSfx('musics/0437.ogg') # run quitGame self.quitGame() # Set up initial camera position base.camera.setPos(0, 0, 0) base.camera.setHpr(0, 0, 0) base.camera.reparentTo(self.flyBot.flyBot) # import player controls from player file self.playerControl = player.KeyboardControl(self.flyBot, self.chests, self.door, self.walls, self.player) # import leap motion control self.leapControl = player.swordControl(self.leap, self.player) taskMgr.add(self.leapControl.swingsword, 'swingsword') # spawn new enemies sec = 5 - self.player.atLevel taskMgr.doMethodLater(sec, self.spawnEnemies, 'createNewEnemy') # test enemy movements taskMgr.add(self.enemyMovements, 'enemyMovements') # Game AI AI = GameAI(self.enemies, self.flyBot) taskMgr.add(AI.makeDecision, 'enemyStateDetermination') # stop all tasks def stopGame(self): taskMgr.remove('checkGameState') taskMgr.remove('enemyStateDetermination') taskMgr.remove('enemyMovements') taskMgr.remove('createNewEnemy') taskMgr.remove('swingsword') taskMgr.remove('fireballHits') taskMgr.remove('killEnemy') taskMgr.remove("playerMove") taskMgr.remove('openChestOrDoor') taskMgr.remove('moveFireball') taskMgr.remove('fireFireballs') # allow keyboard exit def quitGame(self): textObject = OnscreenText(text='ESC to exit game', pos=(-0.25, -0.05), scale=0.05, parent=base.a2dTopRight) # The key esc will exit the game base.accept('escape', sys.exit) # create new enemies def spawnEnemies(self, task): if len(self.enemies) < 20: # default state is stay self.numbEnemies += 1 newEnemy = enemy.Enemy(1, self.numbEnemies, self.player) self.enemies.append(newEnemy) task.delayTime += 1 return task.again # moves the enemies towards the player def enemyMovements(self, task): for enemy in self.enemies: enemy.lookAtPlayer(self.flyBot) if enemy.state == 0: enemy.move(self.flyBot.flyBot) if enemy.state == 2: randomChest = random.randint(0, 3) doorOrChest = random.randint( [self.door.door, self.chests[randomChest].chestModel]) enemy.move(doorOrChest) return task.cont # Collision functions, called in init def wallCollisions(self): # Pusher so that the player cannot move past the walls self.playerPusher = CollisionHandlerPusher() base.cTrav.addCollider(self.flyBot.playerCollider, self.playerPusher) self.playerPusher.addCollider(self.flyBot.playerCollider, self.flyBot.flyBot) self.enemyPusher = CollisionHandlerPusher() for enemy in self.enemies: base.cTrav.addCollider(enemy.collider, self.enemyPusher) self.enemyPusher.addCollider(enemy.collider, enemy.enemyModel) def swordHitEnemy(self, task): # When the sword collides with enemy, enemy dies for enemy in self.enemies: self.playerKill = CollisionHandlerEvent() base.cTrav.addCollider(enemy.collider, self.playerKill) self.playerKill.addInPattern('%fn-into-%in') # perform the task self.kill = DirectObject() self.kill.accept('enemy' + str(enemy.numb) + '-into-swordCollider', enemy.killEnemy) self.swordHit = DirectObject() self.swordHit.accept( 'enemy' + str(enemy.numb) + '-into-swordCollider', self.swordHitSound) if not enemy.isAlive: self.enemies.remove(enemy) return task.cont # play the sound when the sword hits an ememy def swordHitSound(self, *args): if self.player.damage: self.swordCut.play() # create collision system for fireballs based on the location of the player # and the location of a given enemy def fireballHitPlayer(self, task): for enemy in self.enemies: if enemy.fireballFired.isLive: # When fireball collides with player, player health reduces playerX = self.flyBot.flyBot.getX() playerY = self.flyBot.flyBot.getY() margin = 5 enemyH = math.sin(math.radians(enemy.enemyModel.getH())) fireballX = enemy.enemyModel.getX() fireballY = enemy.enemyModel.getY( ) + enemyH * enemy.fireballFired.fireball.getY() enemyY = enemy.enemyModel.getY() playerH = self.flyBot.flyBot.getH() if abs(fireballY) > 230 or abs(fireballX) > 230: enemy.fireballFired.removeFireball(task) if (playerH > -45 and playerH < 45) or (playerH > 135) or (playerH < -135): if playerX - margin <= fireballX and playerX + margin >= fireballX: if (abs(enemy.enemyModel.getH()) <= 45 and fireballY >= playerY) or\ (abs(enemy.enemyModel.getH()) >= 135 and fireballY <= playerY): self.fireballHit.play() self.player.changeStats(-5, 0) enemy.fireballFired.removeFireball(task) else: if playerY - margin <= fireballY and playerY + margin >= fireballY: if (enemy.enemyModel.getH() <= 0 and fireballX >= playerX) or\ (enemy.enemyModel.getH() > 0 and fireballX <= playerX): self.fireballHit.play() self.player.changeStats(-5, 0) enemy.fireballFired.removeFireball(task) return task.cont
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.imageObject = OnscreenImage(image = 'earth.jpg', pos = (0, 1, 0)) self.imageObject.setScale(1.9,1,1) tpRed = TextProperties() tpRed.setTextColor(1, 1, 1, 1) tpSlant = TextProperties() tpSlant.setSlant(0.3) tpRoman = TextProperties() cmr12 = loader.loadFont('cmr12.egg') tpRoman.setFont(cmr12) tpMgr = TextPropertiesManager.getGlobalPtr() tpMgr.setProperties("red", tpRed) tpMgr.setProperties("slant", tpSlant) tpMgr.setProperties("roman", tpRoman) self.textObject = OnscreenText(text = '\1red\1\1roman\1\1slant\1Space Collector', pos = (-0.6, 0.4), scale = 0.2) self.textScore=0 self.b = DirectButton(text = ("Start", "Start", "Start", "disabled"),command=self.beginGame) self.b.setScale(0.1,0.1,0.1) self.b.setPos(0.7,0,-0.8) myMaterial = Material() myMaterial.setShininess(1000) myMaterial.setDiffuse(VBase4(0.5,0.5,0.5,1)) myMaterial.setAmbient(VBase4(5,5,5,1)) myMaterial.setSpecular(VBase4(10,10,10,1)) myTexture = loader.loadTexture("maps/grayjumpjetTexture.tif") self.ship = loader.loadModel("GrayJumpJet") self.ship.setScale(0.15, 0.3, 0.15) self.ship.setPos(0,0,0) self.ship.setTexture(myTexture,1) self.ship.reparentTo(render) self.slab = loader.loadModel("box") self.slab.find("**/Cube;+h").setCollideMask(BitMask32.bit(0)) self.slab.setScale(1.5,10,1) self.slab.setPos(0,0,-1) self.slab.setHpr(0,0,0) self.slab.setMaterial(myMaterial) self.slab.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition) self.slab.setTexProjector(TextureStage.getDefault(), render, self.slab) self.slab.setTexture(loader.loadTexture("maps/crate_Material_#11_CL.tif"),1) self.junk = [None]*100 self.loadJunk() self.createTrack() base.trackball.node().setPos(0, 20, -4) self.acceleration=0 self.velocity=0 self.yPos=0 render.setShaderAuto() self.cTrav = CollisionTraverser() self.shipGroundRay = CollisionRay() self.shipGroundRay.setOrigin(0,0,1000) self.shipGroundRay.setDirection(0,0,-1) self.shipGroundCol = CollisionNode('shipRay') self.shipGroundCol.addSolid(self.shipGroundRay) self.shipGroundCol.setFromCollideMask(BitMask32.bit(0)) self.shipGroundCol.setIntoCollideMask(BitMask32.allOff()) self.shipGroundColNp = self.ship.attachNewNode(self.shipGroundCol) self.shipGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.shipGroundColNp, self.shipGroundHandler) self.collHandEvent = CollisionHandlerEvent() # add the into pattern with fromObject-into-thisObject self.collHandEvent.addInPattern( 'into-%in' ) self.accept("into-Junk",self.cHandler) bkground = loader.loadModel("square") bkground.reparentTo(camera) bkground.setScale(300,170,50) tex = loader.loadTexture("earth2.jpg") bkground.setTexture(tex,1) bkground.setPos(0,299,0) bkground.setHpr(0,90,0) base.camLens.setFar(300) self.mySound = loader.loadMusic("coinslot1.wav") self.timer=60 self.textTimer=0 self.prevY=0 self.prevX=0 self.shipGroundColNp.show() #self.camGroundColNp.show() self.collided=1 self.jumpTime=0 self.jumpOn=0 self.curZ=0 self.interval=0 self.zPosition=0 self.isGameOver=0 self.score=0 # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) if base.mouseWatcherNode.hasMouse(): self.prevX=base.mouseWatcherNode.getMouseX() self.prevY=base.mouseWatcherNode.getMouseY() def beginGame(self): self.textObject.destroy() self.imageObject.destroy() self.b.destroy() props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) self.taskMgr.add(self.moveForward, "MoveForward") self.accept("mouse1",self.jump) self.textScore = OnscreenText(text = '\1red\1\1slant\1Score : 0', pos = (-0.8, 0.8), scale = 0.1) self.textTimer = OnscreenText(text = '\1red\1\1slant\1Time Left : 2:00', pos = (-0.8, 0.7), scale = 0.1) print 'GameBegin' def cHandler(self,collEntry): print "collision" def loadJunk(self): f = open('junk1.txt','r') x=f.readline() y=f.readline() z=f.readline() i=0 while x!="": self.junk[i] = loader.loadModel("rubbishset/rubbish-set.lwo") self.junk[i].setScale(0.5,1,0.5) self.junk[i].reparentTo(render) colSphere=self.initCollisionSphere(self.junk[i],"Junk") self.junk[i].setPos(int(x),int(y),int(z)) x=f.readline() y=f.readline() z=f.readline() i=i+1 def initCollisionSphere(self,node,name): bounds = node.getBounds() center = bounds.getCenter() radius = bounds.getRadius()*0.6 cNode = CollisionNode(name) cNode.addSolid(CollisionSphere(center,radius)) cNP=node.attachNewNode(cNode) cNP.show() return cNP def createTrack(self): f = open('track.txt','r') a = f.read(1) i=0 j=0 while(a!=""): if a=="\n": a=f.read(1) if(a==""): break nSlab = int(a) #print nSlab while nSlab!=0: placeholder = render.attachNewNode("Slab") placeholder.setColor(j*0.92*0.4,nSlab*nSlab*0.51,0.23,1) placeholder.setPos(j*3-7,i*15,nSlab-3) self.slab.instanceTo(placeholder) nSlab=nSlab-1 j=j+1 if(j==5): i=i+1 j=0 print i a=f.read(1) def moveForward(self, task): curX=0 curY=0 shipCollided=0 c=self.timer-int(task.time) self.textTimer.setText('\1red\1\1slant\1Time Left : '+str(int(c/60))+':'+str(c%60)) if base.mouseWatcherNode.hasMouse(): curX=base.mouseWatcherNode.getMouseX() curY=base.mouseWatcherNode.getMouseY() #if(curY>self.prevY+0.01): self.acceleration = self.acceleration+1 #if(curY<self.prevY-0.01): # self.acceleration = self.acceleration-1 if(self.acceleration<45 and self.acceleration>=0): self.velocity=self.acceleration*task.time self.yPos=self.velocity * task.time self.ship.setY(self.yPos) if self.prevX<curX-0.001: self.ship.setHpr(0,0,5) #Sequence(self.ship.hprInterval(0.1,Point3(0,0,10),self.ship.getHpr())).start() self.ship.setX(curX*8) self.prevX=curX elif self.prevX>curX+0.001: self.ship.setHpr(0,0,-5) #Sequence(self.ship.hprInterval(0.1,Point3(0,0,-10),self.ship.getHpr())).start() self.ship.setX(curX*8) self.prevX=curX else: #self.ship.setHpr(0,0,0) Sequence(self.ship.hprInterval(0.1,Point3(0,0,0),self.ship.getHpr())).start() #print yPos self.camera.setPos(0,self.yPos-25,4) #self.slnp.setPos(0,self.yPos+20,4) self.cTrav.traverse(render) entries = [] for i in range(self.shipGroundHandler.getNumEntries()): entry = self.shipGroundHandler.getEntry(i) entries.append(entry) entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "Cube"): self.zPosition=entries[0].getSurfacePoint(render).getZ() #self.ship.setZ(entries[0].getSurfacePoint(render).getZ()+1) print str(self.zPosition) + " "+str(self.ship.getZ()) if self.zPosition>=self.ship.getZ(): shipCollided=1 self.isGameOver=1 else: shipCollided=0 self.collided=1 print entries[0].getIntoNode().getName() + "collided" elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "Junk"): pZ=entries[0].getSurfacePoint(render).getZ() if(self.ship.getZ()<=pZ and self.ship.getZ()>=pZ-2): entries[0].getIntoNode().getParent(0).removeAllChildren() self.score=self.score+1000 self.timer=self.timer+20 self.textScore.setText('\1red\1\1slant\1Score : '+str(self.score)) self.mySound.play() print self.score else: self.collided=0 if shipCollided!=1: val=0 if(self.jumpOn==1): val=10 if(self.interval==0): self.interval=task.time self.curZ=self.ship.getZ() self.jumpTime=0 else: self.jumpTime=self.jumpTime+task.time-self.interval self.interval=task.time zPos = self.curZ + val*self.jumpTime - 12*self.jumpTime*self.jumpTime if(zPos<self.zPosition+1 and self.collided==1): zPos=self.zPosition+1 self.ship.setZ(zPos) self.accept("mouse1",self.jump) self.jumpOn=0 self.interval=0 else: self.ship.setZ(zPos) if zPos<-40: self.isGameOver=1 self.prevX=curX self.prevY=curY self.score=self.score+1 self.textScore.setText('\1red\1\1slant\1Score : '+str(self.score)) if(self.isGameOver==1): props = WindowProperties() props.setCursorHidden(False) base.win.requestProperties(props) self.imageObject = OnscreenImage(image = 'earth.jpg', pos = (0, 1, 0)) self.imageObject.setScale(1.9,1,1) self.textObject = OnscreenText(text = '\1red\1\1roman\1\1slant\1Space Collector', pos = (-0.6, 0.4), scale = 0.2) self.b = DirectButton(text = ("Start", "Start", "Start", "disabled"),command=self.beginGame) self.b.setScale(0.1,0.1,0.1) self.b.setPos(0.7,0,-0.8) self.ship.setPos(0,0,0) self.zPosition=0 self.prevY=0 self.prevX=0 self.collided=1 self.jumpTime=0 self.jumpOn=0 self.curZ=0 self.interval=0 self.zPosition=0 self.isGameOver=0 self.score=0 self.acceleration=0 self.velocity=0 self.yPos=0 self.score=0 self.timer=120 self.textTimer.destroy() self.textScore.destroy() for x in self.junk: if(x!=None): x.detachNode() x=None print 'destroyed' self.loadJunk() else: return Task.cont def jump(self): self.jumpOn=1 self.ignore("mouse1")
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 DistributedGolfSpot(DistributedObject.DistributedObject, FSM.FSM): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGolfSpot') positions = ((-45, 100, GolfGlobals.GOLF_BALL_RADIUS), (-15, 100, GolfGlobals.GOLF_BALL_RADIUS), (15, 100, GolfGlobals.GOLF_BALL_RADIUS), (45, 100, GolfGlobals.GOLF_BALL_RADIUS)) toonGolfOffsetPos = Point3(-2, 0, -GolfGlobals.GOLF_BALL_RADIUS) toonGolfOffsetHpr = Point3(-90, 0, 0) rotateSpeed = 20 golfPowerSpeed = base.config.GetDouble('golf-power-speed', 3) golfPowerExponent = base.config.GetDouble('golf-power-exponent', 0.75) def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedGolfSpot') self.boss = None self.index = None self.avId = 0 self.toon = None self.golfSpotSmoother = SmoothMover() self.golfSpotSmoother.setSmoothMode(SmoothMover.SMOn) self.smoothStarted = 0 self.__broadcastPeriod = 0.2 if self.index > len(self.positions): self.notify.error('Invalid index %d' % index) self.fadeTrack = None self.setupPowerBar() self.aimStart = None self.golfSpotAdviceLabel = None self.changeSeq = 0 self.lastChangeSeq = 0 self.controlKeyAllowed = False self.flyBallTracks = {} self.splatTracks = {} self.__flyBallBubble = None self.flyBallHandler = None self.__flyBallSequenceNum = 0 self.swingInterval = None self.lastHitSequenceNum = -1 self.goingToReward = False self.gotHitByBoss = False self.releaseTrack = None self.grabTrack = None self.restoreScaleTrack = None return def setBossCogId(self, bossCogId): self.bossCogId = bossCogId self.boss = base.cr.doId2do[bossCogId] self.boss.setGolfSpot(self, self.index) def setIndex(self, index): self.index = index def disable(self): DistributedObject.DistributedObject.disable(self) self.ignoreAll() def delete(self): DistributedObject.DistributedObject.delete(self) self.ignoreAll() self.boss = None return def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) self.triggerName = self.uniqueName('trigger') self.triggerEvent = 'enter%s' % self.triggerName self.smoothName = self.uniqueName('golfSpotSmooth') self.golfSpotAdviceName = self.uniqueName('golfSpotAdvice') self.posHprBroadcastName = self.uniqueName('golfSpotBroadcast') self.ballPowerTaskName = self.uniqueName('updateGolfPower') self.adjustClubTaskName = self.uniqueName('adjustClub') self.loadAssets() self.accept('flyBallHit-%d' % self.index, self.__flyBallHit) def loadAssets(self): self.root = render.attachNewNode('golfSpot-%d' % self.index) self.root.setPos(*self.positions[self.index]) self.ballModel = loader.loadModel('phase_6/models/golf/golf_ball') self.ballColor = VBase4(1, 1, 1, 1) if self.index < len(GolfGlobals.PlayerColors): self.ballColor = VBase4(*GolfGlobals.PlayerColors[self.index]) self.ballModel.setColorScale(self.ballColor) self.ballModel.reparentTo(self.root) self.club = loader.loadModel('phase_6/models/golf/putter') self.clubLookatSpot = self.root.attachNewNode('clubLookat') self.clubLookatSpot.setY(-(GolfGlobals.GOLF_BALL_RADIUS + 0.1)) cs = CollisionSphere(0, 0, 0, 1) cs.setTangible(0) cn = CollisionNode(self.triggerName) cn.addSolid(cs) cn.setIntoCollideMask(ToontownGlobals.WallBitmask) self.trigger = self.root.attachNewNode(cn) self.trigger.stash() self.hitBallSfx = loader.loadSfx('phase_6/audio/sfx/Golf_Hit_Ball.ogg') def cleanup(self): if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if self.releaseTrack: self.releaseTrack.finish() self.releaseTrack = None flyTracks = self.flyBallTracks.values() for track in flyTracks: track.finish() if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None if self.restoreScaleTrack: self.restoreScaleTrack.finish() self.restoreScaleTrack = None self.root.removeNode() self.ballModel.removeNode() self.club.removeNode() if self.powerBar: self.powerBar.destroy() self.powerBar = None taskMgr.remove(self.triggerName) self.boss = None return def setState(self, state, avId, extraInfo): if not self.isDisabled(): self.gotHitByBoss = extraInfo if state == 'C': self.demand('Controlled', avId) elif state == 'F': self.demand('Free') elif state == 'O': self.demand('Off') else: self.notify.error('Invalid state from AI: %s' % state) def enterOff(self): pass def exitOff(self): pass def enterFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack = Sequence(Wait(6), self.getRestoreScaleInterval(), name='restoreScaleTrack') self.restoreScaleTrack.start() if self.avId == localAvatar.doId: if not self.isDisabled(): self.ballModel.setAlphaScale(0.3) self.ballModel.setTransparency(1) taskMgr.doMethodLater(5, self.__allowDetect, self.triggerName) self.fadeTrack = Sequence(Func(self.ballModel.setTransparency, 1), self.ballModel.colorScaleInterval(0.2, VBase4(1, 1, 1, 0.3)), name='fadeTrack-enterFree') self.fadeTrack.start() else: self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) self.avId = 0 return def exitFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack.finish() self.restoreScaleTrack = None taskMgr.remove(self.triggerName) self.ballModel.clearTransparency() self.trigger.stash() self.ignore(self.triggerEvent) return def enterControlled(self, avId): self.avId = avId toon = base.cr.doId2do.get(avId) if not toon: return self.enableControlKey() self.toon = toon self.grabTrack = self.makeToonGrabInterval(toon) if avId == localAvatar.doId: self.boss.toCraneMode() camera.reparentTo(self.root) camera.setPosHpr(0, -10, 3, 0, 0, 0) localAvatar.setPos(self.root, self.toonGolfOffsetPos) localAvatar.setHpr(self.root, self.toonGolfOffsetHpr) localAvatar.sendCurrentPosition() self.__enableControlInterface() self.startPosHprBroadcast() self.accept('exitCrane', self.gotBossZapped) self.grabTrack.start() def exitControlled(self): self.grabTrack.finish() del self.grabTrack if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if not self.ballModel.isEmpty(): if self.ballModel.isHidden(): self.notify.debug('ball is hidden scale =%s' % self.ballModel.getScale()) else: self.notify.debug('ball is showing scale=%s' % self.ballModel.getScale()) if self.toon and not self.toon.isDisabled(): self.toon.startSmooth() self.releaseTrack = self.makeToonReleaseInterval(self.toon) self.stopPosHprBroadcast() self.stopSmooth() if self.avId == localAvatar.doId: self.__disableControlInterface() if not self.goingToReward: camera.reparentTo(base.localAvatar) camera.setPos(base.localAvatar.cameraPositions[0][0]) camera.setHpr(0, 0, 0) self.stopAdjustClubTask() self.releaseTrack.start() self.enableControlKey() return def __allowDetect(self, task): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = Sequence(self.ballModel.colorScaleInterval(0.2, self.ballColor), Func(self.ballModel.clearTransparency), name='fadeTrack-allowDetect') self.fadeTrack.start() self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) def __hitTrigger(self, event): self.d_requestControl() def getRestoreScaleInterval(self): return Sequence() def d_requestControl(self): self.sendUpdate('requestControl') def d_requestFree(self, gotHitByBoss): self.sendUpdate('requestFree', [gotHitByBoss]) def makeToonGrabInterval(self, toon): origPos = toon.getPos(self.root) origHpr = toon.getHpr(self.root) a = self.accomodateToon(toon) newPos = toon.getPos() newHpr = toon.getHpr() origHpr.setX(PythonUtil.fitSrcAngle2Dest(origHpr[0], newHpr[0])) self.notify.debug('toon.setPosHpr %s %s' % (origPos, origHpr)) toon.setPosHpr(origPos, origHpr) walkTime = 0.2 reach = Sequence() if reach.getDuration() < walkTime: reach = Sequence(ActorInterval(toon, 'walk', loop=1, duration=walkTime - reach.getDuration()), reach) i = Sequence(Parallel(toon.posInterval(walkTime, newPos, origPos), toon.hprInterval(walkTime, newHpr, origHpr), reach), Func(toon.stopLookAround)) if toon == base.localAvatar: i.append(Func(self.switchToAnimState, 'GolfPuttLoop')) i.append(Func(self.startAdjustClubTask)) i = Parallel(i, a) return i def accomodateToon(self, toon): toon.wrtReparentTo(self.root) toon.setPos(self.toonGolfOffsetPos) toon.setHpr(self.toonGolfOffsetHpr) return Sequence() def switchToAnimState(self, animStateName, forced = False): curAnimState = base.localAvatar.animFSM.getCurrentState() curAnimStateName = '' if curAnimState: curAnimStateName = curAnimState.getName() if curAnimStateName != animStateName or forced: base.localAvatar.b_setAnimState(animStateName) def __enableControlInterface(self): gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=2, text=TTLocalizer.BossbotGolfSpotLeave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(1.05, 0, -0.82), command=self.__exitGolfSpot) self.accept('escape', self.__exitGolfSpot) self.accept('control', self.__controlPressed) self.accept('control-up', self.__controlReleased) self.accept('InputState-forward', self.__upArrow) self.accept('InputState-reverse', self.__downArrow) self.accept('InputState-turnLeft', self.__leftArrow) self.accept('InputState-turnRight', self.__rightArrow) taskMgr.add(self.__watchControls, 'watchGolfSpotControls') taskMgr.doMethodLater(5, self.__displayGolfSpotAdvice, self.golfSpotAdviceName) self.arrowVert = 0 self.arrowHorz = 0 if self.powerBar: self.powerBar.show() return def __disableControlInterface(self): if self.closeButton: self.closeButton.destroy() self.closeButton = None self.__cleanupGolfSpotAdvice() self.ignore('escape') self.ignore('control') self.ignore('control-up') self.ignore('InputState-forward') self.ignore('InputState-reverse') self.ignore('InputState-turnLeft') self.ignore('InputState-turnRight') self.arrowVert = 0 self.arrowHorz = 0 taskMgr.remove('watchGolfSpotControls') if self.powerBar: self.powerBar.hide() else: self.notify.debug('self.powerBar is none') return def setupPowerBar(self): self.powerBar = DirectWaitBar(pos=(0.0, 0, -0.94), relief=DGG.SUNKEN, frameSize=(-2.0, 2.0, -0.2, 0.2), borderWidth=(0.02, 0.02), scale=0.25, range=100, sortOrder=50, frameColor=(0.5, 0.5, 0.5, 0.5), barColor=(1.0, 0.0, 0.0, 1.0), text='', text_scale=0.26, text_fg=(1, 1, 1, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05)) self.power = 0 self.powerBar['value'] = self.power self.powerBar.hide() def resetPowerBar(self): self.power = 0 self.powerBar['value'] = self.power self.powerBar['text'] = '' def __displayGolfSpotAdvice(self, task): if self.golfSpotAdviceLabel == None: self.golfSpotAdviceLabel = DirectLabel(text=TTLocalizer.BossbotGolfSpotAdvice, text_fg=VBase4(1, 1, 1, 1), text_align=TextNode.ACenter, relief=None, pos=(0, 0, 0.69), scale=0.1) return def __cleanupGolfSpotAdvice(self): if self.golfSpotAdviceLabel: self.golfSpotAdviceLabel.destroy() self.golfSpotAdviceLabel = None taskMgr.remove(self.golfSpotAdviceName) return def showExiting(self): if self.closeButton: self.closeButton.destroy() self.closeButton = DirectLabel(relief=None, text=TTLocalizer.BossbotGolfSpotLeaving, pos=(1.05, 0, -0.88), text_pos=(0, 0), text_scale=0.06, text_fg=VBase4(1, 1, 1, 1)) self.__cleanupGolfSpotAdvice() return def __exitGolfSpot(self): self.d_requestFree(False) def __controlPressed(self): if self.controlKeyAllowed: self.__beginFireBall() def __controlReleased(self): if self.controlKeyAllowed: self.__endFireBall() def __upArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = 1 elif self.arrowVert > 0: self.arrowVert = 0 def __downArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = -1 elif self.arrowVert < 0: self.arrowVert = 0 def __rightArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = 1 self.switchToAnimState('GolfRotateLeft') elif self.arrowHorz > 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __leftArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = -1 self.switchToAnimState('GolfRotateRight') elif self.arrowHorz < 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __watchControls(self, task): if self.arrowHorz: self.__moveGolfSpot(self.arrowHorz) return Task.cont def __moveGolfSpot(self, xd): dt = globalClock.getDt() h = self.root.getH() - xd * self.rotateSpeed * dt h %= 360 limitH = h self.root.setH(limitH) def __incrementChangeSeq(self): self.changeSeq = self.changeSeq + 1 & 255 def __beginFireBall(self): if self.aimStart != None: return if not self.state_ == 'Controlled': return if not self.avId == localAvatar.doId: return time = globalClock.getFrameTime() self.aimStart = time messenger.send('wakeup') taskMgr.add(self.__updateBallPower, self.ballPowerTaskName) return def __endFireBall(self): if self.aimStart == None: return if not self.state_ == 'Controlled': return if not self.avId == localAvatar.doId: return taskMgr.remove(self.ballPowerTaskName) self.disableControlKey() messenger.send('wakeup') self.aimStart = None power = self.power angle = self.root.getH() self.notify.debug('incrementing self.__flyBallSequenceNum') self.__flyBallSequenceNum = (self.__flyBallSequenceNum + 1) % 255 self.sendSwingInfo(power, angle, self.__flyBallSequenceNum) self.setSwingInfo(power, angle, self.__flyBallSequenceNum) self.resetPowerBar() return def __updateBallPower(self, task): if not self.powerBar: print '### no power bar!!!' return task.done newPower = self.__getBallPower(globalClock.getFrameTime()) self.power = newPower self.powerBar['value'] = newPower return task.cont def __getBallPower(self, time): elapsed = max(time - self.aimStart, 0.0) t = elapsed / self.golfPowerSpeed t = math.pow(t, self.golfPowerExponent) power = int(t * 100) % 200 if power > 100: power = 200 - power return power def stopPosHprBroadcast(self): taskName = self.posHprBroadcastName taskMgr.remove(taskName) def startPosHprBroadcast(self): taskName = self.posHprBroadcastName self.b_clearSmoothing() self.d_sendGolfSpotPos() taskMgr.remove(taskName) taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) def __posHprBroadcast(self, task): self.d_sendGolfSpotPos() taskName = self.posHprBroadcastName taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) return Task.done def d_sendGolfSpotPos(self): timestamp = globalClockDelta.getFrameNetworkTime() self.sendUpdate('setGolfSpotPos', [self.changeSeq, self.root.getH(), timestamp]) def setGolfSpotPos(self, changeSeq, h, timestamp): self.changeSeq = changeSeq if self.smoothStarted: now = globalClock.getFrameTime() local = globalClockDelta.networkToLocalTime(timestamp, now) self.golfSpotSmoother.setH(h) self.golfSpotSmoother.setTimestamp(local) self.golfSpotSmoother.markPosition() else: self.root.setH(h) def b_clearSmoothing(self): self.d_clearSmoothing() self.clearSmoothing() def d_clearSmoothing(self): self.sendUpdate('clearSmoothing', [0]) def clearSmoothing(self, bogus = None): self.golfSpotSmoother.clearPositions(1) def doSmoothTask(self, task): self.golfSpotSmoother.computeAndApplySmoothHpr(self.root) return Task.cont def startSmooth(self): if not self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.reloadPosition() taskMgr.add(self.doSmoothTask, taskName) self.smoothStarted = 1 def stopSmooth(self): if self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.forceToTruePosition() self.smoothStarted = 0 def makeToonReleaseInterval(self, toon): def getSlideToPos(toon = toon): return render.getRelativePoint(toon, Point3(0, -5, 0)) if self.gotHitByBoss: grabIval = Sequence(Func(self.detachClub), name='makeToonReleaseInterval-gotHitByBoss') if not toon.isEmpty(): toonIval = Sequence(Func(toon.wrtReparentTo, render), Parallel(ActorInterval(toon, 'slip-backward'), toon.posInterval(0.5, getSlideToPos, fluid=1)), name='makeToonReleaseInterval-toonIval') grabIval.append(toonIval) else: grabIval = Sequence(Func(self.detachClub)) if not toon.isEmpty(): toonIval = Sequence(Parallel(ActorInterval(toon, 'walk', duration=1.0, playRate=-1.0), LerpPosInterval(toon, duration=1.0, pos=Point3(-10, 0, 0))), Func(toon.wrtReparentTo, render)) grabIval.append(toonIval) if localAvatar.doId == toon.doId: if not self.goingToReward and toon.hp > 0: grabIval.append(Func(self.goToFinalBattle)) grabIval.append(Func(self.notify.debug, 'goingToFinalBattlemode')) grabIval.append(Func(self.safeBossToFinalBattleMode)) return grabIval def safeBossToFinalBattleMode(self): if self.boss: self.boss.toFinalBattleMode() def goToFinalBattle(self): if self.cr: place = self.cr.playGame.getPlace() if place and hasattr(place, 'fsm'): curState = place.fsm.getCurrentState().getName() if place.fsm.getCurrentState().getName() == 'crane': place.setState('finalBattle') else: self.notify.debug('NOT going to final battle, state=%s' % curState) def attachClub(self, avId, pointToBall = False): club = self.club if club: av = base.cr.doId2do.get(avId) if av: av.useLOD(1000) lHand = av.getLeftHands()[0] club.setPos(0, 0, 0) club.reparentTo(lHand) netScale = club.getNetTransform().getScale()[1] counterActToonScale = lHand.find('**/counteractToonScale') if counterActToonScale.isEmpty(): counterActToonScale = lHand.attachNewNode('counteractToonScale') counterActToonScale.setScale(1 / netScale) self.notify.debug('creating counterActToonScale for %s' % av.getName()) club.reparentTo(counterActToonScale) club.setX(-0.25 * netScale) if pointToBall: club.lookAt(self.clubLookatSpot) def detachClub(self): if not self.club.isEmpty(): self.club.reparentTo(self.root) self.club.setZ(-20) self.club.setScale(1) def adjustClub(self): club = self.club if club: distance = club.getDistance(self.clubLookatSpot) scaleFactor = distance / 2.058 club.setScale(1, scaleFactor, 1) def startAdjustClubTask(self): taskMgr.add(self.adjustClubTask, self.adjustClubTaskName) def stopAdjustClubTask(self): taskMgr.remove(self.adjustClubTaskName) def adjustClubTask(self, task): self.attachClub(self.avId, True) self.adjustClub() return task.cont def enableControlKey(self): self.controlKeyAllowed = True def disableControlKey(self): self.controlKeyAllowed = False def sendSwingInfo(self, power, angle, sequenceNum): self.sendUpdate('setSwingInfo', [power, angle, sequenceNum]) def startBallPlayback(self, power, angle, sequenceNum): flyBall = self.ballModel.copyTo(NodePath()) flyBall.setScale(1.0) flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath()) flyBallBubble.reparentTo(flyBall) flyBall.setTag('pieSequence', str(sequenceNum)) flyBall.setTag('throwerId', str(self.avId)) t = power / 100.0 t = 1.0 - t dist = 300 - 200 * t time = 1.5 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(root = self.root, relVel = relVel): return render.getRelativeVector(root, relVel) fly = Sequence(Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel=getVelocity, duration=3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, 'removed collider'), Func(self.flyBallFinishedFlying, sequenceNum)) flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node=self.root), name='flyWithSound') self.notify.debug('starting flyball track') flyWithSound.start() self.flyBallTracks[sequenceNum] = flyWithSound return def setSwingInfo(self, power, angle, sequenceNum): av = base.cr.doId2do.get(self.avId) self.swingInterval = Sequence() if av: self.stopAdjustClubTask() self.swingInterval = Sequence(ActorInterval(av, 'swing-putt', startFrame=0, endFrame=GolfGlobals.BALL_CONTACT_FRAME), Func(self.startBallPlayback, power, angle, sequenceNum), Func(self.ballModel.hide), ActorInterval(av, 'swing-putt', startFrame=GolfGlobals.BALL_CONTACT_FRAME, endFrame=24), Func(self.ballModel.setScale, 0.1), Func(self.ballModel.show), LerpScaleInterval(self.ballModel, 1.0, Point3(1, 1, 1)), Func(self.enableControlKey)) if av == localAvatar: self.swingInterval.append(Func(self.switchToAnimState, 'GolfPuttLoop', True)) self.swingInterval.start() def getFlyBallBubble(self): if self.__flyBallBubble == None: bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS) node = CollisionNode('flyBallBubble') node.addSolid(bubble) node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) node.setIntoCollideMask(BitMask32.allOff()) self.__flyBallBubble = NodePath(node) self.flyBallHandler = CollisionHandlerEvent() self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index) return self.__flyBallBubble def __flyBallHit(self, entry): print entry def flyBallFinishedFlying(self, sequence): if sequence in self.flyBallTracks: del self.flyBallTracks[sequence] def __finishFlyBallTrack(self, sequence): if sequence in self.flyBallTracks: flyBallTrack = self.flyBallTracks[sequence] del self.flyBallTracks[sequence] flyBallTrack.finish() def flyBallFinishedSplatting(self, sequence): if sequence in self.splatTracks: del self.splatTracks[sequence] def __flyBallHit(self, entry): if not entry.hasSurfacePoint() or not entry.hasInto(): return if not entry.getInto().isTangible(): return sequence = int(entry.getFromNodePath().getNetTag('pieSequence')) self.__finishFlyBallTrack(sequence) if sequence in self.splatTracks: splatTrack = self.splatTracks[sequence] del self.splatTracks[sequence] splatTrack.finish() flyBallCode = 0 flyBallCodeStr = entry.getIntoNodePath().getNetTag('pieCode') if flyBallCodeStr: flyBallCode = int(flyBallCodeStr) pos = entry.getSurfacePoint(render) timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32) throwerId = int(entry.getFromNodePath().getNetTag('throwerId')) splat = self.getFlyBallSplatInterval(pos[0], pos[1], pos[2], flyBallCode, throwerId) splat = Sequence(splat, Func(self.flyBallFinishedSplatting, sequence)) self.splatTracks[sequence] = splat splat.start() self.notify.debug('doId=%d into=%s flyBallCode=%d, throwerId=%d' % (self.doId, entry.getIntoNodePath(), flyBallCode, throwerId)) if flyBallCode == ToontownGlobals.PieCodeBossCog and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum self.boss.d_ballHitBoss(2) elif flyBallCode == ToontownGlobals.PieCodeToon and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum avatarDoId = entry.getIntoNodePath().getNetTag('avatarDoId') if avatarDoId == '': self.notify.warning('Toon %s has no avatarDoId tag.' % repr(entry.getIntoNodePath())) return doId = int(avatarDoId) if doId != localAvatar.doId: pass def getFlyBallSplatInterval(self, x, y, z, flyBallCode, throwerId): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps splatName = 'dust' splat = BattleProps.globalPropPool.getProp(splatName) splat.setBillboardPointWorld(2) color = ToontownGlobals.PieCodeColors.get(flyBallCode) if color: splat.setColor(*color) if flyBallCode == ToontownGlobals.PieCodeBossCog: self.notify.debug('changing color to %s' % self.ballColor) splat.setColor(self.ballColor) sound = loader.loadSfx('phase_11/audio/sfx/LB_evidence_miss.ogg') vol = 1.0 if flyBallCode == ToontownGlobals.PieCodeBossCog: sound = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') soundIval = SoundInterval(sound, node=splat, volume=vol) if flyBallCode == ToontownGlobals.PieCodeBossCog and localAvatar.doId == throwerId: vol = 1.0 soundIval = SoundInterval(sound, node=localAvatar, volume=vol) ival = Parallel(Func(splat.reparentTo, render), Func(splat.setPos, x, y, z), soundIval, Sequence(ActorInterval(splat, splatName), Func(splat.detachNode))) return ival def setGoingToReward(self): self.goingToReward = True def gotBossZapped(self): self.showExiting() self.d_requestFree(True)