コード例 #1
0
ファイル: MouseControls.py プロジェクト: rll/labeling_tool
    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()
コード例 #2
0
ファイル: Controller.py プロジェクト: crempp/psg
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)
コード例 #3
0
    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()
コード例 #4
0
ファイル: Picker.py プロジェクト: sambarza/bo
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
                                        
コード例 #5
0
 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
コード例 #6
0
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
コード例 #7
0
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))
コード例 #8
0
ファイル: gui_3d.py プロジェクト: JDShu/das-leben
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))
コード例 #9
0
ファイル: Hero.py プロジェクト: UIKit0/Dota2War
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()
コード例 #10
0
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 ) )
コード例 #11
0
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
コード例 #12
0
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
コード例 #13
0
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)
コード例 #14
0
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 
コード例 #15
0
ファイル: __init__.py プロジェクト: Fish4/Atlantis-Warfare
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)
コード例 #16
0
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
コード例 #17
0
ファイル: __init__.py プロジェクト: edom71/hexabots
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)
コード例 #18
0
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
コード例 #19
0
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()
コード例 #20
0
ファイル: stratCam.py プロジェクト: MichaelEbert/ORR2
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
コード例 #21
0
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
コード例 #22
0
ファイル: Hero.py プロジェクト: UIKit0/Dota2War
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())
コード例 #23
0
ファイル: mazeAnimation.py プロジェクト: PlumpMath/aMAZEing
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
コード例 #24
0
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
コード例 #25
0
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)
コード例 #26
0
ファイル: NodeRaycaster.py プロジェクト: vardis/pano
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
コード例 #27
0
ファイル: MouseControls.py プロジェクト: rll/labeling_tool
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
コード例 #28
0
ファイル: cameraCollision.py プロジェクト: borgified/Hockfire
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)))
コード例 #29
0
ファイル: mousePicker.py プロジェクト: LBdN/labs
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()