def setupCollisions(self): #make a collision traverser, set it to default base.cTrav = CollisionTraverser() #self.cHandler = CollisionHandlerEvent() self.cHandler = CollisionHandlerPusher() #set the pattern for the event sent on collision # "%in" is substituted with the name of the into object #self.cHandler.setInPattern("hit-%in") cSphere = CollisionSphere((0,0,0), 10) #panda is scaled way down! cNode = CollisionNode("vtol") cNode.addSolid(cSphere) #panda is *only* a from object cNode.setFromCollideMask(BitMask32.bit(0)) cNode.setIntoCollideMask(BitMask32.allOff()) cNodePath = self.vtol.attachNewNode(cNode) # cNodePath.show() base.cTrav.addCollider(cNodePath, self.cHandler) self.cHandler.addCollider(cNodePath, self.vtol) #for b1 in self.house2: cTube1 = CollisionTube((-0.4,3,3), (-0.4,3,20), 6.8) cTube2 = CollisionTube((-0.4,-3,3), (-0.4,-3,20), 6.8) cNode = CollisionNode("models/houses/building") cNode.addSolid(cTube1) cNode.addSolid(cTube2) cNodePath = self.house2.attachNewNode(cNode) cTube1 = CollisionTube((-0.4,3,3), (-0.4,3,20), 6.8) cTube2 = CollisionTube((-0.4,-3,3), (-0.4,-3,20), 6.8) cNode = CollisionNode("models/houses/church") cNode.addSolid(cTube1) cNode.addSolid(cTube2) cNodePath = self.house1.attachNewNode(cNode)
def __init__( self, name, camera=None, rootNp=None, fromCollideMask=None, pickTag=None ): gizmo_core.Object.__init__( self, name, camera, rootNp ) self.fromCollideMask = fromCollideMask self.pickTag = pickTag self.selection = [] self.node = None self.collEntry = None # Create a marquee self.marquee = gizmo_core.Marquee( '%sMarquee' % self.name ) # Create collision nodes self.collTrav = CollisionTraverser() #self.collTrav.showCollisions( render ) self.collHandler = CollisionHandlerQueue() self.pickerRay = CollisionRay() # Create collision ray pickerNode = CollisionNode( self.name ) pickerNode.addSolid( self.pickerRay ) pickerNode.setIntoCollideMask( BitMask32.allOff() ) pickerNp = camera.attachNewNode( pickerNode ) self.collTrav.addCollider( pickerNp, self.collHandler ) # Create collision mask for the ray if one is specified if self.fromCollideMask is not None: pickerNode.setFromCollideMask( self.fromCollideMask ) # Bind mouse button events eventNames = ['mouse1', 'control-mouse1', 'mouse1-up'] for eventName in eventNames: self.accept( eventName, self.FireEvent, [eventName] )
def leftClick(self): self.mouse1Down = True #Collision traversal pickerNode = CollisionNode('mouseRay') pickerNP = base.camera.attachNewNode(pickerNode) pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) pickerRay = CollisionRay() pickerNode.addSolid(pickerRay) myTraverser = CollisionTraverser() myHandler = CollisionHandlerQueue() myTraverser.addCollider(pickerNP, myHandler) if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) myTraverser.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if myHandler.getNumEntries() > 0: # This is so we get the closest object myHandler.sortEntries() pickedObj = myHandler.getEntry(0).getIntoNodePath() objTag = pickedObj.findNetTag('mouseCollisionTag').getTag('mouseCollisionTag') if objTag and len(objTag)>0: messenger.send('object_click',[objTag]) pickerNP.remove()
def __init__( self, name, camera=None, rootNp=None, fromCollideMask=None, pickTag=None, gizmos=None ): p3d.Object.__init__( self, name, camera, rootNp ) self.fromCollideMask = fromCollideMask self.pickTag = pickTag self.selection = set([]) self.node = None self.np = None self.collEntry = None self.gizmos = gizmos assert self.gizmos is not None # Create a marquee self.marquee = marquee.Marquee( '%sMarquee' % self.name ) # Create collision ray self.pickerRay = CollisionRay() # Create collision node pickerNode = CollisionNode( self.name ) pickerNode.addSolid( self.pickerRay ) pickerNode.setFromCollideMask( self.fromCollideMask ) self.pickerNp = camera.attachNewNode( pickerNode ) #pickerNp.setCollideMask(AXIS_COLLISION_MASK) self.collHandler = CollisionHandlerQueue() self.collTrav = CollisionTraverser() self.collTrav.showCollisions( render ) self.collTrav.addCollider( self.pickerNp, self.collHandler ) # Bind mouse button events eventNames = ['mouse1', 'control-mouse1', 'mouse1-up'] for eventName in eventNames: self.accept( eventName, self.FireEvent, [eventName] ) #== self.selectionCol = None
def __init__( self, *args, **kwargs ): p3d.SingleTask.__init__( self, *args, **kwargs ) self.fromCollideMask = kwargs.pop( 'fromCollideMask', None ) self.node = None self.collEntry = None # Create collision nodes self.collTrav = CollisionTraverser() #self.collTrav.showCollisions( render ) self.collHandler = CollisionHandlerQueue() self.pickerRay = CollisionRay() # Create collision ray pickerNode = CollisionNode( self.name ) pickerNode.addSolid( self.pickerRay ) pickerNode.setIntoCollideMask( BitMask32.allOff() ) pickerNp = self.camera.attachNewNode( pickerNode ) self.collTrav.addCollider( pickerNp, self.collHandler ) # Create collision mask for the ray if one is specified if self.fromCollideMask is not None: pickerNode.setFromCollideMask( self.fromCollideMask ) # Bind mouse button events eventNames = ['mouse1', 'control-mouse1', 'mouse1-up'] for eventName in eventNames: self.accept( eventName, self.FireEvent, [eventName] )
class ControleMouse(): def __init__(self, render, camera): #Since we are using collision detection to do picking, we set it up like any other collision detection system with a traverser and a handler self.picker = CollisionTraverser() #Make a traverser self.pq = CollisionHandlerQueue() #Make a handler #Make a collision node for our picker ray self.pickerNode = CollisionNode('mouseRay') #Attach that node to the camera since the ray will need to be positioned relative to it self.pickerNP = camera.attachNewNode(self.pickerNode) #Everything to be picked will use bit 1. This way if we were doing other collision we could seperate it self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() #Make our ray self.pickerNode.addSolid(self.pickerRay) #Add it to the collision node #Register the ray as something that can cause collisions self.picker.addCollider(self.pickerNP, self.pq) #self.picker.showCollisions(render) self.pst = CollisionTraverser() #Make a traverser self.hqp = CollisionHandlerQueue() #Make a handler #Make a collision node for our picker ray self.pstNode = CollisionNode('mouseRaytoObj') #Attach that node to the camera since the ray will need to be positioned relative to it self.pstNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pstNode2 = camera.attachNewNode(self.pstNode) self.pickerRayObj = CollisionRay() #Everything to be picked will use bit 1. This way if we were doing other collision we could seperate it #self.pstNode.setFromCollideMask(BitMask32.bit(1)) self.pstNode.addSolid(self.pickerRayObj) #Add it to the collision node #Register the ray as something that can cause collisions self.pst.addCollider(self.pstNode2, self.hqp) #self.pst.showCollisions(render)
def setupCollisions(self): #player sphere cPlayerSphere = CollisionSphere(Point3(0, 0, .5), 10) cPlayerNode = CollisionNode("Player") cPlayerNode.addSolid(cPlayerSphere) cPlayerNode.setFromCollideMask(BitMask32.bit(4)) cPlayerNode.setIntoCollideMask(BitMask32(20)) cPlayerNP = self.player.attachNewNode(cPlayerNode) self.cTrav.addCollider(cPlayerNP, self.playerGroundHandler) #self.cTrav.addCollider(cPlayerNP, self.cRocketHandler) #cPlayerNP.show() #enemy sphere cEnemySphere = CollisionSphere(Point3(0, 0, .5), 10) cEnemyNode = CollisionNode("Enemy") cEnemyNode.addSolid(cEnemySphere) cEnemyNode.setFromCollideMask(BitMask32.bit(4)) cEnemyNode.setIntoCollideMask(BitMask32(18)) cEnemyNP = self.enemy.attachNewNode(cEnemyNode) self.cTrav.addCollider(cEnemyNP, self.enemyGroundHandler)
def pieThrow(self, avId, timestamp, heading, pos, power): toon = self.activity.getAvatar(avId) if toon is None: return tossTrack, pieTrack, flyPie = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, power) if avId == base.localAvatar.doId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.activity.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) collNP = flyPie.attachNewNode(collNode) base.cTrav.addCollider(collNP, self.pieHandler) self.toonPieEventNames[collNP] = 'pieHit-' + collSphereName self.accept(self.toonPieEventNames[collNP], self.handlePieCollision) else: player = self.players.get(avId) if player is not None: player.faceForward() def matchRunningAnim(toon = toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack, name='PartyCogActivity.pieTrack-%d-%s' % (avId, timestamp)) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.pieIvals.append(pieTrack) self.toonPieTracks[avId] = pieTrack
def leftClick(self): self.mouse1Down = True #Collision traversal pickerNode = CollisionNode('mouseRay') pickerNP = base.camera.attachNewNode(pickerNode) pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) pickerRay = CollisionRay() pickerNode.addSolid(pickerRay) myTraverser = CollisionTraverser() myHandler = CollisionHandlerQueue() myTraverser.addCollider(pickerNP, myHandler) if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) myTraverser.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if myHandler.getNumEntries() > 0: # This is so we get the closest object myHandler.sortEntries() pickedObj = myHandler.getEntry(0).getIntoNodePath() objTag = pickedObj.findNetTag('mouseCollisionTag').getTag( 'mouseCollisionTag') if objTag and len(objTag) > 0: messenger.send('object_click', [objTag]) pickerNP.remove()
def __init__(self, *args, **kwargs): p3d.SingleTask.__init__(self, *args, **kwargs) self.fromCollideMask = kwargs.pop('fromCollideMask', None) self.node = None self.collEntry = None # Create collision nodes self.collTrav = CollisionTraverser() #self.collTrav.showCollisions( render ) self.collHandler = CollisionHandlerQueue() self.pickerRay = CollisionRay() # Create collision ray pickerNode = CollisionNode(self.name) pickerNode.addSolid(self.pickerRay) pickerNode.setIntoCollideMask(BitMask32.allOff()) pickerNp = self.camera.attachNewNode(pickerNode) self.collTrav.addCollider(pickerNp, self.collHandler) # Create collision mask for the ray if one is specified if self.fromCollideMask is not None: pickerNode.setFromCollideMask(self.fromCollideMask) # Bind mouse button events eventNames = ['mouse1', 'control-mouse1', 'mouse1-up'] for eventName in eventNames: self.accept(eventName, self.FireEvent, [eventName])
class Agent: def __init__(self, model, run, walk, startPos, scale, select,ralph,saysome): self.actor = Actor(model, {"run":run, "walk":walk}) self.actor.reparentTo(render) self.actor.setScale(scale) self.actor.setPos(startPos) self.actor.setHpr(90,0,0) self.playerGUI = saysome self.myralph = ralph self.setAI() self.cTrav = CollisionTraverser() self.groundRay = CollisionRay(0,0,1000,0,0,-1) self.groundCol = CollisionNode('dinoRay') self.groundCol.addSolid(self.groundRay) self.groundCol.setFromCollideMask(BitMask32.bit(1)) self.groundCol.setIntoCollideMask(BitMask32.allOff()) self.groundColNp = self.actor.attachNewNode(self.groundCol) self.groundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.groundColNp, self.groundHandler) self.sphere = CollisionSphere(0,0,5,13) self.spherecol = CollisionNode('dinoSphere') self.spherecol.addSolid(self.sphere) self.spherecol.setCollideMask(BitMask32.bit(1)) self.dinocolhs = self.actor.attachNewNode(self.spherecol) #self.dinocolhs.show() #self.groundColNp.show() #self.cTrav.showCollisions(render) def setAI(self): #Creating AI World self.AIworld = AIWorld(render) self.AIchar = AICharacter("seeker",self.actor, 380, 50, 250) self.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.pursue(self.myralph) self.actor.loop('run') #AI World update taskMgr.add(self.AIUpdate,"AIUpdate") #to update the AIWorld def AIUpdate(self,task): if self.playerGUI.getpausevalue(): self.AIworld.update() return Task.cont def setControl(self, control, value): self.controlMap[control] = value def getactor(self): return self.actor
def makeNodeLocator(self, environment): meshNode = CollisionNode("NavMeshNodeLocator") meshNode.setFromCollideMask(BitMask32.allOff()) meshNode.setIntoCollideMask(OTPGlobals.PathFindingBitmask) self.polyHashToPID = {} for pId in self.polyToAngles: vertCount = 0 corners = [] for angle in self.polyToAngles[pId]: if angle != 180: # It's a corner corners.append(vertCount) vertCount += 1 # XXX this code only works for square nodes at present # Unfortunately we can only make triangle or square CollisionPolygons on the fly assert len(corners) == 4 #import pdb #pdb.set_trace() verts = [] for vert in corners: verts.append( (self.vertexCoords[self.polyToVerts[pId][vert]][0], self.vertexCoords[self.polyToVerts[pId][vert]][1], 0)) #import pdb #pdb.set_trace() poly = CollisionPolygon(verts[0], verts[1], verts[2], verts[3]) assert poly not in self.polyHashToPID self.polyHashToPID[poly] = pId meshNode.addSolid(poly) ray = CollisionRay() ray.setDirection(0, 0, -1) ray.setOrigin(0, 0, 0) rayNode = CollisionNode("NavMeshRay") rayNode.setFromCollideMask(OTPGlobals.PathFindingBitmask) rayNode.setIntoCollideMask(BitMask32.allOff()) rayNode.addSolid(ray) self.meshNodePath = environment.attachNewNode(meshNode) self.rayNodePath = environment.attachNewNode(rayNode) self.meshNodePath.setTwoSided(True) self.chq = CollisionHandlerQueue() self.traverser = CollisionTraverser() self.traverser.addCollider(self.rayNodePath, self.chq)
class RepairMousePicker: def __init__(self): self.pickerNode = CollisionNode('RepairMousePicker.pickerNode') self.pickerNP = base.cam2d.attachNewNode(self.pickerNode) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.collisionTraverser = CollisionTraverser() self.collisionHandler = CollisionHandlerQueue() self.collisionTraverser.addCollider(self.pickerNP, self.collisionHandler) self.clearCollisionMask() self.orthographic = True def destroy(self): del self.pickerNode self.pickerNP.removeNode() del self.pickerNP del self.pickerRay del self.collisionTraverser del self.collisionHandler def setOrthographic(self, ortho): self.orthographic = ortho def setCollisionMask(self, mask): self.pickerNode.setFromCollideMask(mask) def clearCollisionMask(self): self.pickerNode.setFromCollideMask(BitMask32.allOff()) def getCollisions(self, traverseRoot, useIntoNodePaths = False): if not base.mouseWatcherNode.hasMouse(): return [] mpos = base.mouseWatcherNode.getMouse() if self.orthographic: self.pickerRay.setFromLens(base.cam2d.node(), 0, 0) self.pickerNP.setPos(mpos.getX(), 0.0, mpos.getY()) else: self.pickerRay.setFromLens(base.cam2d.node(), mpos.getX(), mpos.getY()) self.pickerNP.setPos(0.0, 0.0, 0.0) self.collisionTraverser.traverse(traverseRoot) pickedObjects = [] if useIntoNodePaths: for i in range(self.collisionHandler.getNumEntries()): pickedObjects.append(self.collisionHandler.getEntry(i).getIntoNodePath()) else: for i in range(self.collisionHandler.getNumEntries()): pickedObjects.append(self.collisionHandler.getEntry(i)) return pickedObjects
def _initCollisions(self): name = "CogdoMazeLock-%d" % self.id collSphere = CollisionSphere(0, 0, 0.0, 0.25) collSphere.setTangible(0) collNode = CollisionNode(name) collNode.setFromCollideMask(ToontownGlobals.CatchGameBitmask) collNode.addSolid(collSphere) self.model.attachNewNode(collNode) self.enterCollisionEventName = "enter" + name
def __init__(self): self.picker = CollisionTraverser() self.pickerQ = CollisionHandlerQueue() pickerCollN = CollisionNode('heightChecker') self.pickerNode = render.attachNewNode(pickerCollN) pickerCollN.setFromCollideMask(BitMask32.bit(1)) pickerCollN.setIntoCollideMask(BitMask32.allOff()) self.pickerRay = CollisionRay(0,0,300,0,0,-1) pickerCollN.addSolid(self.pickerRay) self.picker.addCollider(self.pickerNode, self.pickerQ)
def __init__(self): self.picker = CollisionTraverser() self.pickerQ = CollisionHandlerQueue() pickerCollN = CollisionNode('mouseRay') pickerCamN = base.camera.attachNewNode(pickerCollN) pickerCollN.setFromCollideMask(BitMask32.bit(1)) pickerCollN.setIntoCollideMask(BitMask32.allOff()) self.pickerRay = CollisionRay() pickerCollN.addSolid(self.pickerRay) self.picker.addCollider(pickerCamN, self.pickerQ) self.accept('mouse1',self.pick)
def pieThrow(self, avId, timestamp, heading, pos, power): """Show local or remote toon throwing a pie.""" toon = self.activity.getAvatar(avId) if toon is None: return tossTrack, pieTrack, flyPie = self.getTossPieInterval(toon, pos[0], pos[1], pos[2] , heading, 0, 0, power) if avId == base.localAvatar.doId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) # Make the sphere intangible collSphere.setTangible(0) name = "PieSphere-%d" % avId collSphereName = self.activity.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) collNP = flyPie.attachNewNode(collNode) base.cTrav.addCollider(collNP, self.pieHandler) self.toonPieEventNames[collNP] = 'pieHit-' + collSphereName self.accept(self.toonPieEventNames[collNP], self.handlePieCollision) else: player = self.players.get(avId) if player is not None: player.faceForward() def matchRunningAnim(toon=toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel( newTossTrack, pieTrack, name="PartyCogActivity.pieTrack-%d-%s" % (avId, timestamp) ) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16. / 24.: elapsedTime = 16. / 24. # make the pie fly immediately pieTrack.start(elapsedTime) self.pieIvals.append(pieTrack) self.toonPieTracks[avId] = pieTrack
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
class RepairMousePicker: def __init__(self): self.pickerNode = CollisionNode('RepairMousePicker.pickerNode') self.pickerNP = base.cam2d.attachNewNode(self.pickerNode) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.collisionTraverser = CollisionTraverser() self.collisionHandler = CollisionHandlerQueue() self.collisionTraverser.addCollider(self.pickerNP, self.collisionHandler) self.clearCollisionMask() self.orthographic = True def destroy(self): del self.pickerNode self.pickerNP.removeNode() del self.pickerNP del self.pickerRay del self.collisionTraverser del self.collisionHandler def setOrthographic(self, ortho): self.orthographic = ortho def setCollisionMask(self, mask): self.pickerNode.setFromCollideMask(mask) def clearCollisionMask(self): self.pickerNode.setFromCollideMask(BitMask32.allOff()) def getCollisions(self, traverseRoot, useIntoNodePaths=False): if not base.mouseWatcherNode.hasMouse(): return [] mpos = base.mouseWatcherNode.getMouse() if self.orthographic: self.pickerRay.setFromLens(base.cam2d.node(), 0, 0) self.pickerNP.setPos(mpos.getX(), 0.0, mpos.getY()) else: self.pickerRay.setFromLens(base.cam2d.node(), mpos.getX(), mpos.getY()) self.pickerNP.setPos(0.0, 0.0, 0.0) self.collisionTraverser.traverse(traverseRoot) pickedObjects = [] if useIntoNodePaths: for i in range(self.collisionHandler.getNumEntries()): pickedObjects.append( self.collisionHandler.getEntry(i).getIntoNodePath()) else: for i in range(self.collisionHandler.getNumEntries()): pickedObjects.append(self.collisionHandler.getEntry(i)) return pickedObjects
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
class Selector(object): '''A Selector listens for mouse clicks and then runs select. Select then broadcasts the selected tag (if there is one)''' def __init__(self): ''' Should the traverser be shared? ''' LOG.debug("[Selector] Initializing") # The collision traverser does the checking of solids for collisions self.cTrav = CollisionTraverser() # The collision handler queue is a simple handler that records all # detected collisions during traversal self.cHandler = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.cTrav.addCollider(self.pickerNP, self.cHandler) # Start listening to clicks self.resume() def select(self, event): LOG.debug("[Selector] Selecting ") if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.cTrav.traverse(render) # TODO - change this to a lower node if self.cHandler.getNumEntries() > 0: #LOG.debug("[Selector] Entries=%d"%self.cHandler.getNumEntries()) self.cHandler.sortEntries() selectionNP = self.cHandler.getEntry(0).getIntoNodePath() selection = selectionNP.findNetTag('SelectorTag').getTag( 'SelectorTag') if selection is not '': LOG.debug("[Selector] Collision with %s" % selection) Event.Dispatcher().broadcast( Event.Event('E_EntitySelect', src=self, data=selection)) else: LOG.debug("[Selector] No collision") #Event.Dispatcher().broadcast(Event.Event('E_EntityUnSelect', src=self, data=selection)) def pause(self): Event.Dispatcher().unregister(self, 'E_Mouse_1') def resume(self): print("unpausing selector") Event.Dispatcher().register(self, 'E_Mouse_1', self.select)
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 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 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 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
class CogdoMazeExit(CogdoGameExit, DirectObject): __module__ = __name__ EnterEventName = 'CogdoMazeDoor_Enter' def __init__(self): CogdoGameExit.__init__(self) self.revealed = False self._players = [] self._initCollisions() def _initCollisions(self): collSphere = CollisionSphere(0, 0, 0, 3.0) collSphere.setTangible(0) self.collNode = CollisionNode(self.getName()) self.collNode.addSolid(collSphere) self.collNP = self.attachNewNode(self.collNode) def destroy(self): self.ignoreAll() CogdoGameExit.destroy(self) def enable(self): self.collNode.setFromCollideMask(ToontownGlobals.WallBitmask) self.accept('enter' + self.getName(), self._handleEnterCollision) def disable(self): self.ignore('enter' + self.getName()) self.collNode.setFromCollideMask(BitMask32(0)) def _handleEnterCollision(self, collEntry): messenger.send(CogdoMazeExit.EnterEventName, [self]) def onstage(self): self.unstash() self.enable() def offstage(self): self.stash() self.disable() def playerEntersDoor(self, player): if player not in self._players: self._players.append(player) self.toonEnters(player.toon) def getPlayerCount(self): return len(self._players) def hasPlayer(self, player): return player in self._players
class Selector(object): '''A Selector listens for mouse clicks and then runs select. Select then broadcasts the selected tag (if there is one)''' def __init__(self): ''' Should the traverser be shared? ''' LOG.debug("[Selector] Initializing") # The collision traverser does the checking of solids for collisions self.cTrav = CollisionTraverser() # The collision handler queue is a simple handler that records all # detected collisions during traversal self.cHandler = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.cTrav.addCollider(self.pickerNP, self.cHandler) # Start listening to clicks self.resume() def select(self, event): LOG.debug("[Selector] Selecting ") if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.cTrav.traverse(render) # TODO - change this to a lower node if self.cHandler.getNumEntries() > 0: #LOG.debug("[Selector] Entries=%d"%self.cHandler.getNumEntries()) self.cHandler.sortEntries() selectionNP = self.cHandler.getEntry(0).getIntoNodePath() selection = selectionNP.findNetTag('SelectorTag').getTag('SelectorTag') if selection is not '': LOG.debug("[Selector] Collision with %s" % selection) Event.Dispatcher().broadcast(Event.Event('E_EntitySelect', src=self, data=selection)) else: LOG.debug("[Selector] No collision") #Event.Dispatcher().broadcast(Event.Event('E_EntityUnSelect', src=self, data=selection)) def pause(self): Event.Dispatcher().unregister(self, 'E_Mouse_1') def resume(self): print("unpausing selector") Event.Dispatcher().register(self, 'E_Mouse_1', self.select)
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)
class Picker(object): ''' classdocs ''' def __init__(self, camera, mouseWatcherNode, camNode, things): ''' Constructor ''' self.mouseWatcherNode = mouseWatcherNode self.camNode = camNode self.things = things self.pickerRay = CollisionRay() self.pickerNode = CollisionNode('mouseRay') self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerNode.addSolid(self.pickerRay) self.pickerNP = camera.attachNewNode(self.pickerNode) self.pq = CollisionHandlerQueue() self.picker = CollisionTraverser() self.picker.addCollider(self.pickerNP, self.pq) def getMouseOn(self, mouse_x, mouse_y): #Set the position of the ray based on the mouse position self.pickerRay.setFromLens(self.camNode, mouse_x, mouse_y) self.picker.traverse(self.things.node) if self.pq.getNumEntries() > 0: #if we have hit something, sort the hits so that the closest #is first, and highlight that node self.pq.sortEntries() selectedNode = self.pq.getEntry(0).getIntoNode() selectedNodeId = selectedNode.getTag('nodeId') thingId = selectedNode.getTag('ID') mouseOnInfo = MouseOnInfo(self.things.getById(thingId), thingId, selectedNode, selectedNodeId, mouse_x, mouse_y) return mouseOnInfo
def _initCollisions(self): self._camCollRay = CollisionRay() camCollNode = CollisionNode('CameraToonRay') camCollNode.addSolid(self._camCollRay) camCollNode.setFromCollideMask(OTPGlobals.WallBitmask | OTPGlobals.CameraBitmask | ToontownGlobals.FloorEventBitmask | ToontownGlobals.CeilingBitmask) camCollNode.setIntoCollideMask(0) self._camCollNP = self._camera.attachNewNode(camCollNode) self._camCollNP.show() self._collOffset = Vec3(0, 0, 0.5) self._collHandler = CollisionHandlerQueue() self._collTrav = CollisionTraverser() self._collTrav.addCollider(self._camCollNP, self._collHandler) self._betweenCamAndToon = {} self._transNP = NodePath('trans') self._transNP.reparentTo(render) self._transNP.setTransparency(True) self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon) self._transNP.setBin('fixed', 10000)
def GenerateCollisionGeometry(geomFaces): collisionFaces = [] for geomFace in geomFaces: tempVerts = list(geomFace.vertex) tempVerts.reverse() colPoly = CollisionPolygon(*tempVerts) collision = CollisionNode('blockCollision') collision.addSolid(colPoly) collision.setFromCollideMask(BitMask32.allOff()) if(geomFace.blockFace == BlockFace.TOP): collision.setIntoCollideMask(Globals.BLOCK_PICKER_BITMASK) else: collision.setIntoCollideMask(Globals.BLOCK_PICKER_BITMASK | Globals.WALL_BITMASK) collisionFaces.append(collision) return collisionFaces
def init_ui(self): self.cTrav = CollisionTraverser('ui_collision_traverser') self.collision_handler = CollisionHandlerQueue() picker_node = CollisionNode('mouse_click_ray') self.picker_node_path = self.camera.attachNewNode(picker_node) picker_node.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.picker_ray = CollisionRay() picker_node.addSolid(self.picker_ray) self.cTrav.addCollider(self.picker_node_path, self.collision_handler) ''' #debug: make a visible line segment from pandac.PandaModules import LineSegs, LVecBase4f, NodePath seg_drawer = LineSegs() seg_drawer.setColor(LVecBase4f(1, 0, 0, 1)) #red seg_drawer.moveTo(0,0,0) seg_drawer.drawTo(0,100,0) NodePath(seg_drawer.create()).reparentTo(self.picker_node_path) ''' self.accept('a', self.mouse_ray)
def createCollisionHandlers(self): # Create a new collision traverser instance. We will use this to determine # if any collisions occurred after performing movement. self.cTrav = CollisionTraverser() camGroundRay = CollisionRay() camGroundRay.setOrigin(0, 0, 1000) camGroundRay.setDirection(0, 0, -1) camGroundCol = CollisionNode('camRay') camGroundCol.addSolid(camGroundRay) camGroundCol.setFromCollideMask(BitMask32.bit(0)) camGroundCol.setIntoCollideMask(BitMask32.allOff()) camGroundColNp = base.camera.attachNewNode(camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(camGroundColNp, self.camGroundHandler) # register the collision pusher self.pusher = CollisionHandlerPusher() # register collision event pattern names self.pusher.addInPattern('col-%fn-into')
def placeCollectibles(self): self.placeCol = render.attachNewNode("Collectible-Placeholder") self.placeCol.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.numObjects): # Load in the health item model self.collect = loader.loadModel(MYDIR+"/ball/jack") self.collect.setPos(0,0,0) self.collect.setH(90) self.collect.setScale(2) self.collect.reparentTo(self.placeCol) self.placeItem(self.collect) # Add spherical collision detection colSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('colSphere') sphereNode.addSolid(colSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(1)) sphereNp = self.collect.attachNewNode(sphereNode)
def showToonThrowingPie(self, avId, timestamp, heading, pos): toon = self.getAvatar(avId) if toon: (tossTrack, pieTrack, flyPie) = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, 0) def removePieFromTraverser(flyPie = flyPie): if base.cTrav: if flyPie: base.cTrav.removeCollider(flyPie) if avId == self.localAvId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = flyPie.attachNewNode(collNode) colNp.show() base.cTrav.addCollider(colNp, self.pieHandler) self.accept('pieHit-' + collSphereName, self.handlePieHitting) def matchRunningAnim(toon = toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.toonPieTracks[avId] = pieTrack
def showToonThrowingPie(self, avId, timestamp, heading, pos): toon = self.getAvatar(avId) if toon: (tossTrack, pieTrack, flyPie) = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, 0) def removePieFromTraverser(flyPie=flyPie): if base.cTrav: if flyPie: base.cTrav.removeCollider(flyPie) if avId == self.localAvId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = flyPie.attachNewNode(collNode) colNp.show() base.cTrav.addCollider(colNp, self.pieHandler) self.accept('pieHit-' + collSphereName, self.handlePieHitting) def matchRunningAnim(toon=toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.toonPieTracks[avId] = pieTrack
def gameLoop(self, task): #print "game task" # ***************** SET CAMERA ****************** base.taskMgr.add(self.rotateCamera, "rotateCamera") self.game.setPlayer(self.player) # ***************** PICKABLE SHITS *************** # setup the pickable suqre planes on the board planes = [] id_plane = 0 for k in range(3): for i in range(3): #print "adding plane: ", id_plane p = addPlane(3) p.setPos(3 * i - 2.5, 3 * k - 2.5, 3.1) p.setTag('pickable', str(id_plane)) p.hide() planes.append(p) id_plane += 1 # set picks pickerNode = CollisionNode('mouseRay') pickerNP = self.cam.attachNewNode(pickerNode) pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() pickerNode.addSolid(self.pickerRay) #pickerNP.show() self.rayQueue = CollisionHandlerQueue() self.cTrav = CollisionTraverser() self.cTrav.addCollider(pickerNP, self.rayQueue) # set action in case of pick self.accept('mouse1', self.picked)
class characterCollSystem(): def __init__(self,rootNode,trav,id): self.GroundRay=CollisionRay(0,0,10,0,0,-1) self.GroundCol = CollisionNode('colDown_'+str(id)) self.GroundCol.addSolid(self.GroundRay) self.GroundCol.setFromCollideMask(BitMask32.bit(1)) self.GroundCol.setIntoCollideMask(BitMask32.allOff()) self.GroundColNp = rootNode.attachNewNode(self.GroundCol) #self.GroundColNp.show() self.GroundHandler = CollisionHandlerQueue() trav.addCollider(self.GroundColNp, self.GroundHandler) self.EnvDetector=CollisionSphere(0, 0, 1, 0.8) self.EnvCol = CollisionNode('colEnv_'+str(id)) self.EnvCol.addSolid(self.EnvDetector) self.EnvCol.setFromCollideMask(BitMask32.bit(2)) self.EnvCol.setIntoCollideMask(BitMask32.allOff()) self.EnvColNp = rootNode.attachNewNode(self.EnvCol) #self.EnvColNp.show() self.pusher = CollisionHandlerPusher() self.pusher.addCollider(self.EnvColNp, rootNode) trav.addCollider(self.EnvColNp, self.pusher) self.trav=trav
def __init__(self, name, world, pos): ActorNode.__init__(self, name) self.nodePath = NodePath(self) self.world = world # init the model or the Actor self.model = self.getModel() self.model.reparentTo(self.nodePath) self.nodePath.setPos(*pos) self.prevPos = self.nodePath.getPos() # collision detection fromObject = self.nodePath.attachNewNode(CollisionNode(name)) self.addSolids(fromObject) fromObject.show() # setup the ground ray, needed for detecting the ground groundRay = CollisionRay() groundRay.setOrigin(0, 0, 1000) groundRay.setDirection(0, 0, -1) groundCol = CollisionNode('groundRay') groundCol.addSolid(groundRay) groundCol.setFromCollideMask(BitMask32.bit(0)) groundCol.setIntoCollideMask(BitMask32.allOff()) groundColNp = base.camera.attachNewNode(groundCol) self.groundHandler = CollisionHandlerQueue() self.world.cTrav.addCollider(groundColNp, self.groundHandler) # self.world.cTrav.addCollider(fromObject, self.world.pusher) # self.world.pusher.addCollider(fromObject, self.nodePath) self.postInit()
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.890000000000001, 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.14999999999999999) self.controlKeyWarningLabel.hide() self.waitingMoveLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForPlayersToFinishMove, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.59999999999999998, 0, -0.75), scale=0.074999999999999997) self.waitingMoveLabel.hide() self.waitingSyncLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForAISync, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.59999999999999998, 0, -0.75), scale=0.074999999999999997) self.waitingSyncLabel.hide() self.infoLabel = DirectLabel(text='', text_fg=VBase4(0, 0, 0, 1), relief=None, pos=(0.0, 0, 0.69999999999999996), scale=0.074999999999999997) self.updateInfoLabel() self.lastForceArrowUpdateTime = 0 self.sendForceArrowUpdateAsap = False self.treasures = [] self.penalties = [] self.obstacles = [] self.controlKeyPressed = False self.controlKeyWarningIval = None 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 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.loadMusic('phase_4/audio/bgm/MG_IceGame.mid') self.gameBoard = loader.loadModel( 'phase_4/models/minigames/ice_game_icerink') background = loader.loadModel('phase_4/models/minigames/ice_game_2d') background.reparentTo(self.gameBoard) 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.69999999999999996) 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.mp3') self.treasureGrabSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_vine_game_bananas.mp3') self.penaltyGrabSound = loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_fire_alt.mp3') self.tireSounds = [] for tireIndex in xrange(4): tireHit = loader.loadSfx( 'phase_4/audio/sfx/Golf_Hit_Barrier_1.mp3') wallHit = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.mp3') obstacleHit = loader.loadSfx( 'phase_4/audio/sfx/Golf_Hit_Barrier_2.mp3') self.tireSounds.append({ 'tireHit': tireHit, 'wallHit': wallHit, 'obstacleHit': obstacleHit }) self.arrowRotateSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_rotate.wav') self.arrowUpSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.mp3') self.arrowDownSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.mp3') self.scoreCircleSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_scoring_1.mp3') 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._DistributedIceGame__placeToon(self.localAvId) self.moveCameraToTop() self.scorePanels = [] base.playMusic(self.music, looping=1, volume=0.80000000000000004) 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() continue 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 None self.notify.debug('setGameReady') if DistributedMinigame.DistributedMinigame.setGameReady(self): return None for index in xrange(self.numPlayers): avId = self.avIdList[index] toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self._DistributedIceGame__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() continue def setGameStart(self, timestamp): if not self.hasLocalToon: return None self.notify.debug('setGameStart') DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() continue self.scores = [0] * self.numPlayers spacing = 0.40000000000000002 for i in xrange(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel( avId, avName) scorePanel.setScale(0.90000000000000002) scorePanel.setPos(0.75 - spacing * (self.numPlayers - 1 - i), 0.0, 0.875) scorePanel.makeTransparent(0.75) self.scorePanels.append(scorePanel) self.arrowKeys.setPressHandlers([ self._DistributedIceGame__upArrowPressed, self._DistributedIceGame__downArrowPressed, self._DistributedIceGame__leftArrowPressed, self._DistributedIceGame__rightArrowPressed, self._DistributedIceGame__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._DistributedIceGame__aimTask, self.uniqueName('aimtask')) if base.localAvatar.laffMeter: base.localAvatar.laffMeter.stop() self.sendForceArrowUpdateAsap = False 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')) 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._DistributedIceGame__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() def enterFinalResults(self): lerpTrack = Parallel() lerpDur = 0.5 tY = 0.59999999999999998 bY = -0.050000000000000003 lX = -0.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] 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 _DistributedIceGame__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() avId > 0 self.forceArrowDict[avId].show() def localForceArrow(self): if self.localAvId in self.forceArrowDict: return self.forceArrowDict[self.localAvId] else: 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 self.tireDict.has_key(localAvatar.doId): 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 _DistributedIceGame__upArrowPressed(self): pass def _DistributedIceGame__downArrowPressed(self): pass def _DistributedIceGame__leftArrowPressed(self): pass def _DistributedIceGame__rightArrowPressed(self): pass def _DistributedIceGame__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 None self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp) if self.timer != None: self.startTimer() 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 _DistributedIceGame__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 None 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 continue return True def _DistributedIceGame__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 None 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 None self.curMatch = match self.curRound = round self.updateInfoLabel() def setScores(self, match, round, scores): if not self.hasLocalToon: return None self.newMatch = match self.newRound = round self.newScores = scores def setNewState(self, state): if not self.hasLocalToon: return None 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.20000000000000001: 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 None 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 continue if goodSpot: for treasure in self.treasures: if newTreasure.nodePath.getDistance( treasure.nodePath) < treasureMargin: goodSpot = False break continue if goodSpot: self.treasures.append(newTreasure) index += 1 continue 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 continue if goodSpot: for treasure in self.treasures: if newPenalty.nodePath.getDistance( treasure.nodePath) < treasureMargin: goodSpot = False break continue if goodSpot: for penalty in self.penalties: if newPenalty.nodePath.getDistance( penalty.nodePath) < treasureMargin: goodSpot = False break continue if goodSpot: self.penalties.append(newPenalty) index += 1 continue 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 None if not int(parts[1]) == self.doId: self.notify.debug("collided with %s, but doId doesn't match" % name) return None treasureNum = int(parts[2]) if 'penalty' in parts[0]: self._DistributedIceGame__penaltyGrabbed(treasureNum) else: self._DistributedIceGame__treasureGrabbed(treasureNum) def _DistributedIceGame__treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.treasureGrabSound.play() self.sendUpdate('claimTreasure', [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return None 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 _DistributedIceGame__penaltyGrabbed(self, penaltyNum): self.penalties[penaltyNum].showGrab() self.sendUpdate('claimPenalty', [penaltyNum]) def setPenaltyGrabbed(self, avId, penaltyNum): if not self.hasLocalToon: return None 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) for count in range(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() c0 in self.tireCollideIds 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 cameraCollisionClass: def __init__( self ): self.collisionCheckSetup() def collisionCheckSetup( self ): print "setting up collision check" #No we create a ray to start above the ball and cast down. This is to #Determine the height the ball should be at and the angle the floor is #tilting. We could have used the sphere around the ball itself, but it #would not be as reliable self.cameraGroundRay = CollisionRay() #Create the ray self.cameraGroundRay.setOrigin(0,0,0.0) #Set its origin self.cameraGroundRay.setDirection(0,0,-1.0) #And its direction #Collision solids go in CollisionNode self.cameraGroundCol = CollisionNode('cameraGroundRay') #Create and name the node self.cameraGroundCol.addSolid(self.cameraGroundRay) #Add the ray self.cameraGroundCol.setFromCollideMask(bitMaskOr([GROUND])) #Set its bitmasks self.cameraGroundCol.setIntoCollideMask(bitMaskOr([])) #Attach the node to the ballRoot so that the ray is relative to the ball #(it will always be 10 feet over the ball and point down) # self.cameraGroundColNp = base.camera.attachNewNode(self.cameraGroundCol) ### the ground controller is allways looking down NOT ACTIVE self.horizontalCameraNode = base.camera.attachNewNode('horizontalCameraNode') self.horizontalCameraNode.reparentTo( base.camera ) self.cameraGroundColNp = self.horizontalCameraNode.attachNewNode(self.cameraGroundCol) #Uncomment this line to see the ray #self.cameraGroundColNp.show() ''' # the camera forward rays look in the direction of the camera self.cameraFrontRay = CollisionRay() #Create the ray self.cameraFrontRay.setOrigin (0,-1,0) #Set its origin self.cameraFrontRay.setDirection(0, 5,0) #And its direction self.cameraFrontCol = CollisionNode('cameraFrontRay') #Create and name the node self.cameraFrontCol.addSolid(self.cameraFrontRay) #Add the ray self.cameraFrontCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks self.cameraFrontCol.setIntoCollideMask(bitMaskOr([])) self.cameraFrontColNp = base.camera.attachNewNode(self.cameraFrontCol) #self.cameraFrontColNp.show() self.cameraBackRay = CollisionRay() #Create the ray self.cameraBackRay.setOrigin (0, 1,0) #Set its origin self.cameraBackRay.setDirection(0,-5,0) #And its direction self.cameraBackCol = CollisionNode('cameraBackRay') #Create and name the node self.cameraBackCol.addSolid(self.cameraBackRay) #Add the ray self.cameraBackCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks self.cameraBackCol.setIntoCollideMask(bitMaskOr([])) self.cameraBackColNp = base.camera.attachNewNode(self.cameraBackCol) #self.cameraBackColNp.show() # the camera left/right rays self.cameraLeftRay = CollisionRay() #Create the ray self.cameraLeftRay.setOrigin (-1,0,0) #Set its origin self.cameraLeftRay.setDirection( 5,0,0) #And its direction self.cameraLeftCol = CollisionNode('cameraLeftRay') #Create and name the node self.cameraLeftCol.addSolid(self.cameraLeftRay) #Add the ray self.cameraLeftCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks self.cameraLeftCol.setIntoCollideMask(bitMaskOr([])) self.cameraLeftColNp = base.camera.attachNewNode(self.cameraLeftCol) #self.cameraLeftColNp.show() self.cameraRightRay = CollisionRay() #Create the ray self.cameraRightRay.setOrigin ( 1,0,0) #Set its origin self.cameraRightRay.setDirection(-5,0,0) #And its direction self.cameraRightCol = CollisionNode('cameraRightRay') #Create and name the node self.cameraRightCol.addSolid(self.cameraRightRay) #Add the ray self.cameraRightCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks self.cameraRightCol.setIntoCollideMask(bitMaskOr([])) self.cameraRightColNp = base.camera.attachNewNode(self.cameraRightCol) #self.cameraRightColNp.show() ''' #Finally, we create a CollisionTraverser. CollisionTraversers are what #do the job of calculating collisions self.cTrav = CollisionTraverser() #Collision traverservs tell collision handlers about collisions, and then #the handler decides what to do with the information. We are using a #CollisionHandlerQueue, which simply creates a list of all of the #collisions in a given pass. There are more sophisticated handlers like #one that sends events and another that tries to keep collided objects #apart, but the results are often better with a simple queue self.cGroundHandler = CollisionHandlerQueue() self.cWallHandler = CollisionHandlerQueue() #Now we add the collision nodes that can create a collision to the #traverser. The traverser will compare these to all others nodes in the #scene. There is a limit of 32 CollisionNodes per traverser #We add the collider, and the handler to use as a pair #self.cTrav.addCollider(self.cameraBallSphere, self.cHandler) self.cTrav.addCollider(self.cameraGroundColNp, self.cGroundHandler) ''' self.cTrav.addCollider(self.cameraBackColNp, self.cWallHandler) self.cTrav.addCollider(self.cameraFrontColNp, self.cWallHandler) self.cTrav.addCollider(self.cameraLeftColNp, self.cWallHandler) self.cTrav.addCollider(self.cameraRightColNp, self.cWallHandler) ''' # we dont want this to be automatically executed #base.cTrav = self.cTrav #Collision traversers have a built in tool to help visualize collisions. #Uncomment the next line to see it. #self.cTrav.showCollisions(render) #self.cTrav.traverse( render ) # add a task to check for collisions taskMgr.add(self.collisionCheckTask, 'collisionCheckTask') def collisionCheckTask( self, task ): # make the parent of the groundCollideHandler be horizontal relative to render self.horizontalCameraNode.setHpr( render, Vec3(0,0,0)) self.cTrav.traverse( render ) #The collision handler collects the collisions. We dispatch which function #to handle the collision based on the name of what was collided into for i in range(self.cGroundHandler.getNumEntries()): self.cGroundHandler.sortEntries() entry = self.cGroundHandler.getEntry(i) object = entry.getIntoNode() self.groundCollideHandler(entry) # stop after first one break for i in range(self.cWallHandler.getNumEntries()): self.cWallHandler.sortEntries() entry = self.cWallHandler.getEntry(i) object = entry.getIntoNode() self.wallCollideHandler(entry) # stop after first one break return Task.cont def groundCollideHandler( self, colEntry ): # get Z position of collision newZ = colEntry.getSurfacePoint(render).getZ() # set position node of camera above collision point base.camera.setZ(newZ+GROUNDDISTANCE) def wallCollideHandler( self, colEntry ): # get position of collision collisionPos = colEntry.getSurfacePoint(render) # get position of camera cameraPos = base.camera.getPos(render) # distance from collisionpoint to camera distance = collisionPos - cameraPos # length of the distance distanceLength = distance.length() # if distance to collision point smaller then defined if distanceLength < MINDISTANCEWALL: # move camera backwand to be at correct distance base.camera.setPos( base.camera.getPos() - (distance * (MINDISTANCEWALL - distanceLength)))
def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.music = base.loadMusic('phase_4/audio/bgm/MG_CogThief.ogg') self.initCogInfo() for barrelIndex in xrange(CTGG.NumBarrels): barrel = loader.loadModel( 'phase_4/models/minigames/cogthief_game_gagTank') barrel.setPos(CTGG.BarrelStartingPositions[barrelIndex]) barrel.setScale(self.BarrelScale) barrel.reparentTo(render) barrel.setTag('barrelIndex', str(barrelIndex)) collSphere = CollisionSphere(0, 0, 0, 4) collSphere.setTangible(0) name = 'BarrelSphere-%d' % barrelIndex collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(CTGG.BarrelBitmask) collNode.addSolid(collSphere) colNp = barrel.attachNewNode(collNode) handler = CollisionHandlerEvent() handler.setInPattern('barrelHit-%fn') base.cTrav.addCollider(colNp, handler) self.accept('barrelHit-' + collSphereName, self.handleEnterBarrel) nodeToHide = '**/gagMoneyTen' if barrelIndex % 2: nodeToHide = '**/gagMoneyFive' iconToHide = barrel.find(nodeToHide) if not iconToHide.isEmpty(): iconToHide.hide() self.barrels.append(barrel) self.gameBoard = loader.loadModel( 'phase_4/models/minigames/cogthief_game') self.gameBoard.find('**/floor_TT').hide() self.gameBoard.find('**/floor_DD').hide() self.gameBoard.find('**/floor_DG').hide() self.gameBoard.find('**/floor_MM').hide() self.gameBoard.find('**/floor_BR').hide() self.gameBoard.find('**/floor_DL').hide() zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.gameBoard.find('**/floor_TT').show() elif zone == ToontownGlobals.DonaldsDock: self.gameBoard.find('**/floor_DD').show() elif zone == ToontownGlobals.DaisyGardens: self.gameBoard.find('**/floor_DG').show() elif zone == ToontownGlobals.MinniesMelodyland: self.gameBoard.find('**/floor_MM').show() elif zone == ToontownGlobals.TheBrrrgh: self.gameBoard.find('**/floor_BR').show() elif zone == ToontownGlobals.DonaldsDreamland: self.gameBoard.find('**/floor_DL').show() else: self.gameBoard.find('**/floor_TT').show() self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.toonSDs = {} avId = self.localAvId toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() self.loadCogs() self.toonHitTracks = {} self.toonPieTracks = {} self.sndOof = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndRewardTick = base.loadSfx( 'phase_3.5/audio/sfx/tick_counter.ogg') self.sndPerfect = base.loadSfx('phase_4/audio/sfx/ring_perfect.ogg') self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') self.jarImage = purchaseModels.find('**/Jar') self.jarImage.reparentTo(hidden) self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(-0.173, 0.0, -0.55), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) return
class Character: """A character with an animated avatar that moves left, right or forward according to the controls turned on or off in self.controlMap. Public fields: self.controlMap -- The character's movement controls self.actor -- The character's Actor (3D animated model) Public functions: __init__ -- Initialise the character move -- Move and animate the character for one frame. This is a task function that is called every frame by Panda3D. setControl -- Set one of the character's controls on or off. """ def __init__(self, model, run, walk, startPos, scale): """Initialise the character. Arguments: model -- The path to the character's model file (string) run : The path to the model's run animation (string) walk : The path to the model's walk animation (string) startPos : Where in the world the character will begin (pos) scale : The amount by which the size of the model will be scaled (float) """ self.controlMap = {"left":0, "right":0, "up":0, "down":0} self.actor = Actor(Config.MYDIR+model, {"run":Config.MYDIR+run, "walk":Config.MYDIR+walk}) self.actor.reparentTo(render) self.actor.setScale(scale) self.actor.setPos(startPos) self.controller = Controller.LocalController(self) taskMgr.add(self.move,"moveTask") # Note: deriving classes DO NOT need # to add their own move tasks to the # task manager. If they override # self.move, then their own self.move # function will get called by the # task manager (they must then # explicitly call Character.move in # that function if they want it). self.prevtime = 0 self.isMoving = False # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above ralph's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.groundRay = CollisionRay() self.groundRay.setOrigin(0,0,1000) self.groundRay.setDirection(0,0,-1) self.groundCol = CollisionNode('ralphRay') self.groundCol.addSolid(self.groundRay) self.groundCol.setFromCollideMask(BitMask32.bit(1)) self.groundCol.setIntoCollideMask(BitMask32.allOff()) self.groundColNp = self.actor.attachNewNode(self.groundCol) self.groundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.groundColNp, self.groundHandler) # Uncomment this line to see the collision rays # self.groundColNp.show() #Uncomment this line to show a visual representation of the #collisions occuring # self.cTrav.showCollisions(render) def move(self, task): """Move and animate the character for one frame. This is a task function that is called every frame by Panda3D. The character is moved according to which of it's movement controls are set, and the function keeps the character's feet on the ground and stops the character from moving if a collision is detected. This function also handles playing the characters movement animations. Arguments: task -- A direct.task.Task object passed to this function by Panda3D. Return: Task.cont -- To tell Panda3D to call this task function again next frame. """ elapsed = task.time - self.prevtime # save the character's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.actor.getPos() # pass on input self.controller.move(task, elapsed) # If the character is moving, loop the run animation. # If he is standing still, stop the animation. if (self.controlMap["up"]!=0) or (self.controlMap["left"]!=0) or (self.controlMap["right"]!=0) or (self.controlMap["down"]!=0): if self.isMoving is False: self.actor.loop("run") self.isMoving = True else: if self.isMoving: self.actor.stop() self.actor.pose("walk",5) self.isMoving = False # Now check for collisions. self.cTrav.traverse(render) # Adjust the character's Z coordinate. If the character's ray hit terrain, # update his Z. If it hit anything else, or didn't hit anything, put # him back where he was last frame. entries = [] for i in range(self.groundHandler.getNumEntries()): entry = self.groundHandler.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() == "terrain"): self.actor.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.actor.setPos(startpos) # Store the task time and continue. self.prevtime = task.time return Task.cont def setControl(self, control, value): """Set the state of one of the character's movement controls. Arguments: See self.controlMap in __init__. control -- The control to be set, must be a string matching one of the strings in self.controlMap. value -- The value to set the control to. """ # FIXME: this function is duplicated in Camera and Character, and # keyboard control settings are spread throughout the code. Maybe # add a Controllable class? self.controlMap[control] = value
class thirdPerson(DirectObject): def __init__(self, parserClass, mainClass, mapLoaderClass, modelLoaderClass): self.switchState = False #self.t = Timer() self.keyMap = {"left": 0, "right": 0, "forward": 0, "backward": 0} self.ralph = Actor( "data/models/units/ralph/ralph", { "run": "data/models/units/ralph/ralph-run", "walk": "data/models/units/ralph/ralph-walk" }) self.ralph.reparentTo(render) # self.ralph.setPos(42, 30, 0) self.ralph.setPos(6, 10, 0) self.ralph.setScale(0.1) self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_right", self.setKey, ["right", 1]) self.accept("arrow_right-up", self.setKey, ["right", 0]) self.accept("arrow_up", self.setKey, ["forward", 1]) self.accept("arrow_up-up", self.setKey, ["forward", 0]) self.accept("arrow_down", self.setKey, ["backward", 1]) self.accept("arrow_down-up", self.setKey, ["backward", 0]) self.isMoving = False self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 1000) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0)) self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) #self.ralphGroundCol.show() base.cam.reparentTo(self.ralph) base.cam.setPos(0, 9, 7) self.floater2 = NodePath(PandaNode("floater2")) self.floater2.reparentTo(self.ralph) self.floater2.setZ(self.floater2.getZ() + 6) base.cam.lookAt(self.floater2) # Uncomment this line to see the collision rays # self.ralphGroundColNp.show() # self.camGroundColNp.show() #Uncomment this line to show a visual representation of the #collisions occuring # self.cTrav.showCollisions(render) self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) taskMgr.add(self.move, "movingTask", extraArgs=[ mainClass, parserClass, mapLoaderClass, modelLoaderClass ]) #Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def move(self, mainClass, parserClass, mapLoaderClass, modelLoaderClass): # Get the time elapsed since last frame. We need this # for framerate-independent movement. elapsed = globalClock.getDt() # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"] != 0): self.ralph.setH(self.ralph.getH() + elapsed * 300) if (self.keyMap["right"] != 0): self.ralph.setH(self.ralph.getH() - elapsed * 300) if (self.keyMap["forward"] != 0): self.ralph.setY(self.ralph, -(elapsed * 50)) #25)) if (self.keyMap["backward"] != 0): self.ralph.setY(self.ralph, +(elapsed * 20)) if (self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or (self.keyMap["right"] != 0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True elif (self.keyMap["backward"] != 0): if self.isMoving is False: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # Now check for collisions. self.cTrav.traverse(render) # Adjust ralph's Z coordinate. If ralph's ray hit terrain, # update his Z. If it hit anything else, or didn't hit anything, put # him back where he was last frame. entries = [] for i in range(self.ralphGroundHandler.getNumEntries()): entry = self.ralphGroundHandler.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()[0:4] == "tile"): self.ralph.setZ(entries[0].getSurfacePoint(render).getZ()) elif (len(entries) > 0) and (entries[0].getIntoNode().getName()[0:5] == "solid"): self.ralph.setPos(startpos) x = int(entries[0].getIntoNode().getName() [len(entries[0].getIntoNode().getName()) - 6:len(entries[0].getIntoNode().getName()) - 4]) y = int(entries[0].getIntoNode().getName() [len(entries[0].getIntoNode().getName()) - 2:]) if (mapLoaderClass.tileArray[y][x].drillTime != None): mainClass.changeTile(mapLoaderClass.tileArray[y][x], 0, parserClass, modelLoaderClass, mapLoaderClass) else: self.ralph.setPos(startpos) self.ralph.setP(0) return Task.cont
class world(DirectObject): def __init__(self): base.disableMouse() base.camLens.setFar(100) self.parserClass = Parser.Parser() # Making the required instances self.mapLoaderClass = mapLoader.mapLoader(self) self.gameObjects = {} self.gameObjectID = 0 self.mapX = self.mapLoaderClass.mapConfigParser.getint( "map", "width") - 1 # Name says it all really self.mapY = self.mapLoaderClass.mapConfigParser.getint( "map", "height") - 1 self.modelLoaderClass = modelLoader.modelLoader(self) self.cameraClass = stratCam.CameraHandler(self) self.mouseClass = stratCam.mouseHandler(self) self.GUI = stratCam.GUI(self) # self.GUI = stratCam.GUI(self) self.priorities = priorities.priorities() base.setFrameRateMeter(True) ############### base.cTrav2 = CollisionTraverser('world2') # base.cTrav2.showCollisions(render) self.heightRay = CollisionRay( ) # A collision ray, used for getting the height of the terrain self.heightRay.setOrigin(0, 0, 100) self.heightRay.setDirection(0, 0, -1) self.heightCol = CollisionNode('unit Ray') self.heightCol.addSolid(self.heightRay) self.heightCol.setTag('units', 'ray1') self.heightCol.setFromCollideMask(BitMask32.bit(0)) # self.heightCol.setIntoCollideMask(BitMask32.allOff()) self.heightColNp = render.attachNewNode(self.heightCol) self.heightColNp.setPos(2, 2, 0) self.heightHandler = CollisionHandlerQueue() base.cTrav2.addCollider(self.heightColNp, self.heightHandler) ############### # myFrame = DirectFrame(frameColor=(0, 0, 0, 1), # frameSize=(-0.25, 0.25, -1, 1), # pos=(1.08, 0, 0)) # button = DirectButton(text = ("button"), scale = 0.1) # button.reparentTo(myFrame) # button.setPos(0, 0, 0.9) self.grids = astar.grid(self) self.unitHandler = unitHandler.world(self) # self.unitHandler.addUnit(0, (10,10,5), self) # self.unitHandler.addUnit(1, (6,10,5), self) # self.unitHandler.moveTo(self, (6, 34), 0) # self.unitHandler.moveTo(self, (34, 30), 1) self.buildingHandler = buildingHandler.buildingHandler(self) self.tileSelected = (0, 0) taskMgr.add(self.tskCheckWalls, "Wall checking") taskMgr.add(self.priorities.jobTask, "Jobs", extraArgs=[self]) self.loadLight() self.accept("escape", sys.exit) self.accept("1", self.unitHandler.addUnit2, extraArgs=[0, self]) self.accept("2", self.unitHandler.addUnit2, extraArgs=[1, self]) self.accept("3", self.unitHandler.addUnit2, extraArgs=[2, self]) self.accept("enter", self.buildingHandler.addBuilding2, extraArgs=[self, 0]) self.accept("p", self.priorities.addJob) print 'END OF GAMEMAIN.PY!' def tskCheckWalls(self, task): for row in self.mapLoaderClass.tileArray: for tile in row: if (tile.solid == True): aroundNo = 0 # if (tile.solidMap[1] == True): # aroundNo += 1 # if (tile.solidMap[3] == True): # aroundNo += 1 # if (tile.solidMap[5] == True): # aroundNo += 1 # if (tile.solidMap[7] == True): # aroundNo += 1 for i in tile.solidMap: if (i == True): aroundNo += 1 if (( tile.solidMap[1] == True and # If only supported by 1 other solid tile.solidMap[3] == False and tile.solidMap[5] == False and tile.solidMap[7] == False) or (tile.solidMap[1] == False and tile.solidMap[3] == True and tile.solidMap[5] == False and tile.solidMap[7] == False) or (tile.solidMap[1] == False and tile.solidMap[3] == False and tile.solidMap[5] == True and tile.solidMap[7] == False) or (tile.solidMap[1] == False and tile.solidMap[3] == False and tile.solidMap[5] == False and tile.solidMap[7] == True) or (tile.solidMap[1] == True and tile.solidMap[3] == False and tile.solidMap[5] == False and tile.solidMap[7] == True) or (tile.solidMap[1] == False and tile.solidMap[3] == True and tile.solidMap[5] == True and tile.solidMap[7] == False) or #): (aroundNo < 3)): #(tile.modelName[0:13] == 'solid no work')): self.mineWall(tile) return Task.cont def mineWall(self, firstTile): def changer(firstTile, finalTileNumber): firstTile.model.detachNode() finalTileData = self.parserClass.wall[ self.parserClass.main['wall_types'][finalTileNumber]] finalTile = copy.copy(finalTileData) finalTile.posX = firstTile.posX finalTile.posY = firstTile.posY finalTile.posZ = firstTile.posZ finalTile.cornerMap = firstTile.cornerMap finalTile.solidMap = firstTile.solidMap finalTile.reda = 0 finalTile.renu = 0 print finalTile.posX / 4, finalTile.posY / 4 if (finalTileData.solid == False): finalTile.solidMap[4] == False if (finalTile.walkable == True ): # Change the meshes for the new tile self.grids.landMesh[finalTile.posY / 4][finalTile.posX / 4] = True else: self.grids.landMesh[finalTile.posY / 4][finalTile.posX / 4] = False if (finalTile.water == True): self.grids.waterMesh[finalTile.posY / 4][finalTile.posX / 4] = True else: self.grids.waterMesh[finalTile.posY / 4][finalTile.posX / 4] = False if (finalTile.lava == True) or (finalTile.water == True) or (finalTile.walkable == True): self.grids.airMesh[finalTile.posY / 4][finalTile.posX / 4] = True else: self.grids.airMesh[finalTile.posY / 4][finalTile.posX / 4] = False elif (finalTileData.solid == True): finalTile.solidMap[4] == True self.grids.landMesh[finalTile.posY / 4][finalTile.posX / 4] = True self.grids.waterMesh[finalTile.posY / 4][finalTile.posX / 4] = True self.grids.airMesh[finalTile.posY / 4][finalTile.posX / 4] = True finalTile.model = self.modelLoaderClass.makeModel( finalTile, self ) #, mapLoaderClass) # From here on is reparenting and positioning the tile to the right place finalTile.model.reparentTo(render) finalTile.model.setPos(finalTile.posX, finalTile.posY, 0) finalTile.model.setCollideMask(0x1) tex = loader.loadTexture(finalTile.texture) finalTile.model.setTexture(tex, 1) if (firstTile.renu != 0): print self.parserClass.main['objects'][ firstTile.reda], firstTile.renu for i in range(firstTile.renu): self.modelLoaderClass.addObject(self, firstTile.reda, finalTile) return finalTile self.mapLoaderClass.tileArray[firstTile.posY / 4][firstTile.posX / 4] = changer( firstTile, 0) self.reloadSurround(self.mapLoaderClass.tileArray[firstTile.posY / 4][firstTile.posX / 4]) def reloadSurround(self, tileChanged): aroundInfo = [] yBehind = tileChanged.posY / 4 - 1 yInfront = tileChanged.posY / 4 + 1 xBehind = tileChanged.posX / 4 - 1 xInfront = tileChanged.posX / 4 + 1 if (yInfront >= self.mapY - 1): yInfront = self.mapY - 1 if (yBehind <= 0): yBehind = 0 if (xInfront >= self.mapX - 1): xInfront = self.mapX - 1 if (xBehind <= 0): xBehind = 0 aroundInfo.append( self.mapLoaderClass.tileArray[yBehind][xBehind]) # BL aroundInfo.append( self.mapLoaderClass.tileArray[yBehind][tileChanged.posX / 4]) # BC aroundInfo.append( self.mapLoaderClass.tileArray[yBehind][xInfront]) # BR aroundInfo.append(self.mapLoaderClass.tileArray[tileChanged.posY / 4][xBehind]) # L aroundInfo.append( self.mapLoaderClass.tileArray[tileChanged.posY / 4][tileChanged.posX / 4 - 1]) aroundInfo.append(self.mapLoaderClass.tileArray[tileChanged.posY / 4][xInfront]) # R aroundInfo.append( self.mapLoaderClass.tileArray[yInfront][xBehind]) # TL aroundInfo.append( self.mapLoaderClass.tileArray[yInfront][tileChanged.posX / 4]) # TC aroundInfo.append( self.mapLoaderClass.tileArray[yInfront][xInfront]) # TR name = self.mapLoaderClass.tileArray[tileChanged.posY / 4 + 1][tileChanged.posX / 4 + 1].modelName for around in aroundInfo: around.solidMap = self.modelLoaderClass.reloadSolidMap( self, around.posX / 4, around.posY / 4) around.model.remove() around.model = self.modelLoaderClass.makeModel(around, self) around.model.setCollideMask(0x01) around.model.reparentTo(render) around.model.setPos(around.posX, around.posY, 0) tex = loader.loadTexture(around.texture) around.model.setTexture(tex, 1) def loadLight(self): #Sets the lights plight = AmbientLight('my plight') light = self.parserClass.userConfig.getfloat('display', 'light') plight.setColor(VBase4(light, light, light, 0.5)) plnp = render.attachNewNode(plight) render.setLight(plnp)
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.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 = -0.05 lX = -0.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 self.tireDict.has_key(localAvatar.doId): 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 cWorld: def __init__(self): # set background color base.setBackgroundColor(0, 0, 0) # create target self.createTarget() # create boids self.createBoids() # setup camera self.setupCamera() # setup lights self.setupLights() # setup collision detection self.setupCollision() # add task taskMgr.add(self.steer, 'steer') # steer task taskMgr.add(self.moveTarget, 'moveTarget') # mouse move target task def createBoids(self): self.redBoid = cBoid() # create red boid # setup blue boid with model path, starting location, max force, and max speed self.redBoid.setup('assets/models/boid_one.egg', Vec3(0.0, 0.0, 0.0), 4.0, 0.1) # create blue boid self.blueBoid = cBoid() # setup blue boid with model path, starting location, max force, and max speed self.blueBoid.setup('assets/models/boid_two.egg', Vec3(0.0, 0.0, 0.0), 4.0, 1.0) def createTarget(self): # load in model file self.target = loader.loadModel('assets/models/target.egg') # parent self.target.reparentTo(render) # set location self.target.setPos(Vec3(0.0, 0.0, 0.0)) def setupCamera(self): # disable auto controls base.disableMouse() # set position, heading, pitch, and roll camera.setPosHpr(Vec3(0.0, -45.0, 45.0), Vec3(0.0, -45.0, 0)) def setupLights(self): # create a point light plight = PointLight('plight') # set its color plight.setColor(VBase4(1.0, 1.0, 1.0, 1)) # attach the light to the render plnp = render.attachNewNode(plight) # set position plnp.setPos(0.0, 0.0, 2.0) # turn on light render.setLight(plnp) def setupCollision(self): # create collision traverser self.picker = CollisionTraverser() # create collision handler self.pq = CollisionHandlerQueue() # create collision node self.pickerNode = CollisionNode('mouseRay') # create collision node # attach new collision node to camera node self.pickerNP = camera.attachNewNode( self.pickerNode) # attach collision node to camera # set bit mask to one self.pickerNode.setFromCollideMask(BitMask32.bit(1)) # set bit mask # create a collision ray self.pickerRay = CollisionRay() # create collision ray # add picker ray to the picker node self.pickerNode.addSolid( self.pickerRay) # add the collision ray to the collision node # make the traverser know about the picker node and its even handler queue self.picker.addCollider( self.pickerNP, self.pq) # add the colision node path and collision handler queue #self.picker.showCollisions( render ) # render or draw the collisions #self.pickerNP.show( ) # render picker ray # create col node self.colPlane = CollisionNode('colPlane') # add solid to col node plane self.colPlane.addSolid( CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0)))) # attach new node to the render self.colPlanePath = render.attachNewNode(self.colPlane) #self.colPlanePath.show( ) # render node # make the col plane look at the camera # this makes it alway look at the camera no matter the orientation # we need this because the ray nees to intersect a plane parallel # to the camera self.colPlanePath.lookAt(camera) # prop up the col plane self.colPlanePath.setP(-45) # set bit mask to one # as I understand it, this makes all col nodes with bit mask one # create collisions while ignoring others of other masks self.colPlanePath.node().setIntoCollideMask(BitMask32.bit(1)) def steer(self, Task): # seek after target self.redBoid.seek(Vec3(self.target.getPos())) # run the algorithm self.redBoid.run() # arrive at the target self.blueBoid.arrive(Vec3(self.target.getPos())) # run the algorithm self.blueBoid.run() return Task.cont # continue task def moveTarget(self, Task): # traverse through the render tree self.picker.traverse(render) # go through the queue of collisions for i in range(self.pq.getNumEntries()): entry = self.pq.getEntry(i) # get entry surfacePoint = entry.getSurfacePoint( render) # get surface point of collision self.target.setPos( surfacePoint) # set surface point to target's position if base.mouseWatcherNode.hasMouse(): # if we have a mouse mpos = base.mouseWatcherNode.getMouse( ) # get the path to the mouse # shoot ray from camera # based on X & Y coordinate of mouse self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) return Task.cont # continue task
class MouseControls(DirectObject.DirectObject): def __init__(self): self.keys = {} for char in string.ascii_lowercase: self.keys[char] = BUTTON_UP def makeKeyPair(ch): def keyUp(): self.keys[ch] = BUTTON_DOWN #print "%s UP" % (ch) def keyDown(): self.keys[ch] = BUTTON_UP #print "%s DOWN" % (ch) return [keyUp, keyDown] keyPair = makeKeyPair(char) self.accept(char, keyPair[0]) self.accept(char + '-up', keyPair[1]) self.accept('mouse1', self.leftClick) self.accept('mouse1-up', self.leftClickUp) self.accept('mouse2', self.mClick) self.accept('mouse2-up', self.mClickUp) self.accept('mouse3', self.rightClick) self.accept('mouse3-up', self.rightClickUp) self.mouse1Down = False self.mouse2Down = False self.mouse3Down = False self.trackMouseTimeOld = 0 self.trackMouseX = 0 self.trackMouseY = 0 self.trackMouse_Mouse1DownOld = False self.trackMouse_Mouse2DownOld = False self.trackMouse_Mouse3DownOld = False taskMgr.add(self.trackMouseTask, 'trackMouseTask') # base.cTrav = CollisionTraverser() self.pickerQ = CollisionHandlerQueue() self.pickerCollN = CollisionNode('mouseRay') self.pickerCamN = base.camera.attachNewNode(self.pickerCollN) self.pickerCollN.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() self.pickerCollN.addSolid(self.pickerRay) base.cTrav.addCollider(self.pickerCamN, self.pickerQ) self.objectUnderCursor = None #taskMgr.add(self.mousePickerTask, 'Mouse picker process') def leftClick(self): self.mouse1Down = True #Collision traversal pickerNode = CollisionNode('mouseRay') pickerNP = base.camera.attachNewNode(pickerNode) pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) pickerRay = CollisionRay() pickerNode.addSolid(pickerRay) myTraverser = CollisionTraverser() myHandler = CollisionHandlerQueue() myTraverser.addCollider(pickerNP, myHandler) if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) myTraverser.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if myHandler.getNumEntries() > 0: # This is so we get the closest object myHandler.sortEntries() pickedObj = myHandler.getEntry(0).getIntoNodePath() objTag = pickedObj.findNetTag('mouseCollisionTag').getTag( 'mouseCollisionTag') if objTag and len(objTag) > 0: messenger.send('object_click', [objTag]) pickerNP.remove() def leftClickUp(self): self.mouse1Down = False def mClick(self): self.mouse2Down = True def mClickUp(self): self.mouse2Down = False def rightClick(self): self.mouse3Down = True def rightClickUp(self): self.mouse3Down = False def trackMouseTask(self, task): timeElapsed = task.time - self.trackMouseTimeOld if timeElapsed < 0.05: return Task.cont self.trackMouseTimeOld = task.time if base.mouseWatcherNode.hasMouse(): mX = base.mouseWatcherNode.getMouseX() mY = base.mouseWatcherNode.getMouseY() diffX = mX - self.trackMouseX diffY = mY - self.trackMouseY if (abs(diffX) > DRAG_THRESH) or (abs(diffY) > DRAG_THRESH): messenger.send('mouseDelta', [diffX, diffY]) self.trackMouseX = mX self.trackMouseY = mY if self.trackMouse_Mouse1DownOld and self.mouse1Down: messenger.send('mouse1Delta', [diffX, diffY]) if self.trackMouse_Mouse2DownOld and self.mouse2Down: messenger.send('mouse2Delta', [diffX, diffY]) if self.trackMouse_Mouse3DownOld and self.mouse3Down: messenger.send('mouse3Delta', [diffX, diffY]) self.trackMouse_Mouse1DownOld = self.mouse1Down self.trackMouse_Mouse2DownOld = self.mouse2Down self.trackMouse_Mouse3DownOld = self.mouse3Down return Task.cont def mousePickerTask(self, task): print 'lalala: ', self.objectUnderCursor if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) #self.picker.traverse(base.render) if self.pickerQ.getNumEntries() > 0: self.pickerQ.sortEntries() firstNode = self.pickerQ.getEntry(0).getIntoNode() if firstNode != self.objectUnderCursor: if self.objectUnderCursor: messenger.send( 'interactive-scene-event', [self.objectUnderCursor.getName(), 'rollout']) print 'Rollout', self.objectUnderCursor.getName() self.objectUnderCursor = firstNode messenger.send( 'interactive-scene-event', [self.objectUnderCursor.getName(), 'rollin']) print 'Rollin', self.objectUnderCursor.getName() else: if self.objectUnderCursor: messenger.send( 'interactive-scene-event', [self.objectUnderCursor.getName(), 'rollout']) print 'Rollout', self.objectUnderCursor.getName() self.objectUnderCursor = None return task.cont
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.debug = True self.statusLabel = self.makeStatusLabel(0) self.collisionLabel = self.makeStatusLabel(1) self.world = self.loader.loadModel("world.bam") self.world.reparentTo(self.render) self.maxspeed = 100.0 # Avion à la pointe des chateaux, direction Ouest ! self.startPos = Vec3(1200, 320, 85) #print (self.startPos) self.startHpr = Vec3(0, 0, 0) #self.player.setPos(1200,320,85) #self.player.setH(0) self.player = self.loader.loadModel("alliedflanker.egg") #self.player.setPos(640,640,85) self.player.setScale(0.2, 0.2, 0.2) self.player.reparentTo(self.render) self.resetPlayer() # load the explosion ring self.explosionModel = loader.loadModel('explosion') self.explosionModel.reparentTo(self.render) self.explosionModel.setScale(0.0) self.explosionModel.setLightOff() # only one explosion at a time: self.exploding = False # performance (to be masked later by fog) and view: self.maxdistance = 1200 self.camLens.setFar(self.maxdistance) self.camLens.setFov(60) self.taskMgr.add(self.updateTask, "update") self.keyboardSetup() # relevant for world boundaries self.worldsize = 1024 self.createEnvironment() self.setupCollisions() self.textCounter = 0 def resetPlayer(self): self.player.show() #self.player.setPos(self.world,self.startPos) #self.player.setHpr(self.world,self.startHpr) self.player.setPos(self.startPos) self.player.setHpr(self.startHpr) self.speed = 10.0 #self.speed = self.maxspeed/2 #print (self.player.getPos()) def makeStatusLabel(self, i): return OnscreenText(style=2, fg=(.5,1,.5,1), pos=(-1.3,0.92-(.08 * i)), \ align=TextNode.ALeft, scale = .08, mayChange = 1) def updateTask(self, task): self.updatePlayer() self.updateCamera() self.collTrav.traverse(self.render) for i in range(self.playerGroundHandler.getNumEntries()): entry = self.playerGroundHandler.getEntry(i) if (self.debug == True): self.collisionLabel.setText("DEAD:" + str(globalClock.getFrameTime())) if (self.exploding == False): self.player.setZ( entry.getSurfacePoint(self.render).getZ() + 10) self.explosionSequence() # we will later deal with 'what to do' when the player dies return task.cont def keyboardSetup(self): self.keyMap = {"left":0, "right":0, "climb":0, "fall":0, \ "accelerate":0, "decelerate":0, "fire":0} self.accept("escape", sys.exit) ## Gestion Vitesse self.accept("a", self.setKey, ["accelerate", 1]) self.accept("a-up", self.setKey, ["accelerate", 0]) self.accept("q", self.setKey, ["decelerate", 1]) self.accept("q-up", self.setKey, ["decelerate", 0]) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_right", self.setKey, ["right", 1]) self.accept("arrow_right-up", self.setKey, ["right", 0]) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_down", self.setKey, ["climb", 1]) self.accept("arrow_down-up", self.setKey, ["climb", 0]) self.accept("arrow_up", self.setKey, ["fall", 1]) self.accept("arrow_up-up", self.setKey, ["fall", 0]) # self.accept(“space”, self.setKey, [“fire”,1]) # self.accept(“space-up”, self.setKey, [“fire”,0]) base.disableMouse() # or updateCamera will fail! def setKey(self, key, value): self.keyMap[key] = value def updateCamera(self): # see issue content for how we calculated these: self.camera.setPos(self.player, 25.6225, 3.8807, 10.2779) #self.camera.setPos(0, 0, 90) self.camera.setHpr(self.player, 94.8996, -16.6549, 1.55508) def updatePlayer(self): # Global Clock # by default, panda runs as fast as it can frame to frame scalefactor = (globalClock.getDt() * self.speed) #climbfactor = scalefactor * 0.5 #bankfactor = scalefactor #speedfactor = scalefactor * 2.9 climbfactor = scalefactor * 0.5 * 2 bankfactor = scalefactor * 2.0 speedfactor = scalefactor * 2.9 # throttle control if (self.keyMap["accelerate"] != 0): self.speed += 1 if (self.speed > self.maxspeed): self.speed = self.maxspeed elif (self.keyMap["decelerate"] != 0): self.speed -= 1 if (self.speed < 0.0): self.speed = 0.0 # Left and Right if (self.keyMap["left"] != 0 and self.speed > 0.0): self.player.setH(self.player.getH() + bankfactor) self.player.setP(self.player.getP() + bankfactor) if (self.player.getP() >= 180): self.player.setP(-180) elif (self.keyMap["right"] != 0 and self.speed > 0.0): self.player.setH(self.player.getH() - bankfactor) self.player.setP(self.player.getP() - bankfactor) if (self.player.getP() <= -180): self.player.setP(180) elif (self.player.getP() > 0): # autoreturn from right self.player.setP(self.player.getP() - (bankfactor + 0.1)) if (self.player.getP() < 0): self.player.setP(0) elif (self.player.getP() < 0): # autoreturn from left self.player.setP(self.player.getP() + (bankfactor + 0.1)) if (self.player.getP() > 0): self.player.setP(0) # Climb and Fall if (self.keyMap["climb"] != 0 and self.speed > 0.00): # faster you go, quicker you climb self.player.setZ(self.player.getZ() + climbfactor) self.player.setR(self.player.getR() + climbfactor) if (self.player.getR() >= 180): self.player.setR(-180) elif (self.keyMap["fall"] != 0 and self.speed > 0.00): self.player.setZ(self.player.getZ() - climbfactor) self.player.setR(self.player.getR() - climbfactor) if (self.player.getR() <= -180): self.player.setR(180) elif (self.player.getR() > 0): # autoreturn from up self.player.setR(self.player.getR() - (climbfactor + 0.1)) if (self.player.getR() < 0): self.player.setR(0) # avoid jitter elif (self.player.getR() < 0): # autoreturn from down self.player.setR(self.player.getR() + (climbfactor + 0.1)) if (self.player.getR() > 0): self.player.setR(0) # move forwards - our X/Y is inverted, see the issue if self.exploding == False: self.player.setX(self.player, -speedfactor) self.applyBoundaries() def createEnvironment(self): # Fog to hide a performance tweak: colour = (0.0, 0.0, 0.0) expfog = Fog("scene-wide-fog") expfog.setColor(*colour) expfog.setExpDensity(0.001) # original : 0.004 render.setFog(expfog) base.setBackgroundColor(*colour) # Our sky skydome = loader.loadModel('sky.egg') skydome.setEffect(CompassEffect.make(self.render)) skydome.setScale(self.maxdistance / 2) # bit less than "far" skydome.setZ(-65) # sink it # NOT render - you'll fly through the sky!: skydome.reparentTo(self.camera) # Our lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.6, .6, .6, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, -10, -10)) directionalLight.setColor(Vec4(1, 1, 1, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) def setupCollisions(self): self.collTrav = CollisionTraverser() self.playerGroundSphere = CollisionSphere(0, 1.5, -1.5, 1.5) self.playerGroundCol = CollisionNode('playerSphere') self.playerGroundCol.addSolid(self.playerGroundSphere) # bitmasks self.playerGroundCol.setFromCollideMask(BitMask32.bit(0)) self.playerGroundCol.setIntoCollideMask(BitMask32.allOff()) self.world.setCollideMask(BitMask32.bit(0)) # and done self.playerGroundColNp = self.player.attachNewNode( self.playerGroundCol) self.playerGroundHandler = CollisionHandlerQueue() self.collTrav.addCollider(self.playerGroundColNp, self.playerGroundHandler) # DEBUG if (self.debug == True): self.playerGroundColNp.show() self.collTrav.showCollisions(self.render) def applyBoundaries(self): if (self.player.getZ() > self.maxdistance): self.player.setZ(self.maxdistance) # should never happen once we add collision, but in case: elif (self.player.getZ() < 0): self.player.setZ(0) # and now the X/Y world boundaries: boundary = False if (self.player.getX() < 0): self.player.setX(0) boundary = True elif (self.player.getX() > self.worldsize): self.player.setX(self.worldsize) boundary = True if (self.player.getY() < 0): self.player.setY(0) boundary = True elif (self.player.getY() > self.worldsize): self.player.setY(self.worldsize) boundary = True # lets not be doing this every frame... if boundary == True and self.textCounter > 30: self.statusLabel.setText("STATUS: MAP END; TURN AROUND") elif self.textCounter > 30: self.statusLabel.setText("STATUS: OK") if self.textCounter > 30: self.textCounter = 0 else: self.textCounter = self.textCounter + 1 def explosionSequence(self): self.exploding = True self.explosionModel.setPosHpr( Vec3(self.player.getX(),self.player.getY(), \ self.player.getZ()), Vec3( self.player.getH(),0,0)) self.player.hide() taskMgr.add(self.expandExplosion, 'expandExplosion') def expandExplosion(self, Task): # expand the explosion rign each frame until a certain size if self.explosionModel.getScale() < VBase3(60.0, 60.0, 60.0): factor = globalClock.getDt() scale = self.explosionModel.getScale() scale = scale + VBase3(factor * 40, factor * 40, factor * 40) self.explosionModel.setScale(scale) return Task.cont else: self.explosionModel.setScale(0) self.exploding = False self.resetPlayer()
class Mouse(DirectObject): def __init__(self, app): # local variables for mouse class self.app = app self.init_collide() self.has_mouse = None self.prev_pos = None self.pos = None self.drag_start = None self.hovered_object = None self.button2 = False self.mouseTask = taskMgr.add(self.mouse_task, 'mouseTask') self.task = None # set up event and response to this event self.accept('mouse1', self.mouse1) self.accept('mouse1-up', self.mouse1_up) # change the mouse to accept 'right-click' to rotate camera self.accept('mouse3', self.rotateCamera) self.accept('mouse3-up', self.stopCamera) self.accept('wheel_up', self.zoomIn) self.accept('wheel_down', self.zoomOut) # set up the collision for object def init_collide(self): # why the heck he import within method from pandac.PandaModules import CollisionTraverser, CollisionNode from pandac.PandaModules import CollisionHandlerQueue, CollisionRay # init and import collision for object self.cTrav = CollisionTraverser('MousePointer') self.cQueue = CollisionHandlerQueue() self.cNode = CollisionNode('MousePointer') self.cNodePath = base.camera.attachNewNode(self.cNode) self.cNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.cRay = CollisionRay() self.cNode.addSolid(self.cRay) self.cTrav.addCollider(self.cNodePath, self.cQueue) # by the collision methods mouse is able to find out which tile mouse is at def find_object(self): if self.app.world.nodePath: self.cRay.setFromLens(base.camNode, self.pos.getX(), self.pos.getY()) self.cTrav.traverse(self.app.world.terrain.nodePath) if self.cQueue.getNumEntries() > 0: self.cQueue.sortEntries() return self.cQueue.getEntry(0).getIntoNodePath() return None # setting task for mouse def mouse_task(self, task): action = task.cont # if the current tile has a mouse point to this self.has_mouse = base.mouseWatcherNode.hasMouse() if self.has_mouse: self.pos = base.mouseWatcherNode.getMouse() if self.prev_pos: self.delta = self.pos - self.prev_pos else: self.delta = None if self.task: action = self.task(task) else: self.pos = None if self.pos: self.prev_pos = Point2(self.pos.getX(), self.pos.getY()) return action # when mouse hover over this hexagon def hover(self, task): if self.hovered_object: self.hovered_object.unhover() self.hovered_object = None if self.button2: self.camera_drag() hovered_nodePath = self.find_object() if hovered_nodePath: tile = hovered_nodePath.findNetTag('tile') if not tile.isEmpty(): tag = tile.getTag('tile') coords = tag.split(',') (x, y) = [int(n) for n in coords] # set the hovered target to be the corresponding hexagon on terrain self.hovered_object = self.app.world.terrain.rows[x][y] self.hovered_object.hover() character = hovered_nodePath.findNetTag('char') if not character.isEmpty(): tag = character.getTag('char') (team_index, char_id) = [int(n) for n in tag.split(',')] self.hovered_object = self.app.world.teams[ team_index].characters_dict[char_id] self.hovered_object.hover() ghost = hovered_nodePath.findNetTag('ghost') if not ghost.isEmpty(): tag = ghost.getTag('ghost') (team_index, char_id) = [int(n) for n in tag.split(',')] for ghostInstance in self.app.ghosts: if (ghostInstance.team.index == team_index) and (ghostInstance.id == char_id): self.hovered_object = ghostInstance self.hovered_object.hover() return task.cont def mouse1(self): self.app.state.request('mouse1') def mouse1_up(self): self.app.state.request('mouse1-up') def camera_drag(self): if self.delta: old_heading = base.camera.getH() new_heading = old_heading - self.delta.getX() * 180 base.camera.setH(new_heading % 360) old_pitch = base.camera.getP() new_pitch = old_pitch + self.delta.getY() * 90 new_pitch = max(-90, min(-10, new_pitch)) base.camera.setP(new_pitch) def rotateCamera(self): self.button2 = True def stopCamera(self): self.button2 = False def zoomIn(self): lens = base.cam.node().getLens() size = lens.getFilmSize() if size.length() >= 75: lens.setFilmSize(size / 1.2) def zoomOut(self): lens = base.cam.node().getLens() size = lens.getFilmSize() if size.length() <= 250: lens.setFilmSize(size * 1.2)
class World(DirectObject): #class World, extends DirectObject, builds the world to play the game ###################### INITIALIZATIONS ######################################### def __init__(self): mySplashScreen = SplashScreen() mySplashScreen.loading() mySplashScreen.introduction() self.promptMode() self.turnWallNotification() ##### Creating Scene ##### self.createBackground() self.loadWallModel() self.loadBallModel() self.setCamera() self.createLighting() ##### Create Controls ##### self.createKeyControls() self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "drop":0} ##### Task Manager ##### timer = 0.2 taskMgr.doMethodLater(timer, self.traverseTask, "tsk_traverse") #scans for collisions every 0.2 seconds taskMgr.add(self.move,"moveTask") #constant smooth movement ##### Collisions ##### self.createBallColliderModel() self.disableForwardMovement = False self.disableBackwardMovement = False self.disableLeftMovement = False self.disableRightMovement = False ##### Game state variables ##### self.isMoving = False self.isDropping = False self.camAngle = math.pi/2 self.direction = "W" #constant; does not change with relativity self.drop = False self.levelHeight = 2.1 self.level = 0 self.maxLevel = 6 self.currentHeight = 13.302 self.cameraHeight = 0.2 self.mode = None self.timer = "" ##### Views ##### self.xray_mode = False self.collision_mode = False self.wireframe = False ##### On-Screen Text ##### self.title = addTitle("aMAZEing") self.instructions = OnscreenText(text="[ i ]: Toggle Instructions", style=1, fg=(0, 0, 0, 1), pos=(1.3, 0.95), align=TextNode.ARight, scale=0.05) self.instr = [] self.messages = [] self.levelText = OnscreenText(text= "Level = " + str(self.level), style=1, fg=(0, 0, 0, 1), pos=(-1.3, -0.95), align=TextNode.ALeft, scale=0.07) self.directionText = OnscreenText(text="Direction = " + self.direction, style=1, fg=(0, 0, 0, 1), pos=(-1.3, -0.85), align=TextNode.ALeft, scale=0.07) self.timerText = OnscreenText(text= self.timer, style=1, fg=(1, 1, 1, 1), pos=(1.3, 0.85), align=TextNode.ARight, scale=0.07) def setKey(self, key, value): #records the state of the arrow keys self.keyMap[key] = value ###################### Onscreen Text ####################################### def postInstructions(self): #posts the instructions onto the screen inst1 = addInstructions(0.95, "[ESC]: Quit") self.instr.append(inst1) inst2 = addInstructions(0.90, "[Left Arrow]: Turn Left") self.instr.append(inst2) inst3 = addInstructions(0.85, "[Right Arrow]: Turn Right") self.instr.append(inst3) inst4 = addInstructions(0.80, "[Up Arrow]: Move Ball Forward") self.instr.append(inst4) inst5 = addInstructions(0.75, "[Down Arrow]: Move Ball Backwards") self.instr.append(inst5) inst6 = addInstructions(0.70, "[Space]: Drop Levels (if level drop is availale)") self.instr.append(inst6) inst7 = addInstructions(0.60, "[x]: Toggle XRay Mode") self.instr.append(inst7) inst8 = addInstructions(0.55, "[c]: Toggle Collision Mode") self.instr.append(inst8) inst9 = addInstructions(0.50, "[z]: Toggle Wireframe") self.instr.append(inst9) inst10 = OnscreenText(text='''Hello! Welcome to aMAZEing! You are this sphere, and your goal is to find the exit of the maze! Each level of the maze has a hole you can drop through, to move on to the next level. This maze has six levels and each maze is a 12x12. If you chose timer mode, you have 5 minutes to finish the maze, or else you lose. Good luck! You're aMAZEing :)''', style = 1, fg=(0, 0, 0, 1), pos=(0, -.1), align=TextNode.ACenter, scale=0.07) self.instr.append(inst10) def deleteInstructions(self): #deletes onscreen instructions for instr in self.instr: instr.destroy() def addNotification(self, txt): #adds a notification to the screen y = 0.9 tex = OnscreenText(text=txt, style=1, fg= (0, 0, 0, 1), pos=(0, y)) self.messages.append(tex) def deleteNotifications(self): #deletes all on-screen notifications for msg in self.messages: msg.destroy() def updateLevelText(self): #updates the level text self.levelText.destroy() levelTextPos = (-1.3, -0.95) levelScale = 0.07 self.levelText = OnscreenText(text= "Level = " + str(self.level), style=1, fg=(0, 0, 0, 1), pos=levelTextPos, align=TextNode.ALeft, scale=levelScale) def updateDirectionText(self): #updates the direction text on the screen self.directionText.destroy() directionTextPos = (-1.3, -0.85) directionScale = 0.07 self.directionText = OnscreenText(text="Direction = " + self.direction, style=1, fg=(0, 0, 0, 1), pos=directionTextPos, align=TextNode.ALeft, scale=directionScale) def updateTimerText(self): #updates timer on screen self.timerText.destroy() timerTextPos = (1.3, 0.85) timerScale = 0.07 if self.mode == "timer": self.timerText = OnscreenText(text= self.timer, style=1, fg=(1, 1, 1, 1), pos=timerTextPos, align=TextNode.ARight, scale=timerScale) def turnWallNotification(self): #give a notification sequence at the beginning notificationSeq = Sequence() notificationSeq.append(Func(addNotification,""" If you just see a blank color, it means you are facing a wall :)""")) notificationSeq.append(Wait(8)) notificationSeq.append(Func(deleteNotifications)) notificationSeq.start() def promptMode(self): #prompts for the mode modeScreen = SplashScreen() modeScreen.mode() def setMode(self, mode): #sets the mode of the game self.mode = mode if self.mode == "timer": self.setTimer() ###################### Initialization Helper Functions ##################### def createBackground(self): #black feautureless space base.win.setClearColor(Vec4(0,0,0,1)) def loadWallModel(self): #loads the wall model (the maze) wallScale = 0.3 wallModelName = self.randomWallModel() #randomly select a maze self.wallModel = loader.loadModel(wallModelName) self.wallModel.setScale(wallScale) self.wallModel.setPos(0, 0, 0) self.wallModel.setCollideMask(BitMask32.allOff()) self.wallModel.reparentTo(render) ### Setting Texture ### texScale = 0.08 self.wallModel.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldNormal) self.wallModel.setTexProjector(TextureStage.getDefault(), render, self.wallModel) self.wallModel.setTexScale(TextureStage.getDefault(), texScale) tex = loader.load3DTexture('/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/wallTex/wallTex_#.png') self.wallModel.setTexture(tex) #creating visual geometry collision self.wallModel.setCollideMask(BitMask32.bit(0)) def randomWallModel(self): #generates a random wall in the library of mazes that were #randomly generated by the Blender script "mazeGenerator" #and exported to this computer numMazes = 10 name = str(random.randint(0, numMazes)) #randomly selects a number saved in the computer path = "/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/mazeModels/maze" path += name return path def loadBallModel(self): #loads the character, a ball model #ballModelStartPos = (-8, -8, 0.701) #THIS IS THE END ballModelStartPos = (8, 8, 13.301) #level 0 ballScale = 0.01 self.ballModel = loader.loadModel("/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/ball") self.ballModel.reparentTo(render) self.ballModel.setScale(ballScale) self.ballModel.setPos(ballModelStartPos) ### Setting ball texture ### texScale = 0.08 self.ballModel.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition) self.ballModel.setTexProjector(TextureStage.getDefault(), render, self.ballModel) self.ballModel.setTexScale(TextureStage.getDefault(), texScale) tex = loader.load3DTexture('/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/ballTex/ballTex_#.png') self.ballModel.setTexture(tex) def setCamera(self): #sets up the initial camera location #camera will follow the sphere followLength = 2 camHeight = 0.2 base.disableMouse() base.camera.setPos(self.ballModel.getX(), self.ballModel.getY() - followLength, self.ballModel.getZ() + camHeight) base.camLens.setNear(0.4) #creates a floater object - will look at the floater object #above the sphere, so you can get a better view self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) def createKeyControls(self): #creates the controllers for the keys #event handler #describes what each key does when pressed and unpressed self.accept("escape", sys.exit) self.accept("arrow_left", self.turnLeft) self.accept("arrow_right", self.turnRight) self.accept("arrow_up", self.setKey, ["forward",1]) self.accept("arrow_down", self.setKey, ["backward",1]) self.accept("space", self.nowDropping) #unpressed event handlers 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("arrow_down-up", self.setKey, ["backward",0]) self.accept("space_up", self.setKey, ["drop", 0]) #views self.accept('x', self.toggle_xray_mode) self.accept('c', self.toggle_collision_mode) self.accept('z', self.toggle_wireframe) #information self.accept('i', self.postInstructions) self.accept('i-up', self.deleteInstructions) #restart self.accept('r', self.restart) #modes self.accept("t", self.setMode, ["timer"]) self.accept("m", self.setMode, ["marathon"]) def createBallColliderModel(self): #creates the collider sphere around the ball cSphereRad = 9.9 self.cTrav = CollisionTraverser() #moves over all possible collisions self.ballModelSphere = CollisionSphere(0, 0, 0, cSphereRad) #collision mesh around ball is a simple sphere self.ballModelCol = CollisionNode('ballModelSphere') self.ballModelCol.addSolid(self.ballModelSphere) self.ballModelCol.setFromCollideMask(BitMask32.bit(0)) self.ballModelCol.setIntoCollideMask(BitMask32.allOff()) self.ballModelColNp = self.ballModel.attachNewNode(self.ballModelCol) self.ballModelGroundHandler = CollisionHandlerQueue() #collision handler queue stores all collision points self.cTrav.addCollider(self.ballModelColNp, self.ballModelGroundHandler) def createLighting(self): #creates lighting for the scene aLightVal = 0.3 dLightVal1 = -5 dLightVal2 = 5 #set up the ambient light ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(aLightVal, aLightVal, aLightVal, 1)) ambientLight1 = AmbientLight("ambientLight1") ambientLight1.setColor(Vec4(aLightVal, aLightVal, aLightVal, 1)) ambientLight2 = AmbientLight("ambientLight2") ambientLight2.setColor(Vec4(aLightVal, aLightVal, aLightVal, 1)) #sets a directional light directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(dLightVal1, dLightVal1, dLightVal1)) directionalLight.setColor(Vec4(1, 1, 1, 1)) directionalLight.setSpecularColor(Vec4(0, 0, 0, 1)) #sets a directional light directionalLight1 = DirectionalLight("directionalLight2") directionalLight1.setDirection(Vec3(dLightVal2, dLightVal1, dLightVal1)) directionalLight1.setColor(Vec4(1, 1, 1, 1)) directionalLight1.setSpecularColor(Vec4(1, 1, 1, 1)) #attaches lights to scene render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(ambientLight1)) render.setLight(render.attachNewNode(ambientLight1)) render.setLight(render.attachNewNode(directionalLight)) render.setLight(render.attachNewNode(directionalLight1)) ###################### COLLISION DETECTION ##################################### def traverseTask(self, task=None): # handles collisions with collision handers and a # collision queue # essentially checks region of potential collision for collisions # and stops the ball if a collision is triggered # called by task manager self.ballModelGroundHandler.sortEntries() for i in range(self.ballModelGroundHandler.getNumEntries()): entry = self.ballModelGroundHandler.getEntry(i) if self.drop == True: #we cant drop in this situation self.ballModel.setZ(self.currentHeight) dropFailWait = 4 dropFailSeq = Sequence() dropFailSeq.append(Func(addNotification,"Whoops! You can't drop here!")) dropFailSeq.append(Wait(dropFailWait)) dropFailSeq.append(Func(deleteNotifications)) dropFailSeq.start() self.drop = False elif self.direction == "N": self.northDisableMovements() elif self.direction == "S": self.southDisableMovements() elif self.direction == "E": self.eastDisableMovements() elif self.direction == "W": self.westDisableMovements() if task: return task.cont #exit task # If there are no collisions if task: return task.cont def northDisableMovements(self): #disables movements when direction is north if self.keyMap["forward"] != 0: #if the ball was moving foward self.disableForwardMovement = True #disable forward movement if self.keyMap["backward"] != 0: self.disableBackwardMovement = True def southDisableMovements(self): #disables movements when direction is south if self.keyMap["forward"] != 0: self.disableBackwardMovement = True if self.keyMap["backward"] != 0: self.disableForwardMovement = True def eastDisableMovements(self): #disables movements when direction is east if self.keyMap["forward"] != 0: self.disableRightMovement = True if self.keyMap["backward"] != 0: self.disableLeftMovement = True def westDisableMovements(self): #disables movements when direction is west if self.keyMap["forward"] != 0: self.disableLeftMovement = True if self.keyMap["backward"] != 0: self.disableRightMovement = True def checkCollisions(self): #checks for collisions self.cTrav.traverse(render) def enableAllWalls(self): #enables all walls by disabling all the disable wall functions self.disableLeftMovement = False self.disableRightMovement = False self.disableForwardMovement = False self.disableBackwardMovement = False def inCollision(self): #return true if we are in a collision right now, false otherwise if (self.disableForwardMovement == True or self.disableBackwardMovement == True or self.disableRightMovement == True or self.disableLeftMovement): return True return False def checkForWin(self): #checks for a win, toggles win splash sceen if we win yLoc = self.ballModel.getY() exitBound = -9.1 if yLoc < exitBound: winScreen = SplashScreen() winScreen.win() if self.mode == "timer": self.checkForTimerLoss() def checkForTimerLoss(self): #checks to see the time, will lose if past 5 minutes if self.timer == "0:05:00": loseScreen = SplashScreen() loseScreen.lose() ###################### MOVEMENTS ############################################### def move(self, task): # Accepts arrow keys to move the player front and back # Also deals with grid checking and collision detection step = 0.03 #movement animation self.movementAnimation(step) #rotation animation self.rotationAnimation() base.camera.setX(self.ballModel.getX() + math.sin(self.camAngle)) base.camera.setY(self.ballModel.getY() + math.cos(self.camAngle)) self.resetCamDist() self.checkCollisions() self.lookAtFloater() self.checkForWin() return task.cont def resetCamDist(self): #resets the camera distance to a specific distance #keeps distance relatively constant camFarDist = 0.75 camCloseDist = 0.7 camvec = self.ballModel.getPos() - base.camera.getPos() #vector between ball and camera camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > camFarDist): base.camera.setPos(base.camera.getPos() + camvec*(camdist-camFarDist)) camdist = camFarDist if (camdist < camCloseDist): base.camera.setPos(base.camera.getPos() - camvec*(camCloseDist-camdist)) camdist = camCloseDist base.camera.lookAt(self.ballModel) def lookAtFloater(self): #looks at the floater above the sphere floaterHeight = 0.23 self.floater.setPos(self.ballModel.getPos()) self.floater.setZ(self.ballModel.getZ() + floaterHeight) base.camera.lookAt(self.floater) ####################### Movement Animation ################################# def ballIsMoving(self): #notes if the ball is moving or not with self.isMoving variable if (self.keyMap["forward"]!=0) or (self.keyMap["backward"]!=0): if self.isMoving == False: self.isMoving = True elif self.keyMap["forward"] == 0 and self.keyMap["backward"] == 0: self.isMoving = False def movementAnimation(self, step): #describes the movement animation if self.drop == True: self.dropMovementAnimation(step) elif self.direction == "N": self.northMovementAnimation(step) elif self.direction == "S": self.southMovementAnimation(step) elif self.direction == "E": self.eastMovementAnimation(step) elif self.direction == "W": self.westMovementAnimation(step) def northMovementAnimation(self, step): #describes animation when direction is north if (self.keyMap["forward"]!=0): #if you are pressing forward if self.disableForwardMovement == False: #if you are just moving through space... self.ballModel.setY(self.ballModel.getY() + step) if self.disableBackwardMovement == True: #if you had moved backwards into a wall #and you want to move forward again self.ballModel.setY(self.ballModel.getY() + step) self.disableBackwardMovement = False if (self.keyMap["backward"]!=0): #if you are pressing backwards if self.disableBackwardMovement == False: #if you are just moving backwards through space... self.ballModel.setY(self.ballModel.getY() - step) if self.disableForwardMovement == True: #if you had moved forward into a wall #and want to back away from the wall self.ballModel.setY(self.ballModel.getY() - step) self.disableForwardMovement = False def southMovementAnimation(self, step): #describes animation when direction is north #same relative set of animations to northMovementAnimation #but opposite if (self.keyMap["forward"]!=0): if self.disableBackwardMovement == False: self.ballModel.setY(self.ballModel.getY() - step) if self.disableForwardMovement == True: self.ballModel.setY(self.ballModel.getY() - step) self.disableForwardMovement = False if (self.keyMap["backward"]!=0): if self.disableForwardMovement == False: self.ballModel.setY(self.ballModel.getY() + step) if self.disableBackwardMovement == True: self.ballModel.setY(self.ballModel.getY() + step) self.disableBackwardMovement = False def eastMovementAnimation(self, step): #describes animation when direction is east #same relative as north and south movement animations #but relative to the x axis #and disabling/enabling right and left movement at collisions if (self.keyMap["forward"]!=0): if self.disableRightMovement == False: self.ballModel.setX(self.ballModel.getX() + step) if self.disableLeftMovement == True: self.ballModel.setX(self.ballModel.getX() + step) self.disableLeftMovement = False if (self.keyMap["backward"]!=0): if self.disableLeftMovement == False: self.ballModel.setX(self.ballModel.getX() - step) if self.disableRightMovement == True: self.ballModel.setX(self.ballModel.getX() - step) self.disableRightMovement = False def westMovementAnimation(self, step): #describes animation when direction is west #relatively same animations as the east movement animations #exact opposite if (self.keyMap["forward"]!=0): if self.disableLeftMovement == False: self.ballModel.setX(self.ballModel.getX() - step) if self.disableRightMovement == True: self.ballModel.setX(self.ballModel.getX() - step) self.disableRightMovement = False if (self.keyMap["backward"]!=0): if self.disableRightMovement == False: self.ballModel.setX(self.ballModel.getX() + step) if self.disableLeftMovement == True: self.ballModel.setX(self.ballModel.getX() + step) self.disableLeftMovement = False def turnRight(self): #turns right in the animation #uses an interval to slowly rotate camera around initial = self.camAngle final = self.camAngle + math.pi/2 #turn animation turnTime = 0.2 turnRightSeq = Sequence() turnRightSeq.append(LerpFunc(self.changeCamAngle, turnTime, initial, final, 'easeInOut')) turnRightSeq.start() self.setKey("right", 1) #notes that the right key is pressed #changes the direction right, based on current direction if self.direction == "N": self.direction = "E" elif self.direction == "E": self.direction = "S" elif self.direction == "S": self.direction = "W" else: self.direction = "N" #when you turn, all the collision disablements should be True #just checking #self.enableAllWalls() #update the label self.updateDirectionText() def turnLeft(self): #turns left initial = self.camAngle final = self.camAngle - math.pi/2 #turn animation turnTime = 0.2 turnRightSeq = Sequence() turnRightSeq.append(LerpFunc(self.changeCamAngle, turnTime, initial, final, 'easeInOut')) turnRightSeq.start() self.setKey("left", 1) #notes that left key is pressed #changes the direction left, based on current direction if self.direction == "N": self.direction = "W" elif self.direction == "W": self.direction = "S" elif self.direction == "S": self.direction = "E" else: self.direction = "N" #when you turn, all the collision disablements should be True #just checking #self.enableAllWalls() #update the label self.updateDirectionText() def changeCamAngle(self, angle): #changes the camAngle to angle self.camAngle = angle def dropMovementAnimation(self, step): #describes movement when drop is hit a = 0.1 if self.keyMap["drop"] != 0: if self.ballModel.getZ() > self.currentHeight - self.levelHeight+ a: self.ballModel.setZ(self.ballModel.getZ() - step) else: self.currentHeight -= self.levelHeight self.level += 1 self.updateLevelText() self.drop = False base.camera.setZ(self.ballModel.getZ() + self.cameraHeight) def nowDropping(self): #toggles isDropping boolean self.drop = True self.setKey("drop", 1) ################## Ball Rotation Animation ################################# def rotationAnimation(self): #describes the rotation movement of sphere self.ballIsMoving() speed=300 inCollision = self.inCollision() if self.isMoving and not inCollision: if self.direction == "N": self.northRotationAnimation(speed) if self.direction == "S": self.southRotationAnimation(speed) if self.direction == "E": self.eastRotationAnimation(speed) if self.direction == "W": self.westRotationAnimation(speed) def northRotationAnimation(self, speed): #describes the rotation animation if direction is north if self.keyMap["forward"] != 0: self.ballModel.setP(self.ballModel.getP()-speed*globalClock.getDt()) elif self.keyMap["backward"] != 0: self.ballModel.setP(self.ballModel.getP()+speed*globalClock.getDt()) def southRotationAnimation(self, speed): #describes the rotaiton animation if the direction is south if self.keyMap["backward"] != 0: self.ballModel.setP(self.ballModel.getP()-speed*globalClock.getDt()) elif self.keyMap["forward"] != 0: self.ballModel.setP(self.ballModel.getP()+speed*globalClock.getDt()) def eastRotationAnimation(self, speed): #describes the rotation animation if the direction is east if self.keyMap["backward"] != 0: self.ballModel.setR(self.ballModel.getR()-speed*globalClock.getDt()) elif self.keyMap["forward"] != 0: self.ballModel.setR(self.ballModel.getR()+speed*globalClock.getDt()) def westRotationAnimation(self, speed): #describes the rotation animation if the direction is west if self.keyMap["forward"] != 0: self.ballModel.setR(self.ballModel.getR()-speed*globalClock.getDt()) elif self.keyMap["backward"] != 0: self.ballModel.setR(self.ballModel.getR()+speed*globalClock.getDt()) ###################### VIEWS ################################################### def toggle_xray_mode(self): #Toggle X-ray mode on and off. #Note: slows down program considerably xRayA = 0.5 self.xray_mode = not self.xray_mode if self.xray_mode: self.wallModel.setColorScale((1, 1, 1, xRayA)) self.wallModel.setTransparency(TransparencyAttrib.MDual) else: self.wallModel.setColorScaleOff() self.wallModel.setTransparency(TransparencyAttrib.MNone) def toggle_collision_mode(self): #Toggle collision mode on and off #Shows visual representation of the collisions occuring self.collision_mode = not self.collision_mode if self.collision_mode == True: # Note: Slows the program down considerably self.cTrav.showCollisions(render) else: self.cTrav.hideCollisions() def toggle_wireframe(self): #toggles wireframe view self.wireframe = not self.wireframe if self.wireframe: self.wallModel.setRenderModeWireframe() else: self.wallModel.setRenderModeFilled() ##################### RESTART ################################################## def restart(self): #restarts the game loading = SplashScreen() loading.loading() self.reset() def reset(self): #resets the maze, resets the location of the character #removes all notes self.wallModel.removeNode() self.ballModel.removeNode() #resets notes self.loadWallModel() self.loadBallModel() self.createBallColliderModel() self.resetCamDist() #resets timers taskMgr.remove("timerTask") self.timer = "" self.timerText.destroy() self.promptMode() #################### TIMER ##################################################### def setTimer(self): #code from panda.egg user on Panda3D, #"How to use Timer, a small example maybe?" forum #creates a timer self.timer = DirectLabel(pos=Vec3(1, 0.85),scale=0.08) taskMgr.add(self.timerTask, "timerTask") def dCharstr(self, theString): #code from panda.egg user on Panda3D, #"How to use Timer, a small example maybe?" forum #turns time string into a readable clock string if len(theString) != 2: theString = '0' + theString return theString def timerTask(self, task): #code from panda.egg user on Panda3D, #"How to use Timer, a small example maybe?" forum #task for resetting timer in timer mode secondsTime = int(task.time) minutesTime = int(secondsTime/60) hoursTime = int(minutesTime/60) self.timer = (str(hoursTime) + ':' + self.dCharstr(str(minutesTime%60)) + ':' + self.dCharstr(str(secondsTime%60))) self.updateTimerText() return Task.cont