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()
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 _DistributedBanquetTable__endFireWater(self): if self.aimStart == None: return None if not self.state == "Controlled": return None if not self.avId == localAvatar.doId: return None taskMgr.remove(self.waterPowerTaskName) messenger.send("wakeup") self.aimStart = None origin = self.nozzle.getPos(render) target = self.boss.getPos(render) angle = deg2Rad(self.waterPitcherNode.getH() + 90) x = math.cos(angle) y = math.sin(angle) fireVector = Point3(x, y, 0) if self.power < 0.001: self.power = 0.001 self.lastPowerFired = self.power fireVector *= self.fireLength * self.power target = origin + fireVector segment = CollisionSegment(origin[0], origin[1], origin[2], target[0], target[1], target[2]) fromObject = render.attachNewNode(CollisionNode("pitcherColNode")) fromObject.node().addSolid(segment) fromObject.node().setFromCollideMask( ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask ) fromObject.node().setIntoCollideMask(BitMask32.allOff()) queue = CollisionHandlerQueue() base.cTrav.addCollider(fromObject, queue) base.cTrav.traverse(render) queue.sortEntries() self.hitObject = None if queue.getNumEntries(): entry = queue.getEntry(0) target = entry.getSurfacePoint(render) self.hitObject = entry.getIntoNodePath() base.cTrav.removeCollider(fromObject) fromObject.removeNode() self.d_firingWater(origin, target) self.fireWater(origin, target) self.resetPowerBar()
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 __endFireWater(self): if self.aimStart == None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return taskMgr.remove(self.waterPowerTaskName) messenger.send('wakeup') self.aimStart = None origin = self.nozzle.getPos(render) target = self.boss.getPos(render) angle = deg2Rad(self.waterPitcherNode.getH() + 90) x = math.cos(angle) y = math.sin(angle) fireVector = Point3(x, y, 0) if self.power < 0.001: self.power = 0.001 self.lastPowerFired = self.power fireVector *= self.fireLength * self.power target = origin + fireVector segment = CollisionSegment(origin[0], origin[1], origin[2], target[0], target[1], target[2]) fromObject = render.attachNewNode(CollisionNode('pitcherColNode')) fromObject.node().addSolid(segment) fromObject.node().setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) fromObject.node().setIntoCollideMask(BitMask32.allOff()) queue = CollisionHandlerQueue() base.cTrav.addCollider(fromObject, queue) base.cTrav.traverse(render) queue.sortEntries() self.hitObject = None if queue.getNumEntries(): entry = queue.getEntry(0) target = entry.getSurfacePoint(render) self.hitObject = entry.getIntoNodePath() base.cTrav.removeCollider(fromObject) fromObject.removeNode() self.d_firingWater(origin, target) self.fireWater(origin, target) self.resetPowerBar() return
class heightChecker(): 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 getHeight(self,obj,pos): res=0 self.pickerNode.setPos(pos) self.picker.traverse(obj) if self.pickerQ.getNumEntries() > 0: self.pickerQ.sortEntries() res=self.pickerQ.getEntry(0).getSurfacePoint(render).getZ() return res
class Gui3D: def __init__(self, game_data, gfx_manager): self.game_data = game_data self.gui_traverser = CollisionTraverser() self.handler = CollisionHandlerQueue() self.selectable_objects = {} for cid, model in gfx_manager.character_models.items(): new_collision_node = CollisionNode('person_' + str(cid)) new_collision_node.addSolid( CollisionTube(0, 0, 0.5, 0, 0, 1.5, 0.5)) new_collision_nodepath = model.attachNewNode(new_collision_node) new_collision_nodepath.setTag("type", "character") new_collision_nodepath.setTag("id", str(cid)) picker_node = CollisionNode('mouseRay') picker_np = camera.attachNewNode(picker_node) self.picker_ray = CollisionRay() picker_node.addSolid(self.picker_ray) self.gui_traverser.addCollider(picker_np, self.handler) self.floor = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) self.floor_np = render.attachNewNode(CollisionNode('floor')) self.floor_np.setTag("type", "ground") self.floor_np.node().addSolid(self.floor) def mouse_click(self): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.picker_ray.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.gui_traverser.traverse(render) num_entries = self.handler.getNumEntries() if num_entries > 0: self.handler.sortEntries() entry = self.handler.getEntry(0) selected = entry.getIntoNodePath() selected_type = selected.getTag("type") if selected_type == "character": self.game_data.select_character(int(selected.getTag("id"))) elif selected_type == "ground": self.game_data.click_point(entry.getSurfacePoint(render))
class Gui3D: def __init__(self, game_data, gfx_manager): self.game_data = game_data self.gui_traverser = CollisionTraverser() self.handler = CollisionHandlerQueue() self.selectable_objects = {} for cid, model in gfx_manager.character_models.items(): new_collision_node = CollisionNode('person_' + str(cid)) new_collision_node.addSolid(CollisionTube(0, 0, 0.5, 0, 0, 1.5, 0.5)) new_collision_nodepath = model.attachNewNode(new_collision_node) new_collision_nodepath.setTag("type","character") new_collision_nodepath.setTag("id",str(cid)) picker_node = CollisionNode('mouseRay') picker_np = camera.attachNewNode(picker_node) self.picker_ray = CollisionRay() picker_node.addSolid(self.picker_ray) self.gui_traverser.addCollider(picker_np, self.handler) self.floor = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) self.floor_np = render.attachNewNode(CollisionNode('floor')) self.floor_np.setTag("type", "ground") self.floor_np.node().addSolid(self.floor) def mouse_click(self): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.picker_ray.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.gui_traverser.traverse(render) num_entries = self.handler.getNumEntries() if num_entries > 0: self.handler.sortEntries() entry = self.handler.getEntry(0) selected = entry.getIntoNodePath() selected_type = selected.getTag("type") if selected_type == "character": self.game_data.select_character(int(selected.getTag("id"))) elif selected_type == "ground": self.game_data.click_point(entry.getSurfacePoint(render))
class Hero(DirectObject): def __init__(self,no): self.HeroStats(no) self.display() # self.displaynot() self.SetupEvents() self.Collision() self.Loader() self.SkillStatus() self.sec=0 self.min=0 self.heroPace=None self.timesec = OnscreenText(text = '', pos = (1.2,-0.725),fg=(1,1,1,1),mayChange=1,scale=0.05) self.timemin = OnscreenText(text = '', pos = (1,-0.725),fg=(1,1,1,1),mayChange=1,scale=0.05) self.deathtxt=OnscreenText(text="",pos=(0.5,0.9),scale=0.5) taskMgr.add(self.update,"update") taskMgr.doMethodLater(1,self.Second,"second") taskMgr.add(self.MousePos,"mouse") def HeroStats(self,no): self.char={} self.char=hero[no] self.name=self.char['name'] self.model=Actor(MYDIRMODEL+self.char['model']+'.egg') self.type=None self.heroicon=self.char['icon'][0] self.skillicons=(self.char['icon'][1],self.char['icon'][2],self.char['icon'][3],self.char['icon'][4]) self.StartPos=Point3(25,25,0) self.gold=4000 self.goldrate = 1 self.items=[-1,-1,-1,-1,-1,-1] #each stores the no of the item self.itemindex=0 self.itemname="self.itemb" self.range=self.char['range'] self.strdt=self.char['strdt'] self.agidt=self.char['agidt'] self.intdt=self.char['intdt'] self.type=self.char['type'] self.Delta1=0 self.Delta2=0 self.Delta3=0 self.Delta4=0 self.Delta5=0 self.lvl=0 self.xp=0 self.Input=None self.str=self.char['str']+(self.strdt*self.lvl) self.agi=self.char['agi'] + (self.agidt*self.lvl) self.int=self.char['int'] +(self.intdt*self.lvl) self.basehp=590+self.str*19 self.basemp=220+(self.int*13) self.maxhp=590 +(self.str*19) self.curhp=self.maxhp self.maxmp=220 +(self.int*13) self.curmp=self.maxmp self.armor=self.char['armor'] +(self.agi/7) self.atkspeed=1.5/self.agi if self.type=='str': self.TYPESTR() if self.type=='agi': self.TYPEAGI() if self.type=='int': self.TYPEINT() self.healrate=0.003 *self.str self.mprate=0.02 *self.int self.res=0.25 self.speed=self.char['speed'] self.skill=0 self.isDead=False self.lon=pi*(self.getX()+10)*(self.getY()+10) def Loader(self): self.model=Actor("models/ralph", {"run": "models/ralph-run"}) # self.model=Actor(MYDIRMODEL+self.model+'.egg') self.model.setScale(3) # self.model.setHpr(90,270,0) self.model.setTransparency(0.5) # self.model.setScale(0.1) self.model.setPos(self.StartPos) self.model.reparentTo(render) # self.model.setColor(0, 0, 0, 0) self.model.loop("run") # self.Input=Input(self.model) Flame(self,self.model) #-------------------------------------------------------------Display Function---------------------------------------------------# def TYPESTR(self): self.mindamage=self.char['min']+self.str+self.Delta1 self.maxdamage=self.char['max']+self.str+self.Delta1 self.damage=range(int(self.mindamage),int(self.maxdamage)) def TYPEAGI(self): self.mindamage=self.char['min']+self.agi+self.Delta1 self.maxdamage=self.char['max']+self.agi+self.Delta1 self.damage=range(int(self.mindamage),int(self.maxdamage)) def TYPEINT(self): self.mindamage=self.char['min']+self.int+self.Delta1 self.maxdamage=self.char['max']+self.int+self.Delta1 self.damage=range(int(self.mindamage),int(self.maxdamage)) def TYPE(self): pass def display(self): x,y,z=self.model.getX(),self.model.getY(),self.model.getZ() base.camera.setPos(x,y,z+180) base.camera.setP(-30) base.camera.lookAt(self.model) self.panel=aspect2d.attachNewNode("panel") self.panel.setTransparency(1) self.SKNode=aspect2d.attachNewNode("skl") self.SKNode.setTransparency(0) self.HP=DirectLabel(text='',parent = self.panel,text_fg=(0,0.9,0,1),frameColor=(0,0,0,0),pos=(-0.41,0,-0.850),scale=0.04) self.MP=DirectLabel(text='',parent = self.panel,text_fg=(0,0,0.8,1),frameColor=(0,0,0,0),pos=(-0.41,0,-0.912),scale=0.04) self.LVL=DirectLabel(text ="Level %d"%(self.lvl+1),parent = self.panel,text_fg=(0,0,0,1),frameColor=(0,0,0,0),pos =(-0.5,0,-0.79),scale=Sc) Text1(self,"Damage",-0.26,-0.02,-1) Text1(self,"Armor",-0.27,0.03,-1) Text1(self,"Str",-0.25,0.085,-1) Text1(self,"Agi",-0.25,0.13,-1) Text1(self,"Int",-0.25,0.17,-1) self.DAM=Text2(self,"%d-%d",(self.mindamage-self.Delta1,self.maxdamage-self.Delta1),-0.40,-0.02,-1) self.ARM=Text2(self,"%d",(self.armor-self.Delta2),-0.40,0.03,-1) self.STR=Text2(self,"%d",(self.str-self.Delta3),-0.40,0.085,-1) self.AGI=Text2(self,"%d",(self.agi-self.Delta4),-0.40,0.13,-1) self.INT=Text2(self,"%d",(self.int-self.Delta5),-0.40,0.17,-1) if self.Delta1!=0: self.damdelta=Text3(self,"%d",self.Delta1,-0.4,-0.02,-1) if self.Delta2!=0: self.armdelta=Text3(self,"%d",self.Delta2,-0.4,0.03,-1) if self.Delta3!=0: self.strdelta=Text3(self,"%d",self.Delta3,-0.36,0.085,-1) if self.Delta4!=0: self.agidelta=Text3(self,"%d",self.Delta4,-0.44,0.13,-1) if self.Delta5!=0: self.intdelta=Text3(self,"%d",self.Delta5,-0.44,0.17,-1) self.hpbar = DirectWaitBar(barColor=(0,0.176470,0,1),parent = self.panel,scale=(0.3,0,0.23), frameColor=(0,0,0,1),pos = (0,0,-0.84)) self.mpbar=DirectWaitBar(barColor=(0,0,0.6,1),parent = self.panel,scale=(0.3,0,0.23), frameColor=(0,0,0,1),pos = (0,0,-0.90)) self.lvlbar=DirectWaitBar(barColor=(0,0,0.2,1),parent = self.panel,image='glue/lvlbar.png',image_scale=(1.1,0,0.2),scale=0.35, pos = (0,0,-0.8)) self.lvlbar.setTransparency(1) self.lvlbar.detachNode() self.skbtn1=DirectButton(image=self.skillicons[0]+'.png',parent=self.SKNode,pos=(posx-1.3,0,posy-1.2),pad=(-0.1,-0.1),scale=biconscale,command=self.SkillNo,extraArgs=[0]) self.skbtn2=DirectButton(image=self.skillicons[1]+'.png',parent=self.SKNode,pos=(posx-1.3+0.14,0,posy-1.2),pad=(-0.1,-0.1),scale=biconscale,command=self.SkillNo,extraArgs=[1]) self.skbtn3=DirectButton(image=self.skillicons[2]+'.png',parent=self.SKNode,pos=(posx-1.3+0.28,0,posy-1.2),pad=(-0.1,-0.1),scale=biconscale,command=self.SkillNo,extraArgs=[2]) self.skbtn4=DirectButton(image=self.skillicons[3]+'.png',parent=self.SKNode,pos=(posx-1.3+0.42,0,posy-1.2),pad=(-0.1,-0.1),scale=biconscale,command=self.SkillNo,extraArgs=[3]) self.b2 = DirectButton(text ="dam",parent = self.panel,pos=(-0.5,0,0),enableEdit=1,scale=(0.25,0,0.1),command=self.hurt,extraArgs=[200]) self.b3 = DirectButton(text ="",image='tome.tga',pos=(0.5,0,0),frameColor=(0,0,0,0),pad=(-0.1,-0.1),enableEdit=1,scale=(0.07,0,0.07),command=self.itemBuy,extraArgs=[0,300]) self.GOLD=OnscreenText(text='',fg=(1,1,1,1),pos=(1.225,-0.84),scale=0.05) # self.escapeEvent = OnscreenText(text=HELPTEXT, font = font,style=1, fg=(1,1,1,1), pos=(-0.82, -0.725),align=TextNode.ALeft, scale = .045) def displaynot(self): self.panel.detachNode() self.SKNode.detachNode() #------------------------------------------------------------Set Functions--------------------------------------------------------# def setDamage(self,amt): if delta >1: self.damage+=delta else: self.damage=self.damage+self.damage*delta def Delta(self,amt1,amt2,amt3,amt4,amt5): if amt1!=0: #After changes occur for that period the taks sets the values to zero self.Delta1+=amt1 if amt2!=0: self.Delta2+=amt2 if amt3!=0: self.Delta3+=amt3 if amt4!=0: self.Delta4+=amt3 if amt5!=0: self.Delta5+=amt3 def hurt(self,amt): if self.curhp>0: if self.curhp<=self.maxhp: self.curhp-=amt*1 def hurtMag(self,delta): if self.curhp>0: if self.curhp<=self.maxhp: self.curhp-=delta*self.res def heal(self,delta): if self.curhp!=self.maxhp: if self.curhp < self.maxhp: self.curhp+=delta def replenish(self,delta): if self.curmp!=self.maxmp: if self.curmp < self.maxmp: if self.curmp>0: self.curmp+=delta def manaspend(self,amt): if self.curmp>amt: self.curmp-=amt def setSpeed(self,delta): if delta > 1: self.speed+=delta else: self.speed=self.speed+self.speed*delta def setArmor(self,delta): self.armor+=delta def setPos(self,x,y,z): self.model.setPos(x,y,z) def setHPColor(self): if self.curhp<0.25*self.maxhp: self.hpbar['barColor']=(1,0,0,1) elif self.curhp<0.5*self.maxhp: self.hpbar['barColor']=(1,0.5,0,1) elif self.curhp<0.75*self.maxhp: self.hpbar['barColor']=(1,1,0,1) else: self.hpbar['barColor']=(0,0.176470,0,1) #-------------------------------------------------------------Setup Keys And EVENTS--------------------------------------------------# def SetupEvents(self): self.dt=0 self.keyMap = {"left":0, "right":0, "forward":0} self.isMoving = False self.Change=False self.Animate=False self.pos3d=None self.target=Point3() self.dist=0 self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) self.Text = OnscreenText(text="Set PanRate",pos=(-1.25,-0.15),scale=0.1) self.slider = DirectSlider(range=(20,100), value=50, pageSize=2, pos=(-1.25,0,-0.2),scale= (0.2,0.2,0.2), command=self.setScrollSpeed) self.dumm=loader.loadModel("models/panda.egg") self.dumm.reparentTo(render) self.dumm.setTag("Unit",'1') self.dumm.setPos(0,0,0) self.mini=0 self.x1,self.y1=self.model.getX(),self.model.getY() self.x2,self.y2=self.dumm.getX(),self.dumm.getY() self.fired=False self.atk=Attack(self.model,self.dumm,1.4) self.accept("arrow_left", self.setKey1, ["left",1,True]) self.accept("arrow_right", self.setKey1, ["right",1,True]) self.accept("arrow_up", self.setKey1, ["forward",1,True]) self.accept("arrow_left-up", self.setKey1, ["left",0,False]) self.accept("arrow_right-up", self.setKey1, ["right",0,False]) self.accept("arrow_up-up", self.setKey1, ["forward",0,False]) self.accept("mouse1",self.ObjectClick) self.accept("mouse3",self.MoveHero) def MoveHero(self): self.startR=self.model.getHpr() self.target=self.mpos3d x2,y2,z2=self.target.getX(),self.target.getY(),self.target.getZ() h1,p1,r1=self.model.getH(),self.model.getP(),self.model.getR() self.dist=sqrt(pow(self.x1-x2,2)+pow(self.y1-y2,2)) self.sptime=self.dist/(self.speed) self.hall=270-degrees(y2/x2) # self.model.setPos(self.model,self.spd,0,self.spd) self.Inter=LerpPosHprInterval(self.model,self.sptime,pos=self.target ,startPos=self.model.getPos(),startHpr=self.startR,hpr=self.startR)#(h1,p1,self.hall)) #Inter2=Func(self.model.lookAt(self.target),Wait(0.3)) self.heroPace = Sequence(self.Inter,name="heroPace") self.heroPace.start() def Collision(self): self.mpos3d=0 self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) base.cTrav = CollisionTraverser() self.collHandler = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) base.cTrav.addCollider(self.pickerNP, self.collHandler) def ObjectClick(self): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) base.cTrav.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if self.collHandler.getNumEntries() > 0: # This is so we get the closest object. self.collHandler.sortEntries() self.pickedObj = self.collHandler.getEntry(0).getIntoNodePath() self.pickedObj = self.pickedObj.findNetTag('Unit') if not self.pickedObj.isEmpty(): self.Attack(self.pickedObj.getPos()) #Handles the object def setKey1(self, key, value,value2): self.keyMap[key] = value self.Change=value2 def checkKeys(self): if (self.keyMap["left"]!=0): self.model.setH(self.model.getH() + self.dt*300) if (self.keyMap["right"]!=0): self.model.setH(self.model.getH() - self.dt*300) if (self.keyMap["forward"]!=0): self.model.setX(self.model, +(self.dt*25*SPEED)) def checkAnim(self): if self.Change: #(self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0): if self.isMoving is False: self.model.loop("run") self.isMoving = True else: if self.isMoving: self.model.stop() self.model.pose("walk",5) self.isMoving = False if self.Animate: pass def Attack(self,pos): self.atk.setWeil(self.model) self.atk.setTarg(self.dumm) self.atk.setDist(self.mini) if self.mini<=60: self.Animate=self.atk.ATT() else: messenger.send('mouse3') if self.mini<=60: self.atk.ATT() def setScrollSpeed(self): SCROLLSPEED=self.slider['value'] def UnSetupEvents(self): self.ignore("arrow_left") self.ignore("arrow_right") self.ignore("arrow_up") self.ignore("arrow_left-up") self.ignore("arrow_right-up") self.ignore("arrow_up-up") self.ignore("enter") self.ignore("mouse1") self.ignore("mouse3") taskMgr.remove("update") taskMgr.remove("second") taskMgr.remove("mouse") #--------------------------------------------------------------Return Functions------------------------------------------------------# def getDamage(self): return self.damage def getPos(self): return self.model.getPos() def getX(self): return self.model.getX() def getY(self): return self.model.getY() def getZ(self): return self.model.getZ() def getlvl(self): return self.lvl def getModel(self): return self.model def gainxp(self,unit): self.xp+=unit def gainGold(self,gain): self.gold+=gain def sendTime(self,min,sec): self.min=min self.sec=sec #----------------------------------------------------------------ITEM FUNCTIONS--------------------------------------------------------# def itemBuy(self,arg,cost): if self.gold>=0: if self.itemindex<=5: del self.items[self.itemindex] self.items.insert(self.itemindex,arg) self.gainGold(-cost) if self.items[self.itemindex]!=-1: if self.itemindex==0: self.itm0= aspect2d.attachNewNode("item0") DirectButton(text ="",parent=self.itm0,image='tome.tga',pos=(0+0.12*self.itemindex,0,-0.90),pad=(-0.1,-0.1),scale=(0.05,0,0.05),extraArgs=[arg,cost],command=self.itemSold)#,commandButtons=DGG.RMB) if self.itemindex==1: self.itm1= aspect2d.attachNewNode("item1") DirectButton(text ="",parent=self.itm1,image='tome.tga',pos=(0+0.12*self.itemindex,0,-0.90),pad=(-0.1,-0.1),scale=(0.05,0,0.05),extraArgs=[arg,cost],command=self.itemSold)#,commandButtons=DGG.RMB) if self.itemindex==2: self.itm2= aspect2d.attachNewNode("item2") DirectButton(text ="",parent=self.itm2,image='tome.tga',pos=(0+0.12*self.itemindex,0,-0.90),pad=(-0.1,-0.1),scale=(0.05,0,0.05),extraArgs=[arg,cost],command=self.itemSold)#,commandButtons=DGG.RMB) if self.itemindex==3: self.itm3= aspect2d.attachNewNode("item3") DirectButton(text ="",parent=self.itm3,image='tome.tga',pos=(0+0.12*self.itemindex,0,-0.90),pad=(-0.1,-0.1),scale=(0.05,0,0.05),extraArgs=[arg,cost],command=self.itemSold)#,commandButtons=DGG.RMB) if self.itemindex==4: self.itm4= aspect2d.attachNewNode("item4") DirectButton(text ="",parent=self.itm4,image='tome.tga',pos=(0+0.12*self.itemindex,0,-0.90),pad=(-0.1,-0.1),scale=(0.05,0,0.05),extraArgs=[arg,cost],command=self.itemSold)#,commandButtons=DGG.RMB) if self.itemindex==5: self.itm5= aspect2d.attachNewNode("item5") DirectButton(text ="",parent=self.itm5,image='tome.tga',pos=(0+0.12*self.itemindex,0,-0.90),pad=(-0.1,-0.1),scale=(0.05,0,0.05),extraArgs=[arg,cost],command=self.itemSold)#,commandButtons=DGG.RMB) self.itemindex+=1 else: Error("No Empty Slots") else: Error("No Gold") def itemSold(self,itemtosell,cost): self.ind=self.items.index(itemtosell) del self.items[self.ind] self.items.insert(self.ind,-1) self.gainGold(cost/2) if self.ind==0: self.itm0.detachNode() if self.ind==1: self.itm1.detachNode() if self.ind==2: self.itm2.detachNode() if self.ind==3: self.itm3.detachNode() if self.ind==4: self.itm4.detachNode() if self.ind==5: self.itm5.detachNode() self.itemindex-=1 def lvlup(self): self.lvl+=1 self.str=self.char['str'] +(self.strdt*self.lvl) self.str=self.char['str'] +(self.agidt*self.lvl) self.int=self.char['int'] +(self.intdt*self.lvl) self.hpgain=(self.strdt+self.Delta1)*19 self.mpgain=(self.intdt+self.Delta3)*13 self.maxhp=590+self.str*19 self.maxmp=290+self.int*13 #some error here self.heal(self.hpgain) self.replenish(self.mpgain) self.xp =0 #---------------------------------------------------------SKILL FUNCTIONS-------------------------------------# def SkillStatus(self): self.sp1=0 self.sp2=0 self.sp3=0 self.sp4=0 self.sp1dam=0 self.sp2dam=0 self.sp3dam=0 self.sp4dam=0 if self.sp1==1: self.range=400 self.sp1dam=130 self.raduis=100 self.sp2dam=30 self.sp3dam=90 self.pulses=6 def SkillNo(self,arg): if arg==0: if self.curmp>=100: self.accept("mouse1",Blink,extraArgs=[self]) self.skbtn1['image']='cancel.png' # self.skbtn1['command']=self.setOpen() else: Error("NO MANA") elif arg==1: StatUp(self) elif arg==2: StatDn(self) else: Ulti(self) def setOpen(self): self.open=False self.ignore("mouse1") self.skbtn1['image']=self.skillicons[0]+'.png' self.accept("mouse1",self.ObjectClick) #----------------------------------------TASK FUNCTIONS------------------------------------------------------# def Delay(self,task): self.Delta(-2,-2,-2) return task.done def Second(self,task): self.gainGold(self.goldrate) self.heal(self.healrate) self.replenish(self.mprate) return task.again def update(self,task): self.timemin.setText(str(self.min)) self.timesec.setText(str(self.sec)) self.str=self.char['str'] +(self.strdt*self.lvl)+self.Delta3 self.agi=self.char['agi'] + (self.agidt*self.lvl)+self.Delta4 self.int=self.char['int']+(self.intdt*self.lvl)+self.Delta5 self.hpgain=(self.strdt+self.Delta1)*19 self.mpgain=(self.intdt+self.Delta3)*13 self.maxhp=590+self.str*19 self.maxmp=290+self.int*13 #some error here # self.heal(self.hpgain) # self.replenish(self.mpgain) self.armor=self.char['armor'] +(self.agi/7)+self.Delta2 self.atkspeed=1.5/self.agi if self.type=='str': self.TYPESTR() if self.type=='agi': self.TYPEAGI() if self.type=='int': self.TYPEINT() self.healrate=0.03 *self.str self.mprate=0.02 *self.int self.GOLD.setText(str(self.gold)) self.hpbar['range']=int(self.maxhp) self.hpbar['value']=int(self.curhp) self.mpbar['range']=int(self.maxmp) self.mpbar['value']=int(self.curmp) self.lvlbar['range']=int(10*self.lvl) self.lvlbar['value']=int(self.xp) self.HP['text']="HP"+str(int(self.curhp))+"/"+str(int(self.maxhp)) self.MP['text']="MP"+str(int(self.curmp))+"/"+str(int(self.maxmp)) self.DAM['text']=str(int(self.mindamage))+'-'+str(int(self.maxdamage)) self.ARM['text']=str(int(self.armor)) self.STR['text']=str(int(self.str)) self.AGI['text']=str(int(self.agi)) self.INT['text']=str(int(self.int)) self.LVL['text']="LEVEL "+str(int(self.lvl)) if self.xp>=20*20: self.lvlup() if self.curhp<=0: taskMgr.add(self.Death,"death") self.x1,self.y1=self.model.getX(),self.model.getY() self.x2,self.y2=self.dumm.getX(),self.dumm.getY() self.mini=sqrt(pow(self.x1-self.x2,2)+pow(self.y1-self.y2,2)) Debug2(self,str(self.mini)) elapsed = globalClock.getDt() self.dt=elapsed self.setHPColor() self.checkAnim() self.checkKeys() # base.camera.lookAt(self.model) # self.floater.setPos(self.model.getPos()) # base.camera.lookAt(self.floater) return task.cont def Death(self,task): self.isDead=True Debug2(self,str(task.time)) if self.isDead==True: self.model.reparentTo(hidden) self.panel.detachNode() self.deathtime=(self.lvl+1)*3 self.isDead=False if int(task.time)==self.deathtime: self.model.setPos(self.StartPos) self.model.reparentTo(render) self.curhp=self.maxhp self.model.loop("walk") self.display() taskMgr.remove("death") # self.deathtxt.destroy() return task.cont def MousePos(self, task): #This Took me 1.5 Months to Learn if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.mpos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine(self.mpos3d, render.getRelativePoint(camera, nearPoint),render.getRelativePoint(camera, farPoint)): pass return task.again def destroy(self): self.panel.detachNode() self.t1.destroy() self.t2.destroy() self.model.remove() self.timesec.destroy() self.timemin.destroy() self.UnsetupEvents()
class MousePicker( gizmo_core.Object ): """ Class to represent a ray fired from the input camera lens using the mouse. """ 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 FireEvent( self, event ): # Send a message containing the node name and the event name, including # the collision entry as arguments if self.node is not None: messenger.send( '%s-%s' % ( self.node.getName(), event ), [self.collEntry] ) def UpdateTask( self, task ): # Traverse the hierarchy and find collisions self.collTrav.traverse( self.rootNp ) if self.collHandler.getNumEntries(): # If we have hit something, sort the hits so that the closest is first self.collHandler.sortEntries() collEntry = self.collHandler.getEntry( 0 ) node = collEntry.getIntoNode() # If this node is different to the last node, send a mouse leave # event to the last node, and a mouse enter to the new node if node != self.node: if self.node is not None: messenger.send( '%s-mouse-leave' % self.node.getName(), [self.collEntry] ) messenger.send( '%s-mouse-enter' % node.getName(), [collEntry] ) # Send a message containing the node name and the event over name, # including the collision entry as arguments messenger.send( '%s-mouse-over' % node.getName(), [collEntry] ) # Keep these values self.collEntry = collEntry self.node = node elif self.node is not None: # No collisions, clear the node and send a mouse leave to the last # node that stored messenger.send( '%s-mouse-leave' % self.node.getName(), [self.collEntry] ) self.node = None # Update the ray's position if base.mouseWatcherNode.hasMouse(): mp = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens( self.camera.node(), mp.getX(), mp.getY() ) return task.cont def StartSelection( self, clearSelection=True ): # Start the marquee self.marquee.Start() # Clear selection list if required if clearSelection: self.selection = [] def StopSelection( self ): # Stop the marquee self.marquee.Stop() nodes = [] for node in self.rootNp.findAllMatches( '**' ): if self.marquee.IsPoint3Inside( self.camera, self.rootNp, node.getPos() ): if self.pickTag is not None: if node.getTag( self.pickTag ): nodes.append( node ) else: nodes.append( node ) # Add any node which was under the mouse to the selection if self.collHandler.getNumEntries(): collEntry = self.collHandler.getEntry( 0 ) node = collEntry.getIntoNodePath().getParent() nodes.append( node ) # If the node was already in the selection then remove it, otherwise # add the node to the selection for node in nodes: if node in self.selection: self.selection.remove( node ) else: self.selection.append( node ) # Remove duplicated self.selection = list( set( self.selection ) )
class World(DirectObject.DirectObject): def __init__(self): self.creeps = None self.open = False self.sec = 0 self.min = 0 self.pindex = 1 # This is the Pause Index self.index = -1 # This is the hero Index self.rindex = False # This is the Repick Index self.hpicked = [] # This List Stores All The Heroes Picked and Removes Them for i in range(0, 110): self.hpicked.append(-1) # Gotta change and check this self.hindex = 0 # When a hero is picked this index saves it and stores it in the list self.RND = render.attachNewNode("rend") self.LightHandler = None self.Players() self.LoadTerrain() # Load the Map self.SetupCamera() self.SetupLight() self.SetupEvents() self.SetupTimer() self.chooseHero() self.SetupMap() self.SetupCreeps() self.SetupCollision() self.displayed = False self.keyMap = {"cam-left": 0, "cam-right": 0, "cam-up": 0, "cam-down": 0, "zoom-in": 0, "zoom-out": 0} self.chatindex = 0 self.chat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] self.text = ["text1", "text2", "text3", "text4", "text5" "text6" "text7" "text8" "text9", "text10", "text11"] self.task = None def Players(self): self.hero1 = None self.hero2 = None self.hero3 = None self.hero4 = None self.hero5 = None self.hero6 = None self.hero7 = None self.hero8 = None self.hero9 = None self.hero10 = None self.player1 = None self.player2 = None self.player3 = None self.player4 = None self.player5 = None self.player6 = None self.player7 = None self.player8 = None self.player9 = None self.player10 = None def LoadTerrain(self): self.terrain = loader.loadModel("models/environment") self.terrain.setTag("Map", "1") self.terrain.reparentTo(self.RND) self.itmpan1 = OnscreenImage(image=MYDIRIMG + "/3.png", scale=(0.3, 0, 0.09), pos=(0.61, 0, -0.915)) self.itmpan2 = OnscreenImage(image=MYDIRIMG + "/3.png", scale=(0.3, 0, 0.09), pos=(0.61, 0, -0.740)) self.t2 = OnscreenImage(image=MYDIRIMG + "/t2.png", scale=(0.25, 0, 0.06), pos=(1.160, 0, -0.71)) self.t1 = OnscreenImage(image=MYDIRIMG + "/t1.png", scale=(0.25, 0, 0.06), pos=(1.160, 0, -0.83)) self.end = OnscreenImage(image=MYDIRIMG + "/end.png", scale=(0.1, 0, 0.2), pos=(1.510, 0, -0.80)) self.back = OnscreenImage(image=MYDIRIMG + "/back.png", scale=(0.57, 0, 0.2), pos=(-0.26, 0, -0.80)) def SetupCollision(self): base.cTrav = CollisionTraverser() self.collHandler = CollisionHandlerQueue() self.pickerNode = CollisionNode("mouseRay") self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) base.cTrav.addCollider(self.pickerNP, self.collHandler) def ObjectClick(self): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) base.cTrav.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if self.collHandler.getNumEntries() > 0: # This is so we get the closest object. self.collHandler.sortEntries() self.pickedObj = self.collHandler.getEntry(0).getIntoNodePath() self.pickedObj1 = self.pickedObj.findNetTag("Unit") self.pickedObj2 = self.pickedObj.findNetTag("MyHero") self.pickedObj3 = self.pickedObj.findNetTag("Map") self.pickedObj4 = self.pickedObj.findNetTag("MyHero") if self.pickedObj1 == self.creeps.getModel(): if self.displayed is False: self.displayed = True self.creeps.display() else: if self.displayed is True: self.displayed = False self.creeps.displaynot() if self.hero != None: if self.pickedObj2 == self.hero1.getModel(): if self.displayed is False: self.displayed = True self.hero1.display() else: if self.displayed is True: self.displayed = False self.hero1.displaynot() def SetupCamera(self): base.camera.setPos(0, 0, 180) base.camera.setP(-30) base.camera.lookAt(0, 0, 0) def SetupTimer(self): self.btn = aspect2d.attachNewNode("btn") self.btn.setTransparency(1) self.timesec = OnscreenText(text="", pos=(1.3, -0.71), fg=(1, 1, 1, 1), mayChange=1, scale=0.05) self.timemin = OnscreenText(text="", pos=(1.1, -0.71), fg=(1, 1, 1, 1), mayChange=1, scale=0.05) self.pausebtn = DirectButton( text="Pause (%d)" % (self.pindex), parent=self.btn, text_fg=(0, 0.2, 0, 1), text_pos=(0.05, -0.15), text_scale=(0.48, 0.53), image=(MYDIRIMG + "btnof.png", MYDIRIMG + "btnon.png", MYDIRIMG + "btnon.png", None), frameColor=(0, 0, 0, 0), pos=(-1.0, 0, -0.81), image_scale=(1.0, 0, 0.7), scale=(0.15, 0, 0.10), command=self.Pause, ) self.infobtn = DirectButton( text="Info", parent=self.btn, text_fg=(0, 0.2, 0, 1), text_pos=(0.05, -0.15), text_scale=0.6, image=(MYDIRIMG + "btnof.png", MYDIRIMG + "btnon.png", MYDIRIMG + "btnon.png", None), frameColor=(0, 0, 0, 0), pos=(-1.0, 0, -0.68), image_scale=(1.0, 0, 0.7), scale=(0.15, 0, 0.10), command=self.Pause, ) taskMgr.doMethodLater(1, self.Timer, "tickTask") def SetupMap(self): self.minimap = minimap(None) def SetupLight(self): self.LightHandler = Lights(None) def SetupEvents(self): self.DEntry = DirectEntry( text="", pos=(-0.6, 0.0, -0.7), image=MYDIRIMG + "/tooltips9.png", frameColor=(0, 0, 0, 1), width=27, image_pos=(13.5, 0, 0.2), image_scale=(15, 0, 0.6), scale=0.05, initialText="", numLines=1, focus=1, command=self.Parser, ) self.DEntry.setTransparency(1) self.DEntry.detachNode() taskMgr.add(self.MoveCamera, "CameraControl") self.accept("enter", self.MsgBox) self.accept("wheel_up", self.setKey, ["zoom-in", 1]) self.accept("wheel_down", self.setKey, ["zoom-out", 1]) # self.accept("wheel_up-up",self.setKey, ["zoom-in",0]) # self.accept("wheel_down-up",self.setKey, ["zoom-out",0]) self.accept("a", self.setKey, ["cam-left", 1]) self.accept("d", self.setKey, ["cam-right", 1]) self.accept("w", self.setKey, ["cam-up", 1]) self.accept("s", self.setKey, ["cam-down", 1]) self.accept("+", self.setKey, ["zoom-in", 1]) self.accept("-", self.setKey, ["zoom-out", 1]) self.accept("a-up", self.setKey, ["cam-left", 0]) self.accept("d-up", self.setKey, ["cam-right", 0]) self.accept("w-up", self.setKey, ["cam-up", 0]) self.accept("s-up", self.setKey, ["cam-down", 0]) self.accept("+-up", self.setKey, ["zoom-in", 0]) self.accept("--up", self.setKey, ["zoom-out", 0]) self.accept("mouse1", self.ObjectClick) def UnSetupEvents(self): self.ignore("a") self.ignore("s") self.ignore("w") self.ignore("s") self.ignore("+") self.ignore("-") self.ignore("enter") self.ignore("wheel_up") self.ignore("wheel_down") taskMgr.remove("CameraControl") def setKey(self, key, value): self.keyMap[key] = value def MoveCamera(self, task): mpos = base.mouseWatcherNode.getMouse() elapsed = globalClock.getDt() self.dt = elapsed self.mx = mpos.getX() self.my = mpos.getY() if self.keyMap["cam-left"] != 0: base.camera.setX(base.camera, -(self.dt * 20)) if self.keyMap["cam-right"] != 0: base.camera.setX(base.camera, +(self.dt * 20)) if self.keyMap["zoom-in"] != 0: base.camera.setY(base.camera, -(self.dt * 20)) if self.keyMap["zoom-out"] != 0: base.camera.setY(base.camera, +(self.dt * 20)) if self.keyMap["cam-down"] != 0: base.camera.setZ(base.camera, -(self.dt * 20)) if self.keyMap["cam-up"] != 0: base.camera.setZ(base.camera, +(self.dt * 20)) if self.mx > 0.95: if base.camera.getX() < MAPLIMIT: base.camera.setX(base.camera, +(self.dt * SCROLLSPEED)) if self.mx < -0.95: if base.camera.getX() > -MAPLIMIT: base.camera.setX(base.camera, -(self.dt * SCROLLSPEED)) if self.my > 0.95: if base.camera.getY() < MAPLIMIT: base.camera.setZ(base.camera, +(self.dt * SCROLLSPEED)) if self.my < -0.95: if base.camera.getY() > -MAPLIMIT: base.camera.setZ(base.camera, -(self.dt * SCROLLSPEED)) return task.cont def chooseHero(self): if self.hero1 == None: self.BTNnode = aspect2d.attachNewNode("buttons") for i in range(0, 3): for j in range(0, 4): self.index += 1 if icons[self.index] == None: continue if self.hpicked[self.index] == self.index: continue self.worldHeroButton(-1.8 + j * 0.1, -i * 0.1, self.index) def worldHeroButton(self, x, y, arg): DirectButton( text="", parent=self.BTNnode, text_font=font, image=MYDIRICONS + icons[arg] + ".tga", frameColor=(0, 0, 0, 0), pad=(-0.1, -0.1), image_scale=(IconSx + 0.2, 0, IconSy + 0.2), pos=(posx - 0.5 + x, 0, posy + y), scale=(0.20, 0, 0.20), command=self.SetupHero, extraArgs=[arg], ) def SetupCreeps(self): self.creeps = Unit1() def SetupHero(self, no): self.hpicked.insert(self.hindex, no) self.hindex += 1 self.BTNnode.detachNode() self.hero1 = Hero(no) self.hero1.getModel().setTag("Hero1", "1") def Timer(self, task): self.task = task self.sec += 1 if self.hero1 != None: self.hero1.sendTime(self.min, self.sec) if self.sec >= 60: self.sec = 0 self.min += 1 self.timemin.setText(str(self.min)) self.timesec.setText(str(self.sec)) return task.again def MsgBox(self): if self.open == False: self.DEntry.reparentTo(aspect2d) self.open = True else: self.DEntry.detachNode() self.open = False def Parser(self, text): Text = text # Within 120 seconds on the game if self.hero1 == None: self.BTNnode.detachNode() if Text == "-random": self.hero1 = Hero(random.randint(0, 96)) elif Text == "-random int": self.hero1 = Hero(random.randint(66, 96)) elif Text == "-random str": self.hero1 = Hero(random.randint(0, 36)) elif Text == "-random agi": self.hero1 == Hero(random.randint(36, 66)) if Text == "-repick": if self.rindex == False: if self.hero1 != None: self.hero1.destroy() self.hero1 = None self.index = -1 self.chooseHero() self.rindex = True else: Error("Cannot Repick") elif Text == "-": pass else: pass # self.Chat(Text,self.task) # taskMgr.add(self.Chat,"nn",extraArgs=[Text]) # this sends text to allies def ChatTimer(self, task, chat, i): chat.destroy() self.chat.insert(i, 0) self.chatindex -= 1 return task.done def Chat(self, text, task): for i in range(1, 15): if self.chat[i] == 0: self.text[i] = OnscreenText(text=text, pos=(-1.3, -0.4), fg=(0, 0, 0, 1), scale=0.07) self.chat.insert(self.chatindex, 1) taskMgr.doMethodLater(5, self.ChatTimer, "chat", [task, self.text[i], i]) self.chatindex += 1 break else: self.text[i].setY(-(0.1 * i) + 0.4) return task.done def Pause(self): if self.pindex != 0: self.pindex -= 1 time.sleep(2) self.pausebtn["text"] = "Pause (%d)" % (self.pindex) else: Error("Pause Limits Used") def destroy(self): if self.hero1 != None: self.hero1.destroy() self.minimap.destroy() self.btn.detachNode() self.BTNnode.detachNode() taskMgr.remove("timer") self.terrain.detachNode() del self.LightHandler del self.creeps self.UnSetupEvents() def MousePos(self, task): # This Took me 1.5 Months to Learn if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pos3d = Point3() self.nearPoint = Point3() self.farPoint = Point3() base.camLens.extrude(mpos, self.nearPoint, self.farPoint) if self.plane.intersectsLine( self.pos3d, render.getRelativePoint(camera, self.nearPoint), render.getRelativePoint(camera, self.farPoint) ): pass return task.again
class CogdoFlyingCameraManager: def __init__(self, cam, parent, player, level): self._toon = player.toon self._camera = cam self._parent = parent self._player = player self._level = level self._enabled = False def enable(self): if self._enabled: return self._toon.detachCamera() self._prevToonY = 0.0 levelBounds = self._level.getBounds() l = Globals.Camera.LevelBoundsFactor self._bounds = ((levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]), (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]), (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2])) self._lookAtZ = self._toon.getHeight( ) + Globals.Camera.LookAtToonHeightOffset self._camParent = NodePath('CamParent') self._camParent.reparentTo(self._parent) self._camParent.setPos(self._toon, 0, 0, 0) self._camParent.setHpr(180, Globals.Camera.Angle, 0) self._camera.reparentTo(self._camParent) self._camera.setPos(0, Globals.Camera.Distance, 0) self._camera.lookAt(self._toon, 0, 0, self._lookAtZ) self._cameraLookAtNP = NodePath('CameraLookAt') self._cameraLookAtNP.reparentTo(self._camera.getParent()) self._cameraLookAtNP.setPosHpr(self._camera.getPos(), self._camera.getHpr()) self._levelBounds = self._level.getBounds() self._enabled = True self._frozen = False self._initCollisions() 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 _destroyCollisions(self): self._collTrav.removeCollider(self._camCollNP) self._camCollNP.removeNode() del self._camCollNP del self._camCollRay del self._collHandler del self._collOffset del self._betweenCamAndToon self._transNP.removeNode() del self._transNP def freeze(self): self._frozen = True def unfreeze(self): self._frozen = False def disable(self): if not self._enabled: return self._destroyCollisions() self._camera.wrtReparentTo(render) self._cameraLookAtNP.removeNode() del self._cameraLookAtNP self._camParent.removeNode() del self._camParent del self._prevToonY del self._lookAtZ del self._bounds del self._frozen self._enabled = False def update(self, dt=0.0): self._updateCam(dt) self._updateCollisions() def _updateCam(self, dt): toonPos = self._toon.getPos() camPos = self._camParent.getPos() x = camPos[0] z = camPos[2] toonWorldX = self._toon.getX(render) maxX = Globals.Camera.MaxSpinX toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX) spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / ( maxX * maxX) newH = 180.0 + spinAngle self._camParent.setH(newH) spinAngle = spinAngle * (pi / 180.0) distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle) distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle) d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0]) if abs(d) > Globals.Camera.LeewayX: if d > Globals.Camera.LeewayX: x = toonPos[0] + Globals.Camera.LeewayX else: x = toonPos[0] - Globals.Camera.LeewayX x = self._toon.getX(render) + distToRightOfToon boundToonZ = min(toonPos[2], self._bounds[2][1]) d = z - boundToonZ if d > Globals.Camera.MinLeewayZ: if self._player.velocity[2] >= 0 and toonPos[ 1] != self._prevToonY or self._player.velocity[2] > 0: z = boundToonZ + d * INVERSE_E**(dt * Globals.Camera.CatchUpRateZ) elif d > Globals.Camera.MaxLeewayZ: z = boundToonZ + Globals.Camera.MaxLeewayZ elif d < -Globals.Camera.MinLeewayZ: z = boundToonZ - Globals.Camera.MinLeewayZ if self._frozen: y = camPos[1] else: y = self._toon.getY(render) - distBehindToon self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z)) if toonPos[2] < self._bounds[2][1]: h = self._cameraLookAtNP.getH() if d >= Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ) elif d <= -Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._camParent, 0, 0, self._lookAtZ) self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0) self._camera.setHpr( smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr())) self._prevToonY = toonPos[1] def _updateCollisions(self): pos = self._toon.getPos(self._camera) + self._collOffset self._camCollRay.setOrigin(pos) direction = -Vec3(pos) direction.normalize() self._camCollRay.setDirection(direction) self._collTrav.traverse(render) nodesInBetween = {} if self._collHandler.getNumEntries() > 0: self._collHandler.sortEntries() for entry in self._collHandler.getEntries(): name = entry.getIntoNode().getName() if name.find('col_') >= 0: np = entry.getIntoNodePath().getParent() if not np in nodesInBetween: nodesInBetween[np] = np.getParent() for np in nodesInBetween.keys(): if np in self._betweenCamAndToon: del self._betweenCamAndToon[np] else: np.setTransparency(True) np.wrtReparentTo(self._transNP) if np.getName().find('lightFixture') >= 0: if not np.find('**/*floor_mesh').isEmpty(): np.find('**/*floor_mesh').hide() elif np.getName().find('platform') >= 0: if not np.find('**/*Floor').isEmpty(): np.find('**/*Floor').hide() for np, parent in self._betweenCamAndToon.items(): np.wrtReparentTo(parent) np.setTransparency(False) if np.getName().find('lightFixture') >= 0: if not np.find('**/*floor_mesh').isEmpty(): np.find('**/*floor_mesh').show() elif np.getName().find('platform') >= 0: if not np.find('**/*Floor').isEmpty(): np.find('**/*Floor').show() self._betweenCamAndToon = nodesInBetween
class MouseEvents(DirectObject.DirectObject): def __init__(self): # from gameEngine import moveUnitsNext, moveUnitsPrev # self.accept('arrow_down', moveUnitsNext ) # self.accept('arrow_up', moveUnitsPrev ) self.accept('arrow_up-repeat', self.moveCameraUp) self.accept('arrow_up', self.moveCameraUp) self.accept('arrow_down-repeat', self.moveCameraDown) self.accept('arrow_down', self.moveCameraDown) self.accept('arrow_left-repeat', self.moveCameraLeft) self.accept('arrow_left', self.moveCameraLeft) self.accept('arrow_right-repeat', self.moveCameraRight) self.accept('arrow_right', self.moveCameraRight) # Initialize the traverser. self.myTraverser = CollisionTraverser() # Initialize the handler. self.myHandler = CollisionHandlerQueue() self.accept("escape", sys.exit) #Exit the program when escape is pressed base.disableMouse() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.myTraverser.addCollider(self.pickerNP, self.myHandler) ''' the player has to double click a star or planet in order to activate them ''' self.accept("mouse1", self.handleLeftMouseClick) self.accept("mouse3", self.handleRightMouseClick) self.accept("mouse1-up", self.handleMouseDrag) self.mouseFirstPos = None cm = CardMaker('quad') # cm.setFrameFullscreenQuad() self.drag_rect_path = base.render2d.attachNewNode(cm.generate()) self.drag_rect_path.setTransparency(TransparencyAttrib.MAlpha) self.drag_rect_path.setColor(Vec4(1,1,1,0.3)) self.drag_rect_path.hide() # self.drag_rect_path = LineNodePath(base.render2d, thickness = 8.0) def selectionRectangle(self, task): if base.mouseWatcherNode.hasMouse():# and self.mouseFirstPos != None: mpos = base.mouseWatcherNode.getMouse() self.drag_rect_path.show() self.drag_rect_path.setSx(mpos.getX()-self.mouseFirstPos.getX()+0.0001) self.drag_rect_path.setSz(mpos.getY()-self.mouseFirstPos.getY()+0.0001) self.drag_rect_path.setPos(self.mouseFirstPos.getX(), 0, self.mouseFirstPos.getY()) # self.drag_rect_path.drawLines([((self.mouseFirstPos.getX(),self.mouseFirstPos.getY()),(mpos.getX(), mpos.getY()))]) # self.drag_rect_path.create() # base.win.makeDisplayRegion(self.mouseFirstPos.getX(), self.mouseFirstPos.getY(), mpos.getX(), mpos.getY()) return task.cont def handleMouseDrag(self): if base.mouseWatcherNode.hasMouse(): if self.mouseFirstPos != None: mpos = base.mouseWatcherNode.getMouse() lvec = Vec2(self.mouseFirstPos) - Vec2(mpos) if lvec.length() > 0.01: scaled_pos = Point2(self.mouseFirstPos) scaled_pos.setX(scaled_pos.getX()*base.getAspectRatio()) scaled_mpos = Point2(mpos) scaled_mpos.setX(scaled_mpos.getX()*base.getAspectRatio()) for unit in self.player.selected_units: unit.deselect() del self.player.selected_units[:] for unit in self.player.units: if unit.is3dpointIn2dRegion(scaled_pos, scaled_mpos): unit.select() self.mouseFirstPos = None self.drag_rect_path.hide() taskMgr.remove(self.rect_task) def setPlayer(self, player): self.player = player def setCamera(self, camera): self.camera = camera def moveCameraUp(self): self.camera.camera_direction = "moveUp" def moveCameraDown(self): self.camera.camera_direction = "moveDown" def moveCameraLeft(self): self.camera.camera_direction = "moveLeft" def moveCameraRight(self): self.camera.camera_direction = "moveRight" def handleLeftMouseClick(self): if base.mouseWatcherNode.hasMouse(): #get the mouse position mpos = base.mouseWatcherNode.getMouse() self.savemousePos() # This makes the ray's origin the camera and makes the ray point # to the screen coordinates of the mouse. self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.myTraverser.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if self.myHandler.getNumEntries() > 0: # This is so we get the closest object. self.myHandler.sortEntries() pickedObj = self.myHandler.getEntry(0).getIntoNodePath() if pickedObj.hasTag('star'): self.selected(pickedObj, 'star', 'pyStar', 'leftClick') elif pickedObj.hasTag('planet'): self.selected(pickedObj, 'planet', 'pyPlanet', 'leftClick') elif pickedObj.hasTag('unit'): self.selected(pickedObj, 'unit', 'pyUnit', 'leftClick') elif pickedObj.hasTag('testUnit'): self.selected(pickedObj, 'testUnit', 'pyTestUnit', 'leftClick') self.rect_task = taskMgr.add(self.selectionRectangle, 'drag') def savemousePos(self): self.mouseFirstPos = Point2(base.mouseWatcherNode.getMouse()) # self.mouseFirstPos.setX(self.mouseFirstPos.getX()*1.33) def handleRightMouseClick(self): if base.mouseWatcherNode.hasMouse(): #get the mouse position mpos = base.mouseWatcherNode.getMouse() # This makes the ray's origin the camera and makes the ray point # to the screen coordinates of the mouse. self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.myTraverser.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if self.myHandler.getNumEntries() > 0: # This is so we get the closest object. self.myHandler.sortEntries() pickedObj = self.myHandler.getEntry(0).getIntoNodePath() #if pickedObj.hasTag('star'): # self.selected(pickedObj, 'star', 'pyStar') if pickedObj.hasTag('planet'): self.selected(pickedObj, 'planet', 'pyPlanet', 'rightClick') #elif pickedObj.hasTag('unit'): # self.selected(pickedObj, 'unit', 'pyUnit') def selected(self, pickedObj, tag, python_tag, click): # print 'Player has selected '+ tag + ' ' + pickedObj.getTag(tag) model_path = pickedObj.getParent() #model_path.notify("starSelected") model = model_path.getPythonTag(python_tag) if(click == 'rightClick'): model.selectRight(self.player) elif(click == 'leftClick' and tag == 'unit'): if(self.player == model.player): for unit in self.player.selected_units: unit.deselect() del self.player.selected_units[:] model.select() else: model.select(self.player)
class MousePicker( p3d.SingleTask ): """ Class to represent a ray fired from the input camera lens using the mouse. """ 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] ) def OnUpdate( self, task ): # Update the ray's position if self.mouseWatcherNode.hasMouse(): mp = self.mouseWatcherNode.getMouse() self.pickerRay.setFromLens( self.camera.node(), mp.getX(), mp.getY() ) # Traverse the hierarchy and find collisions self.collTrav.traverse( self.rootNp ) if self.collHandler.getNumEntries(): # If we have hit something, sort the hits so that the closest is first self.collHandler.sortEntries() collEntry = self.collHandler.getEntry( 0 ) node = collEntry.getIntoNode() # If this node is different to the last node, send a mouse leave # event to the last node, and a mouse enter to the new node if node != self.node: if self.node is not None: messenger.send( '%s-mouse-leave' % self.node.getName(), [self.collEntry] ) messenger.send( '%s-mouse-enter' % node.getName(), [collEntry] ) # Send a message containing the node name and the event over name, # including the collision entry as arguments messenger.send( '%s-mouse-over' % node.getName(), [collEntry] ) # Keep these values self.collEntry = collEntry self.node = node elif self.node is not None: # No collisions, clear the node and send a mouse leave to the last # node that stored messenger.send( '%s-mouse-leave' % self.node.getName(), [self.collEntry] ) self.node = None def FireEvent( self, event ): """ Send a message containing the node name and the event name, including the collision entry as arguments. """ if self.node is not None: messenger.send( '%s-%s' % ( self.node.getName(), event ), [self.collEntry] ) def GetFirstNodePath( self ): """ Return the first node in the collision queue if there is one, None otherwise. """ if self.collHandler.getNumEntries(): collEntry = self.collHandler.getEntry( 0 ) return collEntry.getIntoNodePath() return None
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 CogdoFlyingCameraManager: def __init__(self, cam, parent, player, level): self._toon = player.toon self._camera = cam self._parent = parent self._player = player self._level = level self._enabled = False def enable(self): if self._enabled: return self._toon.detachCamera() self._prevToonY = 0.0 levelBounds = self._level.getBounds() l = Globals.Camera.LevelBoundsFactor self._bounds = ( (levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]), (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]), (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2]), ) self._lookAtZ = self._toon.getHeight() + Globals.Camera.LookAtToonHeightOffset self._camParent = NodePath("CamParent") self._camParent.reparentTo(self._parent) self._camParent.setPos(self._toon, 0, 0, 0) self._camParent.setHpr(180, Globals.Camera.Angle, 0) self._camera.reparentTo(self._camParent) self._camera.setPos(0, Globals.Camera.Distance, 0) self._camera.lookAt(self._toon, 0, 0, self._lookAtZ) self._cameraLookAtNP = NodePath("CameraLookAt") self._cameraLookAtNP.reparentTo(self._camera.getParent()) self._cameraLookAtNP.setPosHpr(self._camera.getPos(), self._camera.getHpr()) self._levelBounds = self._level.getBounds() self._enabled = True self._frozen = False self._initCollisions() 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 _destroyCollisions(self): self._collTrav.removeCollider(self._camCollNP) self._camCollNP.removeNode() del self._camCollNP del self._camCollRay del self._collHandler del self._collOffset del self._betweenCamAndToon self._transNP.removeNode() del self._transNP def freeze(self): self._frozen = True def unfreeze(self): self._frozen = False def disable(self): if not self._enabled: return self._destroyCollisions() self._camera.wrtReparentTo(render) self._cameraLookAtNP.removeNode() del self._cameraLookAtNP self._camParent.removeNode() del self._camParent del self._prevToonY del self._lookAtZ del self._bounds del self._frozen self._enabled = False def update(self, dt=0.0): self._updateCam(dt) self._updateCollisions() def _updateCam(self, dt): toonPos = self._toon.getPos() camPos = self._camParent.getPos() x = camPos[0] z = camPos[2] toonWorldX = self._toon.getX(render) maxX = Globals.Camera.MaxSpinX toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX) spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / (maxX * maxX) newH = 180.0 + spinAngle self._camParent.setH(newH) spinAngle = spinAngle * (pi / 180.0) distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle) distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle) d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0]) if abs(d) > Globals.Camera.LeewayX: if d > Globals.Camera.LeewayX: x = toonPos[0] + Globals.Camera.LeewayX else: x = toonPos[0] - Globals.Camera.LeewayX x = self._toon.getX(render) + distToRightOfToon boundToonZ = min(toonPos[2], self._bounds[2][1]) d = z - boundToonZ if d > Globals.Camera.MinLeewayZ: if self._player.velocity[2] >= 0 and toonPos[1] != self._prevToonY or self._player.velocity[2] > 0: z = boundToonZ + d * INVERSE_E ** (dt * Globals.Camera.CatchUpRateZ) elif d > Globals.Camera.MaxLeewayZ: z = boundToonZ + Globals.Camera.MaxLeewayZ elif d < -Globals.Camera.MinLeewayZ: z = boundToonZ - Globals.Camera.MinLeewayZ if self._frozen: y = camPos[1] else: y = self._toon.getY(render) - distBehindToon self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z)) if toonPos[2] < self._bounds[2][1]: h = self._cameraLookAtNP.getH() if d >= Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ) elif d <= -Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._camParent, 0, 0, self._lookAtZ) self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0) self._camera.setHpr(smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr())) self._prevToonY = toonPos[1] def _updateCollisions(self): pos = self._toon.getPos(self._camera) + self._collOffset self._camCollRay.setOrigin(pos) direction = -Vec3(pos) direction.normalize() self._camCollRay.setDirection(direction) self._collTrav.traverse(render) nodesInBetween = {} if self._collHandler.getNumEntries() > 0: self._collHandler.sortEntries() for entry in self._collHandler.getEntries(): name = entry.getIntoNode().getName() if name.find("col_") >= 0: np = entry.getIntoNodePath().getParent() if not nodesInBetween.has_key(np): nodesInBetween[np] = np.getParent() for np in nodesInBetween.keys(): if self._betweenCamAndToon.has_key(np): del self._betweenCamAndToon[np] else: np.setTransparency(True) np.wrtReparentTo(self._transNP) if np.getName().find("lightFixture") >= 0: if not np.find("**/*floor_mesh").isEmpty(): np.find("**/*floor_mesh").hide() elif np.getName().find("platform") >= 0: if not np.find("**/*Floor").isEmpty(): np.find("**/*Floor").hide() for np, parent in self._betweenCamAndToon.items(): np.wrtReparentTo(parent) np.setTransparency(False) if np.getName().find("lightFixture") >= 0: if not np.find("**/*floor_mesh").isEmpty(): np.find("**/*floor_mesh").show() elif np.getName().find("platform") >= 0: if not np.find("**/*Floor").isEmpty(): np.find("**/*Floor").show() self._betweenCamAndToon = nodesInBetween
class Mouse(DirectObject): def __init__(self, app): 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 self.accept('mouse1', self.mouse1) self.accept('mouse1-up', self.mouse1_up) self.accept('mouse2', self.rotateCamera) self.accept('mouse2-up', self.stopCamera) self.accept('wheel_up', self.zoomIn) self.accept('wheel_down', self.zoomOut) def init_collide(self): from pandac.PandaModules import CollisionTraverser, CollisionNode from pandac.PandaModules import CollisionHandlerQueue, CollisionRay 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) 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 def mouse_task(self, task): action = task.cont 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 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] 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() 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(0, 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() lens.setFilmSize(size / 1.2) def zoomOut(self): lens = base.cam.node().getLens() size = lens.getFilmSize() lens.setFilmSize(size * 1.2)
class MousePicker(p3d.SingleTask): """ Class to represent a ray fired from the input camera lens using the mouse. """ 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]) def OnUpdate(self, task, x=None, y=None): # Update the ray's position if self.mouseWatcherNode.hasMouse(): mp = self.mouseWatcherNode.getMouse() x, y = mp.getX(), mp.getY() if x is None or y is None: return self.pickerRay.setFromLens(self.camera.node(), x, y) # Traverse the hierarchy and find collisions self.collTrav.traverse(self.rootNp) if self.collHandler.getNumEntries(): # If we have hit something, sort the hits so that the closest is first self.collHandler.sortEntries() collEntry = self.collHandler.getEntry(0) node = collEntry.getIntoNode() # If this node is different to the last node, send a mouse leave # event to the last node, and a mouse enter to the new node if node != self.node: if self.node is not None: messenger.send('%s-mouse-leave' % self.node.getName(), [self.collEntry]) messenger.send('%s-mouse-enter' % node.getName(), [collEntry]) # Send a message containing the node name and the event over name, # including the collision entry as arguments messenger.send('%s-mouse-over' % node.getName(), [collEntry]) # Keep these values self.collEntry = collEntry self.node = node elif self.node is not None: # No collisions, clear the node and send a mouse leave to the last # node that stored messenger.send('%s-mouse-leave' % self.node.getName(), [self.collEntry]) self.node = None def FireEvent(self, event): """ Send a message containing the node name and the event name, including the collision entry as arguments. """ if self.node is not None: messenger.send('%s-%s' % (self.node.getName(), event), [self.collEntry]) def GetFirstNodePath(self): """ Return the first node in the collision queue if there is one, None otherwise. """ if self.collHandler.getNumEntries(): collEntry = self.collHandler.getEntry(0) return collEntry.getIntoNodePath() return None
class Mode(object): """This is the base Mode class""" def __init__(self, game): self.name = "MODE" self.guiMediaPath = '../Packages/anw/gui/media/' self.alive = 1 self.enableMouseCamControl = 1 self.enableScrollWheelZoom = 1 self.canSelectFlags = {} self.messagePositions = [] self.selectTypes = [] self.gui = [] self.sims = [] self.game = game self.depth = 20.0 self.zoomCameraDepth = 10.0 self.zoomCameraOutDepth = -10.0 self.zoomSpeed = 5 self.panSpeed = 1.0 self.runningTasks = [] if globals.serverMode == 0: self.setMyBackground() camera.setHpr(0,0,0) self.mainmenu = None self.scrollSpeed = 0.1 if globals.serverMode == 0: self.setMousePicker() self.setCameraPosition() self.selector = None self.selector2 = None self.log = logging.getLogger('mode') self.entryFocusList = ('anw.gui.mainmenubuttons','anw.gui.industryvalue', 'anw.gui.cityindustry','anw.gui.weapondirection', 'anw.gui.scrollvalue','anw.gui.shipdesignvalue', 'anw.gui.systemmenu','anw.gui.tradevalue', 'anw.gui.designmenu','anw.gui.shipyardmenu', 'anw.gui.mimenu', 'anw.gui.textentry', 'anw.gui.marketsystemsellvalue', 'anw.gui.sendcreditsvalue') def __getstate__(self): odict = self.__dict__.copy() # copy the dict since we change it del odict['log'] # remove stuff not to be pickled return odict def __setstate__(self,dict): log=logging.getLogger('mode') self.__dict__.update(dict) self.log=log def setMousePicker(self): self.picker = CollisionTraverser() self.pq = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.picker.addCollider(self.pickerNP, self.pq) self.selectable = render.attachNewNode("selectable") def setCameraPosition(self): self.cameraPos = (camera.getX(), camera.getY(), camera.getZ()) self.cameraMoving = 0 def setCanSelectFlag(self, key): """Set the Flag""" self.clearAllCanSelectFlags() self.canSelectFlags[key] = 1 def clearAllCanSelectFlags(self): """Clear any selection flags""" for key in self.canSelectFlags.keys(): self.canSelectFlags[key] = 0 def isAnyFlagSelected(self): """Return 1 if any flags are selected""" for key in self.canSelectFlags.keys(): if self.canSelectFlags[key] == 1: return 1 return 0 def validateSelection(self): """Can something be selected right now""" if self.cameraMoving == 0: return 1 else: return 0 def removeMyGui(self, myGuiName): """Remove gui""" myGui = getattr(self, myGuiName) if myGui in self.gui: self.gui.remove(myGui) if myGui != None: myGui.destroy() setattr(self, myGuiName, None) def createMainMenu(self, key): self.mainmenu = mainmenubuttons.MainMenuButtons(self.guiMediaPath) self.mainmenu.setMyGame(self.game) self.mainmenu.setMyMode(self) self.mainmenu.enableLastButton(key) self.mainmenu.checkDisableButton(key) self.mainmenu.writeGameInfo() self.mainmenu.acceptSpaceBarKey() self.gui.append(self.mainmenu) def removeMainMenu(self): if self.mainmenu != None: self.mainmenu.destroyMe() self.mainmenu = None def centerCameraOnSim(self, sim): """Center the camera on the sim position""" self.game.app.disableMouseCamControl() camera.setPos(sim.getX(), camera.getY(), sim.getZ()) camera.setHpr(0,0,0) if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() def drawBox(self, x, y, width, height, color='guiblue1', lineWidth=0.15, glow=1): """Draw a box""" #LEFT myLine = line.Line(self.guiMediaPath,(x,y),(x,y+height), 'square_grey', lineWidth, glow) myLine.sim.setColor(globals.colors[color]) self.gui.append(myLine) #TOP myLine = line.Line(self.guiMediaPath,(x,y+height),(x+width,y+height), 'square_grey', lineWidth, glow) myLine.sim.setColor(globals.colors[color]) self.gui.append(myLine) #RIGHT myLine = line.Line(self.guiMediaPath,(x+width,y+height),(x+width,y), 'square_grey', lineWidth, glow) myLine.sim.setColor(globals.colors[color]) self.gui.append(myLine) #BOTTOM myLine = line.Line(self.guiMediaPath,(x+width,y),(x,y), 'square_grey', lineWidth, glow) myLine.sim.setColor(globals.colors[color]) self.gui.append(myLine) def stopCameraTasks(self): taskMgr.remove('zoomInCameraTask') taskMgr.remove('zoomOutCameraTask') self.cameraMoving = 0 self.game.app.enableMouseCamControl() self.enableMouseCamControl=1 def resetCamera(self): self.game.app.disableMouseCamControl() camera.setPos(self.cameraPos[0], self.zoomCameraOutDepth, self.cameraPos[2]) # I don't really understand why this doesn't reset the view when having a planet selected and hitting spacebar? camera.setHpr(0,0,0) if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() def zoomInCamera(self): if camera.getY() <= self.zoomCameraDepth: self.game.app.disableMouseCamControl() taskMgr.add(self.zoomInCameraTask, 'zoomInCameraTask', extraArgs=[self.zoomCameraDepth]) self.runningTasks.append('zoomInCameraTask') def zoomInCameraAmount(self, amount): """Zoom in Camera a certain amount specified""" depth = camera.getY()+amount self.game.app.disableMouseCamControl() taskMgr.add(self.zoomInCameraTask, 'zoomInCameraTask', extraArgs=[depth]) self.runningTasks.append('zoomInCameraTask') def zoomInCameraTask(self, depth): """Zoom in the camera until its at depth""" y = camera.getY() if y + 0.1 >= depth: # or y >= 8.0: # TODO: tacking this on will mess with the design screen but prevents you from zooming in too close everywhere else. self.cameraMoving = 0 if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() camera.setY(y) return Task.done else: camera.setY(y+self.getZoomSpeed(y, depth)) self.cameraMoving = 1 return Task.cont def getZoomSpeed(self, y, depth): """Make Camera zoom in faster if camera is further away""" diff = depth-y return diff/5.0 def zoomOutCamera(self): if camera.getY() >= self.zoomCameraOutDepth: self.game.app.disableMouseCamControl() taskMgr.add(self.zoomOutCameraTask, 'zoomOutCameraTask', extraArgs=[self.zoomCameraOutDepth]) self.runningTasks.append('zoomOutCameraTask') def zoomOutCameraAmount(self, amount): """Zoom out Camera a certain amount sepecified""" depth = camera.getY()-amount self.game.app.disableMouseCamControl() taskMgr.add(self.zoomOutCameraTask, 'zoomOutCameraTask', extraArgs=[depth]) self.runningTasks.append('zoomOutCameraTask') def zoomOutCameraTask(self, depth): """Zoom out the camera until its at 0 Depth""" y = camera.getY() if y - 0.1 <= depth: self.cameraMoving = 0 if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() camera.setY(y) return Task.done else: camera.setY(y+self.getZoomSpeed(y, depth)) self.cameraMoving = 1 return Task.cont def panCameraLeft(self, amount): """Pan Camera""" pos = camera.getX()-amount self.game.app.disableMouseCamControl() taskMgr.add(self.panCameraLeftTask, 'panCameraLeftTask', extraArgs=[pos]) self.runningTasks.append('panCameraLeftTask') def panCameraLeftTask(self, pos): """pan the camera to new position""" x = camera.getX() if x <= pos: self.cameraMoving = 0 if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() return Task.done else: camera.setX(x-self.panSpeed) self.cameraMoving = 1 return Task.cont def panCameraRight(self, amount): """Pan Camera""" pos = camera.getX()+amount self.game.app.disableMouseCamControl() taskMgr.add(self.panCameraRightTask, 'panCameraRightTask', extraArgs=[pos]) self.runningTasks.append('panCameraRightTask') def panCameraRightTask(self, pos): """pan the camera to new position""" x = camera.getX() if x >= pos: self.cameraMoving = 0 if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() return Task.done else: camera.setX(x+self.panSpeed) self.cameraMoving = 1 return Task.cont def panCameraUp(self, amount): """Pan Camera""" pos = camera.getZ()+amount self.game.app.disableMouseCamControl() taskMgr.add(self.panCameraUpTask, 'panCameraUpTask', extraArgs=[pos]) self.runningTasks.append('panCameraUpTask') def panCameraUpTask(self, pos): """pan the camera to new position""" z = camera.getZ() if z >= pos: self.cameraMoving = 0 if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() return Task.done else: camera.setZ(z+self.panSpeed) self.cameraMoving = 1 return Task.cont def panCameraDown(self, amount): """Pan Camera""" pos = camera.getZ()-amount self.game.app.disableMouseCamControl() taskMgr.add(self.panCameraDownTask, 'panCameraDownTask', extraArgs=[pos]) self.runningTasks.append('panCameraDownTask') def panCameraDownTask(self, pos): """pan the camera to new position""" z = camera.getZ() if z <= pos: self.cameraMoving = 0 if self.enableMouseCamControl == 1: self.game.app.enableMouseCamControl() return Task.done else: camera.setZ(z-self.panSpeed) self.cameraMoving = 1 return Task.cont def createSelector(self,type='select',speed=2.0): """Create selector for indication of selected objects""" self.selector = self.loadObject(type, scale=2, parent=render, transparency=True, pos=Point2(0,0), glow=1) self.selector.hide() ival = self.selector.hprInterval((speed), Vec3(0, 0, 360)) ival.loop() def createSelector2(self,type='select',speed=2.0): """Create selector2 for indication of secondary selected objects""" self.selector2 = self.loadObject(type, scale=2, parent=render, transparency=True, pos=Point2(0,0), glow=1) self.selector2.hide() ival = self.selector2.hprInterval((speed), Vec3(0, 0, 360)) ival.loop() def playSound(self, soundName): """Play a Sound based on soundName given, call app""" if globals.serverMode == 0: self.game.app.playSound(soundName) def askForHelp(self): """Ask the Server to analyse Player and provide help""" try: serverResult = self.game.server.askForHelp(self.game.authKey) if type(serverResult) == types.ListType: (message, self.game.myEmpire['help']) = serverResult self.modeMsgBox(message) else: self.modeMsgBox(serverResult) except: self.modeMsgBox('askForHelp->Connection to Server Lost') def assignSelector(self, myObj, scale): """create the Selector and assign to myObj at scale""" if self.selector == None: self.createSelector() self.selector.show() self.selector.setPos(myObj.getX(), myObj.getY(), myObj.getZ()) self.selector.setScale(scale) def assignSelector2(self, myObj, scale): """create the Selector2 and assign to myObj at scale""" if self.selector2 == None: self.createSelector2() self.selector2.show() self.selector2.setPos(myObj.getX(), myObj.getY(), myObj.getZ()) self.selector2.setScale(scale) ##def checkEndTurn(self): ##"""Do a Server Assesment of turn before ending the turn""" ##try: ##if 'EndTurn' in self.game.myEmpire['help']: ### turn not ended yet ##(serverResult, self.game.myEmpire['help']) = self.game.server.askForHelp(self.game.authKey) ##if serverResult == 'Server Assessment: WARNINGS:0, CRITICAL:0 (Check Mail for Assesment)': ### server assessment is good, end the turn without asking ##self.endMyTurn() ##else: ### server assessment has not come back without warnings ask for confirmation ##self.modeYesNoBox('%s - Do you still want to end your turn?' % serverResult, 'endturnYes', 'yesNoBoxNo') ##else: ### turn already ended, unend turn ##self.modeYesNoBox('Do you want to cancel your end turn?' , 'endturnYes', 'yesNoBoxNo') ##except: ##self.modeMsgBox('checkEndTurn->Connection to Server Lost, Login Again') def exitGame(self, doLogout=True): """Exit the game""" self.setEmpireDefaults(self.game.authKey) if doLogout: self.setLogout(self.game.authKey) self.alive = 0 self.game.app.quit() def getCreditInfoFromServer(self): self.getEmpireUpdate(['CR']) def refreshCredit(self): """Ask the Server for an updated Credit Info""" self.mainmenu.updateCR() def getEmpireUpdate(self, listAttr): """Ask the Server for updated Empire info""" try: serverResult = self.game.server.getEmpireUpdate(self.game.authKey, listAttr) if type(serverResult) == types.StringType: self.modeMsgBox(serverResult) else: for key, value in serverResult.iteritems(): self.game.myEmpire[key] = value except: self.modeMsgBox('getEmpireUpdate->Connection to Server Lost') def getMailUpdate(self): """Ask the Server for any updated mail""" try: myMailDict = self.game.myEmpire['mailBox'] serverResult = self.game.server.getMailUpdate(self.game.authKey, myMailDict.keys()) if type(serverResult) == types.StringType: self.modeMsgBox(serverResult) else: for key, value in serverResult.iteritems(): myMailDict[key] = value except: self.modeMsgBox('getMailUpdate->Connection to Server Lost') def getGalaxyUpdate(self, listAttr): """Ask the Server for updated Galaxy info""" try: serverResult = self.game.server.getGalaxyUpdate(listAttr, self.game.authKey) if type(serverResult) == types.StringType: self.modeMsgBox(serverResult) else: for key, value in serverResult.iteritems(): self.game.myGalaxy[key] = value except: self.modeMsgBox('getGalaxyUpdate->Connection to Server Lost') def getSystemUpdate(self, listAttr, systemID): """Ask the Server for updated System info""" try: serverResult = self.game.server.getSystemUpdate(listAttr, systemID, self.game.authKey) if type(serverResult) == types.StringType: self.modeMsgBox(serverResult) else: mySystemDict = self.game.allSystems[systemID] for key, value in serverResult.iteritems(): mySystemDict[key] = value except: self.modeMsgBox('getSystemUpdate->Connection to Server Lost') def enterMode(self): """Enter the mode.""" self.alive = 1 self.setShortcuts() def setShortcuts(self): """Set the default mode shortcuts""" self.game.app.accept('mouse1', self.onMouse1Down) self.game.app.accept('mouse3', self.onMouse2Down) self.game.app.accept('space', self.onSpaceBarClear) if self.enableMouseCamControl == 1: self.game.app.accept('wheel_up', self.onMouseWheelUp) self.game.app.accept('wheel_down', self.onMouseWheelDown) def exitMode(self): """Exit the mode""" self.removeMySims() self.removeAllGui() self.game.app.ignoreAll() self.removeAllTasks() self.alive = 0 def removeAllTasks(self): """Remove and Stop any tasks running""" for taskName in self.runningTasks: taskMgr.remove(taskName) def removeMySims(self): """Remove all sims in mode""" for sim in self.sims: try: sim.destroy() except: sim.removeNode() def removeAllGui(self): """Remove all DirectGUI""" for gui in self.gui: gui.destroy() def setPlanePickable(self, obj, dictName): """Set the plane model itself to be collideable with the mouse ray""" obj.sim.reparentTo(self.selectable) obj.sim.find('**/pPlane1').node().setIntoCollideMask(BitMask32.bit(1)) obj.sim.find('**/pPlane1').node().setTag(dictName, obj.id) def setSpherePickable(self, obj, dictName): """Set the sphere model itself to be collideable with the mouse ray""" obj.sim.reparentTo(self.selectable) obj.sim.find('**/pSphere1').node().setIntoCollideMask(BitMask32.bit(1)) obj.sim.find('**/pSphere1').node().setTag(dictName, obj.id) def setMySelector(self, x, y, z, scale): """Show selector if it is not in current position else return false""" selectorPos = (self.selector.getX(), self.selector.getY(), self.selector.getZ()) if selectorPos != (x,y,z): self.selector.setPos(x,y,z) self.selector.show() self.selector.setScale(scale) return 1 else: self.selector.setPos(-1,-1,-1) return 0 #self.enableScrollWheelZoom = 0 def getListButton(self, id, myScrolledList): """Return Button selected from buttonList gui based on id""" for button in myScrolledList.buttonsList: if button['extraArgs'][1] == id: return button def setMySelector2(self, x, y, z, scale): """Show selector2 if it is not in current position else return false""" selectorPos = (self.selector2.getX(), self.selector2.getY(), self.selector2.getZ()) if selectorPos != (x,y,z): self.selector2.setPos(x,y,z) self.selector2.show() self.selector2.setScale(scale) return 1 else: self.selector2.setPos(-1,-1,-1) return 0 #self.enableScrollWheelZoom = 0 def hideMySelector(self): """Hide the selector, move its position""" self.selector.setPos(-1,-1,-1) self.selector.hide() if self.selector2 != None: self.selector2.hide() def onMouse1Down(self): """Allow dynamic picking of an object within mode""" #Check to see if we can access the mouse. We need it to do anything else if base.mouseWatcherNode.hasMouse(): #get the mouse position mpos = base.mouseWatcherNode.getMouse() #Set the position of the ray based on the mouse position self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) #Do the actual collision pass (Do it only on the selectable for #efficiency purposes) self.picker.traverse(self.selectable) 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() for selectable in self.selectTypes: name = self.pq.getEntry(0).getIntoNode().getTag(selectable) if name != '': self.clearAnyGui() mySelectedDict = getattr(self, selectable) mySelected = mySelectedDict[name] myMethod = getattr(self, '%sSelected' % selectable) if self.validateSelection(): myMethod(mySelected) break def onMouseWheelUp(self): """ zoom out """ if self.enableScrollWheelZoom: self.stopCameraTasks() self.zoomInCameraAmount(20.0) def onMouseWheelDown(self): """ zoom in """ if self.enableScrollWheelZoom: self.stopCameraTasks() self.zoomOutCameraAmount(20.0) def onMouse2Down(self): """clear""" self.onSpaceBarClear() def onSpaceBarClear(self): """Space bar should reset the view in the mode""" if self.validateSelection(): self.resetCamera() self.clearMouseSelection() self.zoomOutCamera() self.setShortcuts() self.enableScrollWheelZoom = 1 def clearMouseSelection(self): """Clear mouse selection before selecting something new""" pass def clearAnyGui(self): pass def update(self, interval): """update the mode, return the status, 0 means stop game""" return self.alive def setMyBackground(self): """Set the Background of mode""" base.setBackgroundColor(globals.colors['guiblue3']) def setEmpireDefaults(self, clientKey): """Read the defaults currently set and change them in the database""" try: # setup attributes to send to server defaults = ['viewIndustry', 'viewMilitary', 'viewResources', 'viewTradeRoutes'] d = {} for item in defaults: d[item] = self.game.myEmpire[item] serverResult = self.game.server.setEmpire(clientKey, d) if serverResult == 1: print 'Setup Empire Defaults Success' else: self.modeMsgBox(serverResult) except: self.modeMsgBox('SetEmpireDefaults->Connection to Server Lost, Login Again') def setEmpireValues(self, dValues): """Update Empire with d = key: empire attribute name, value = new value""" try: serverResult = self.game.server.setEmpire(self.game.authKey, dValues) if serverResult == 1: for key, value in dValues.iteritems(): self.game.myEmpire[key] = value print 'Empire Update Success' else: self.modeMsgBox(serverResult) except: self.modeMsgBox('setEmpireValues->Connection to Server Lost, Login Again') def setLogout(self, clientKey): """Send a Logout Request to the Server""" try: serverResult = self.game.server.logout(clientKey) if serverResult == 1: print 'Logout Successful, Exit Program' else: self.modeMsgBox(serverResult) except: self.modeMsgBox('setLogout->Connection to Server Lost, Login Again') def submitDesign(self, name): """Take Ship Design and submit it to Server for verification and storage""" (oldName, hullID, compDict, weaponDict) = self.myShipDesign.getMyDesign() dOrder = {'name':name, 'hullID':hullID, 'compDict':compDict, 'weaponDict':weaponDict} try: serverResult = self.game.server.addShipDesign(self.game.authKey, dOrder) if type(serverResult) == types.StringType: self.modeMsgBox(serverResult) else: # design has been accepted by server, retrieve design ID and add to client (ID,name) = serverResult self.game.shipDesigns[ID] = (name, hullID, compDict, weaponDict) self.getEmpireUpdate(['designsLeft']) except: self.modeMsgBox('submitDesign->Connection to Server Lost, Login Again') def destroyTempFrames(self): """Destroy any Temp Frames""" for frame in self.tempFrames: frame.destroy() self.tempFrames = [] def modeMsgBox(self, messageText): """Create a message for the user""" self.createMessage(messageText) def createMessage(self, text): """Create a new message for user""" myMessage = fadingtext.FadingText(self.guiMediaPath, text, self.messagePositions) self.messagePositions.append(myMessage.getMyPosition()) self.playSound('beep03') def writeToScreen(self, myText, x, z, scale=0.2, color='default', font=3, wordwrap=10): if color == 'default': color = Vec4(.1,.1,.8,.8) text = textonscreen.TextOnScreen(self.guiMediaPath, myText, scale,font=3) text.writeTextToScreen(x, self.depth, z, wordwrap=wordwrap) text.setColor(color) self.gui.append(text) def loadObject(self, tex=None, pos='default', depth=55, scale=1, transparency=True, parent='cam', model='plane', glow=0): if pos == 'default': pos = Point2(0,0) if parent == 'cam': parent = camera scaleX = 187.5 scaleZ = 117.1875 obj = loader.loadModelCopy('%s%s' % (self.guiMediaPath, model)) #default object uses the plane model if parent: obj.reparentTo(parent) #Everything is parented to the camera so #that it faces the screen obj.setPos(Point3(pos.getX(), depth, pos.getY())) #Set initial position obj.setSx(scaleX) obj.setSz(scaleZ) obj.setBin("unsorted", 0) #This tells Panda not to worry about the #order this is drawn in. (it prevents an #effect known as z-fighting) if transparency: obj.setTransparency(1) #All of our objects are trasnparent if tex: tex = loader.loadTexture('%s%s.png' % (self.guiMediaPath, tex)) #Load the texture obj.setTexture(tex, 1) #Set the texture self.sims.append(obj) obj.setShaderInput('glow',Vec4(glow,0,0,0),glow) return obj def onEntryFocus(self): """When a text Entry is in focus disable all shortcut keys""" for gui in self.gui: if gui.__module__ in self.entryFocusList: gui.ignoreShortcuts() def onEntryOutFocus(self): """When an text Entry is out of focus enable all shortcut keys""" for gui in self.gui: if gui.__module__ in self.entryFocusList: gui.setShortcuts()
class CameraHandler(DirectObject.DirectObject): def __init__(self, parserClass, mapLoaderClass, modelLoaderClass, mainClass, mapWidth, mapHeight, scrollborder, zoomInSpeed, zoomOutSpeed, zoomMax, zoomMin): self.zoomMax = zoomMax self.zoomMin = zoomMin base.disableMouse() # This disables the default mouse based camera control used by panda. This default control is awkward, and won't be used. base.camera.setPos(10,20,10) base.camera.lookAt(0,0,0) # Gives the camera an initial position and rotation. self.mx,self.my = 0,0 # Sets up variables for storing the mouse coordinates self.orbiting = False # A boolean variable for specifying whether the camera is in orbiting mode. Orbiting mode refers to when the camera is being moved # because the user is holding down the right mouse button. self.target = Vec3() # sets up a vector variable for the camera's target. The target will be the coordinates that the camera is currently focusing on. self.camDist = 20 # A variable that will determine how far the camera is from it's target focus self.panRateDivisor = 100. # This variable is used as a divisor when calculating how far to move the camera when panning. Higher numbers will yield slower panning # and lower numbers will yield faster panning. This must not be set to 0. self.panZoneSize = scrollborder # This variable controls how close the mouse cursor needs to be to the edge of the screen to start panning the camera. It must be less than 1, # and I recommend keeping it less than .2 self.panLimitsX = Vec2(0, 4*mapWidth) self.panLimitsY = Vec2(0, 4*mapHeight) # These two vairables will serve as limits for how far the camera can pan, so you don't scroll away from the map. self.setTarget(0,0,0) # calls the setTarget function to set the current target position to the origin. self.turnCameraAroundPoint(0,0) # calls the turnCameraAroundPoint function with a turn amount of 0 to set the camera position based on the target and camera distance self.accept("mouse2",self.startOrbit) # sets up the camrea handler to accept a right mouse click and start the "drag" mode. self.accept("mouse2-up",self.stopOrbit) # sets up the camrea handler to understand when the right mouse button has been released, and ends the "drag" mode when # the release is detected. # The next pair of lines use lambda, which creates an on-the-spot one-shot function. self.accept("wheel_up",lambda : self.adjustCamDist(zoomInSpeed)) # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the # adjustCamDist function with the argument 0.9 self.accept("wheel_down",lambda : self.adjustCamDist(zoomOutSpeed)) # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the # adjustCamDist function with the argument 1.1 # ######### self.tileSelected = (0,0) #** Collision events ignition base.cTrav = CollisionTraverser() collisionHandler = CollisionHandlerEvent() self.collisionHandler2 = CollisionHandlerQueue() pickerNode=CollisionNode('mouseraycnode') pickerNP=base.camera.attachNewNode(pickerNode) self.pickerRay=CollisionRay() pickerNode.addSolid(self.pickerRay) base.cTrav.showCollisions(render) # The ray tag pickerNode.setTag('rays','ray1') base.cTrav.addCollider(pickerNP, self.collisionHandler2) self.accept("mouse1", self.mouseClick, [mapLoaderClass]) self.accept("q", self.mineWall, [parserClass, modelLoaderClass, mapLoaderClass, mainClass]) taskMgr.add(self.rayupdate, "blah") ########## taskMgr.add(self.camMoveTask,'camMoveTask') # sets the camMoveTask to be run every frame ########## def rayupdate(self, task): if base.mouseWatcherNode.hasMouse(): self.entry=0 self.collisionHandler2.sortEntries() if self.collisionHandler2.getNumEntries()>0: self.entry=self.collisionHandler2.getEntry(0) mpos=base.mouseWatcherNode.getMouse() # this function will set our ray to shoot from the actual camera lenses off the 3d scene, passing by the mouse pointer position, # making magically hit what is pointed by it in the 3d space self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) return task.cont def mineWall(self, parserClass, modelLoaderClass, mapLoaderClass, mainClass): if (self.tileSelected != (0,0)): mainClass.mineWall(mapLoaderClass.tileArray[self.tileSelected[1]][self.tileSelected[0]], parserClass, modelLoaderClass, mapLoaderClass) def mouseClick(self, mapLoaderClass): if (self.entry!=0): x = int(self.entry.getIntoNode().getName()[len(self.entry.getIntoNode().getName())-6:len(self.entry.getIntoNode().getName())-4]) y = int(self.entry.getIntoNode().getName()[len(self.entry.getIntoNode().getName())-2:]) if (mapLoaderClass.tileArray[y][x].selectable == True): mapLoaderClass.tileArray[self.tileSelected[1]][self.tileSelected[0]].model.setColor(1,1,1,1) mapLoaderClass.tileArray[y][x].model.setColor(0.5,1,0.5,1) self.tileSelected = (x, y) else: mapLoaderClass.tileArray[self.tileSelected[1]][self.tileSelected[0]].model.setColor(1,1,1,1) self.tileSelected = (0,0) # print self.tileSelected def turnCameraAroundPoint(self, deltaX, deltaY): # This function performs two important tasks. First, it is used for the camera orbital movement that occurs when the # right mouse button is held down. It is also called with 0s for the rotation inputs to reposition the camera during the # panning and zooming movements. # The delta inputs represent the change in rotation of the camera, which is also used to determine how far the camera # actually moves along the orbit. newCamHpr = Vec3() newCamPos = Vec3() # Creates temporary containers for the new rotation and position values of the camera. camHpr=base.camera.getHpr() # Creates a container for the current HPR of the camera and stores those values. newCamHpr.setX(camHpr.getX()+deltaX) newCamHpr.setY(self.clamp(camHpr.getY()-deltaY, -85, -10)) newCamHpr.setZ(camHpr.getZ()) # Adjusts the newCamHpr values according to the inputs given to the function. The Y value is clamped to prevent # the camera from orbiting beneath the ground plane and to prevent it from reaching the apex of the orbit, which # can cause a disturbing fast-rotation glitch. base.camera.setHpr(newCamHpr) # Sets the camera's rotation to the new values. angleradiansX = newCamHpr.getX() * (math.pi / 180.0) angleradiansY = newCamHpr.getY() * (math.pi / 180.0) # Generates values to be used in the math that will calculate the new position of the camera. newCamPos.setX(self.camDist*math.sin(angleradiansX)*math.cos(angleradiansY)+self.target.getX()) newCamPos.setY(-self.camDist*math.cos(angleradiansX)*math.cos(angleradiansY)+self.target.getY()) newCamPos.setZ(-self.camDist*math.sin(angleradiansY)+self.target.getZ()) base.camera.setPos(newCamPos.getX(),newCamPos.getY(),newCamPos.getZ()) # print (newCamPos.getX(),newCamPos.getY(),newCamPos.getZ()) # Performs the actual math to calculate the camera's new position and sets the camera to that position. #Unfortunately, this math is over my head, so I can't fully explain it. base.camera.lookAt(self.target.getX(),self.target.getY(),self.target.getZ() ) # Points the camera at the target location. def setTarget(self, x, y, z): #This function is used to give the camera a new target position. x = self.clamp(x, self.panLimitsX.getX(), self.panLimitsX.getY()) self.target.setX(x) y = self.clamp(y, self.panLimitsY.getX(), self.panLimitsY.getY()) self.target.setY(y) self.target.setZ(z) # Stores the new target position values in the target variable. The x and y values are clamped to the pan limits. def setPanLimits(self, xMin, xMax, yMin, yMax): # This function is used to set the limitations of the panning movement. self.panLimitsX = (xMin, xMax) self.panLimitsY = (yMin, yMax) # Sets the inputs into the limit variables. def clamp(self, val, minVal, maxVal): # This function constrains a value such that it is always within or equal to the minimum and maximum bounds. val = min( max(val, minVal), maxVal) # This line first finds the larger of the val or the minVal, and then compares that to the maxVal, taking the smaller. This ensures # that the result you get will be the maxVal if val is higher than it, the minVal if val is lower than it, or the val itself if it's # between the two. return val # returns the clamped value def startOrbit(self): # This function puts the camera into orbiting mode. self.orbiting=True # Sets the orbiting variable to true to designate orbiting mode as on. def stopOrbit(self): # This function takes the camera out of orbiting mode. self.orbiting=False # Sets the orbiting variable to false to designate orbiting mode as off. def adjustCamDist(self, distFactor): # This function increases or decreases the distance between the camera and the target position to simulate zooming in and out. # The distFactor input controls the amount of camera movement. # For example, inputing 0.9 will set the camera to 90% of it's previous distance. self.camDist=self.camDist*distFactor if (self.camDist >= self.zoomMax): self.camDist = self.zoomMax elif (self.camDist <= self.zoomMin): self.camDist = self.zoomMin # Sets the new distance into self.camDist. self.turnCameraAroundPoint(0,0) # Calls turnCameraAroundPoint with 0s for the rotation to reset the camera to the new position. def camMoveTask(self, task): # This task is the camera handler's work house. It's set to be called every frame and will control both orbiting and panning the camera. if base.mouseWatcherNode.hasMouse(): # We're going to use the mouse, so we have to make sure it's in the game window. If it's not and we try to use it, we'll get # a crash error. mpos = base.mouseWatcherNode.getMouse() # Gets the mouse position if self.orbiting: # Checks to see if the camera is in orbiting mode. Orbiting mode overrides panning, because it would be problematic if, while # orbiting the camera the mouse came close to the screen edge and started panning the camera at the same time. self.turnCameraAroundPoint((self.mx-mpos.getX())*100,(self.my-mpos.getY())*100) # calculates new values for camera rotation based on the change in mouse position. mx and my are used here as the old # mouse position. else: # If the camera isn't in orbiting mode, we check to see if the mouse is close enough to the edge of the screen to start panning moveY=False moveX=False # these two booleans are used to denote if the camera needs to pan. X and Y refer to the mouse position that causes the # panning. X is the left or right edge of the screen, Y is the top or bottom. if self.my > (1 - self.panZoneSize): angleradiansX1 = base.camera.getH() * (math.pi / 180.0) panRate1 = (1 - self.my - self.panZoneSize) * (self.camDist / self.panRateDivisor) * 2 moveY = True if self.my < (-1 + self.panZoneSize): angleradiansX1 = base.camera.getH() * (math.pi / 180.0)+math.pi panRate1 = (1 + self.my - self.panZoneSize)*(self.camDist / self.panRateDivisor) moveY = True if self.mx > (1 - self.panZoneSize): angleradiansX2 = base.camera.getH() * (math.pi / 180.0)+math.pi*0.5 panRate2 = (1 - self.mx - self.panZoneSize) * (self.camDist / self.panRateDivisor) * 2 moveX = True if self.mx < (-1 + self.panZoneSize): angleradiansX2 = base.camera.getH() * (math.pi / 180.0)-math.pi*0.5 panRate2 = (1 + self.mx - self.panZoneSize) * (self.camDist / self.panRateDivisor) moveX = True # These four blocks check to see if the mouse cursor is close enough to the edge of the screen to start panning and then # perform part of the math necessary to find the new camera position. Once again, the math is a bit above my head, so # I can't properly explain it. These blocks also set the move booleans to true so that the next lines will move the camera. if moveY: tempX = self.target.getX()+math.sin(angleradiansX1)*panRate1 tempX = self.clamp(tempX, self.panLimitsX.getX(), self.panLimitsX.getY()) self.target.setX(tempX) tempY = self.target.getY()-math.cos(angleradiansX1)*panRate1 tempY = self.clamp(tempY, self.panLimitsY.getX(), self.panLimitsY.getY()) self.target.setY(tempY) self.turnCameraAroundPoint(0,0) if moveX: tempX = self.target.getX()-math.sin(angleradiansX2)*panRate2 tempX = self.clamp(tempX, self.panLimitsX.getX(), self.panLimitsX.getY()) self.target.setX(tempX) tempY = self.target.getY()+math.cos(angleradiansX2)*panRate2 tempY = self.clamp(tempY, self.panLimitsY.getX(), self.panLimitsY.getY()) self.target.setY(tempY) self.turnCameraAroundPoint(0,0) # These two blocks finalize the math necessary to find the new camera position and apply the transformation to the # camera's TARGET. Then turnCameraAroundPoint is called with 0s for rotation, and it resets the camera position based # on the position of the target. The x and y values are clamped to the pan limits before they are applied. # print(self.target) self.mx=mpos.getX() self.my=mpos.getY() # The old mouse positions are updated to the current mouse position as the final step. return task.cont
class objectIdPicklingClass: def __init__( self, bit=[PICKABLE] ): global OBJECTIDMAPPING #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 = base.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(bitMaskOr(bit)) 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) def mousePick( self ): #Check to see if we can access the mouse. We need it to do anything else if base.mouseWatcherNode.hasMouse(): #get the mouse position mpos = base.mouseWatcherNode.getMouse() #Set the position of the ray based on the mouse position self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) #Do the actual collision pass (Do it only on the squares for #efficiency purposes) self.picker.traverse( render ) 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() pickedObj = self.pq.getEntry(0).getIntoNodePath() #print pickedObj pickedObjObjectId = pickedObj.findNetTag( 'objectId' ) if pickedObj.hasNetTag( 'objectId' ): return pickedObj.getNetTag( 'objectId' ) else: print "pickedObj.hasNetTag( 'objectId' ) failed" return None else: print "self.pq.getNumEntries() = %i" % self.pq.getNumEntries() return None else: print "base.mouseWatcherNode.hasMouse() failed" return None def getPickerRayDirection( self, mousePos=None ): #posX, posY ): ''' return the direction of the ray sent trought the mouse ''' # the pickerRay cannot be changed anyway once it has been set in a frame (BUG?) if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() #mousePos = (mpos.getX(), mpos.getY()) self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) # make a copy of the ray direction = self.pickerRay.getDirection() mouseRayDirection = Point3(direction.getX(), direction.getY(), direction.getZ()) # and normalize it mouseRayDirection.normalize() return mouseRayDirection def getObjectMousePick( self ): objectId = self.mousePick() if OBJECTIDMAPPING.has_key( objectId ): return OBJECTIDMAPPING[objectId] else: return None
class Input(DirectObject): def __init__(self,model): self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) self.Text = OnscreenText(text="Set PanRate",pos=(-1.25,-0.15),scale=0.1) self.slider = DirectSlider(range=(20,100), value=50, pageSize=2, pos=(-1.25,0,-0.2),scale= (0.2,0.2,0.2), command=self.setScrollSpeed) def Attack(self,pos): self.atk.setWeil(self.model) self.atk.setTarg(self.dumm) self.atk.setDist(self.mini) if self.mini<=60: self.Animate=self.atk.ATT() else: messenger.send('mouse3') if self.mini<=60: self.atk.ATT() def setScrollSpeed(self): SCROLLSPEED=self.slider['value'] def MousePos(self, task): #This Took me 1.5 Months to Learn if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pos3d = Point3() self.nearPoint = Point3() self.farPoint = Point3() base.camLens.extrude(mpos, self.nearPoint, self.farPoint) if self.plane.intersectsLine(self.pos3d, render.getRelativePoint(camera, self.nearPoint), render.getRelativePoint(camera, self.farPoint)): pass return task.again def MoveHero(self): self.startR=self.model.getHpr() self.target=self.pos3d x2,y2,z2=self.target.getX(),self.target.getY(),self.target.getZ() h1,p1,r1=self.model.getH(),self.model.getP(),self.model.getR() self.dist=sqrt(pow(self.x1-x2,2)+pow(self.y1-y2,2)) self.sptime=self.dist/(30) self.hall=270-degrees(y2/x2) # self.model.setPos(self.model,self.spd,0,self.spd) Inter=LerpPosHprInterval(self.model,self.sptime,pos=self.target ,startPos=self.model.getPos(),startHpr=self.startR,hpr=self.startR)#(h1,p1,self.hall)) #Inter2=Func(self.model.lookAt(self.target),Wait(0.3)) self.heroPace = Sequence(Inter,name="heroPace") self.heroPace.start() def Move(self,task): self.x1,self.y1=self.model.getX(),self.model.getY() self.x2,self.y2=self.dumm.getX(),self.dumm.getY() self.mini=sqrt(pow(self.x1-self.x2,2)+pow(self.y1-self.y2,2)) Debug2(self,str(self.mini)) elapsed = globalClock.getDt() self.dt=elapsed self.setAnim() if (self.keyMap["left"]!=0): self.model.setH(self.model.getH() + self.dt*300) if (self.keyMap["right"]!=0): self.model.setH(self.model.getH() - self.dt*300) if (self.keyMap["forward"]!=0): self.model.setX(self.model, +(self.dt*25*SPEED)) # base.camera.lookAt(self.model) self.floater.setPos(self.model.getPos()) # base.camera.lookAt(self.floater) return task.cont def Setup(self): self.accept("arrow_left", self.setKey1, ["left",1,True]) self.accept("arrow_right", self.setKey1, ["right",1,True]) self.accept("arrow_up", self.setKey1, ["forward",1,True]) self.accept("arrow_left-up", self.setKey1, ["left",0,False]) self.accept("arrow_right-up", self.setKey1, ["right",0,False]) self.accept("arrow_up-up", self.setKey1, ["forward",0,False]) self.accept("mouse1",self.ObjectClick) self.accept("mouse3",self.MoveHero) def setKey1(self, key, value,value2): self.keyMap[key] = value self.Change=value2 def setAnim(self): if self.Change: #(self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0): if self.isMoving is False: self.model.loop("run") self.isMoving = True else: if self.isMoving: self.model.stop() self.model.pose("walk",5) self.isMoving = False if self.Animate: pass #set the attack anim here def Coll(self): base.cTrav = CollisionTraverser() self.collHandler = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) base.cTrav.addCollider(self.pickerNP, self.collHandler) def ObjectClick(self): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) base.cTrav.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if self.collHandler.getNumEntries() > 0: # This is so we get the closest object. self.collHandler.sortEntries() self.pickedObj = self.collHandler.getEntry(0).getIntoNodePath() self.pickedObj = self.pickedObj.findNetTag('Unit') if not self.pickedObj.isEmpty(): self.Attack(self.pickedObj.getPos())
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
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 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 NodeRaycaster: def __init__(self, renderer): self.log = logging.getLogger('pano.raycaster') self.renderer = renderer #Stores the collisions of the camera ray with the cubemap self.collisionsQueue = None #Variables for setting up collision detection in Panda self.pickerNP = None self.pickerNode = None self.pickerRay = None self.traverser = None def initialize(self): """ To setup collision detection we need: a. A CollisionNode having a ray as its solid and placed at the position of the camera while also having the same orientation as the camera. b. A new nodepath placed in the scenegraph as an immediate child of the camera. It will be used to insert the collision node in the scenegraph. c. A CollisionRay for firing rays based on mouse clicks. d. A collisions traverser. e. A collisions queue where all found collisions will be stored for later processing. """ self.traverser = CollisionTraverser('Hotspots collision traverser') self.collisionsQueue = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.pickerNP = self.renderer.getCamera().attachNewNode( self.pickerNode) self.traverser.addCollider(self.pickerNP, self.collisionsQueue) def dispose(self): if self.pickerNP is not None: self.traverser.removeCollider(self.pickerNP) self.pickerNode.clearSolids() self.pickerNP.removeNode() def raycastWindow(self, x, y, returnAll=False): ''' Casts a camera ray, whose origin is implicitly defined by the given window coordinates, against the rendered scene returns information regarding the hit point, if any. @param x: The x window coordinate of the ray's origin in render2d space. @param y: The y window coordinate of the ray's origin in render2d space @param returnAll: If set to False then only the closest collided geometry is returned, otherwise all nodepaths whose collision nodes were intersected by the camera ray will be returned. @return: If returnAll was False, then a list containing a tuple of the form (topmost intersected NodePath, contact point Point3f). if returnAll was set to True, a list of tuples in the same form as above, one tuple for each intersection. None if no collision occurred. ''' #This makes the ray's origin the camera and makes the ray point #to the screen coordinates of the mouse self.pickerRay.setFromLens(self.renderer.getCamera().node(), x, y) #Check for collision only with the node self.traverser.traverse(self.renderer.getSceneRoot()) if self.collisionsQueue.getNumEntries() > 0: if not returnAll: self.collisionsQueue.sortEntries() cEntry = self.collisionsQueue.getEntry(0) if cEntry.hasInto(): return [(cEntry.getIntoNodePath(), cEntry.getSurfacePoint())] else: return None else: nodepaths = [] for i in xrange(self.collisionsQueue.getNumEntries()): cEntry = self.collisionsQueue.getEntry(i) if cEntry.hasInto(): # self.log.debug('adding collision into-nodepath: %s' % str(cEntry.getIntoNodePath())) intoNP = cEntry.getIntoNodePath() nodepaths.append( (intoNP, cEntry.getSurfacePoint(intoNP))) return nodepaths
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 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)))
class MousePicker( p3d.Object ): """ Class to represent a ray fired from the input camera lens using the mouse. """ 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 FireEvent( self, event ): # Send a message containing the node name and the event name, including # the collision entry as arguments print "FireEvent", event, self.node if self.node is not None: print self.np, self.np.getName() messenger.send( '%s-%s' % ( self.node.getName(), event ), [self.collEntry] ) elif event in ('mouse1', 'control-mouse1'): self.StartSelection() elif event == 'mouse1-up': if self.marquee.started: self.StopSelection() def UpdateTask( self, task ): #self.collTrav.traverse( self.rootNp ) # Traverse the hierarchy and find collisions self.collTrav.traverse(render) # Traverse the hierarchy and find collisions if self.collHandler.getNumEntries(): # If we have hit something, self.collHandler.sortEntries() # sort the hits so that the closest is first collEntry = self.collHandler.getEntry( 0 ) else: collEntry = None self.set_node( collEntry) # updating the pickerRay if base.mouseWatcherNode.hasMouse(): mp = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens( self.camera.node(), mp.getX(), mp.getY() ) return task.cont def set_node(self, collEntry): #== if collEntry : new_node = collEntry.getIntoNode() else : new_node = None #== if new_node == self.node : # ultra triky bit, even if the node is th same # the collision is not and it is used for the picking later on if collEntry : self.collEntry = collEntry return #== if self.node is not None: messenger.send( '%s-mouse-leave' % self.node.getName()) self.np.setColorScale( Vec4(1) ) self.node = None #== if new_node is not None: self.collEntry = collEntry self.node = new_node #== self.np = self.collEntry.getIntoNodePath().getParent() self.np.setColorScale( Vec4(1, 0, 0, 1) ) print self.np , self.np.getName() messenger.send( '%s-mouse-enter' %self.node.getName(), [collEntry] ) messenger.send( '%s-mouse-over' %self.node.getName(), [collEntry] ) def StartSelection( self, clearSelection=True ): print "StartSelection" # Reset selected node colours if self.selectionCol: self.selectionCol.replace_nodes([]) #for i in self.selection: #i.setColorScale( Vec4(1) ) self.marquee.Start() #== if clearSelection: self.selection = set([]) def StopSelection( self ): print "StopSelection" # Stop the marquee self.marquee.Stop() nodes = set([]) for node in self.rootNp.findAllMatches( '**' ): if self.marquee.IsPoint3Inside( self.camera, self.rootNp, node.getPos() ): #if self.pickTag is None or node.getTag( self.pickTag ): if node.getPythonTag('mesh_view'): nodes.add( node ) # Add any node which was under the mouse to the selection if self.collHandler.getNumEntries(): collEntry = self.collHandler.getEntry( 0 ) node = collEntry.getIntoNodePath().getParent() if node.getPythonTag('mesh_view'): nodes.add( node ) #nodes.add( node ) self.selection = nodes #== if self.selectionCol: self.selectionCol.replace_nodes(nodes) #for i in self.selection: #i.setColorScale( Vec4(1, 0, 0, 1) ) #== self.gizmos.AttachNodePaths( self.selection ) if self.gizmos.active is not None: # Refresh the active gizmo so it appears in the right place self.gizmos.active.Refresh()