def createPlayerCollisions(self): """ create a collision solid and ray for the player """ cn = CollisionNode('player') cn.setFromCollideMask(COLLISIONMASKS['geometry']) cn.setIntoCollideMask(COLLISIONMASKS['portals'] | COLLISIONMASKS['exit'] | COLLISIONMASKS['lava']) cn.addSolid(CollisionSphere(0,0,0,3)) solid = self.node.attachNewNode(cn) # TODO : find a way to remove that, it's the cause of the little # "push me left" effect we see sometime when exiting a portal self.base.cTrav.addCollider(solid,self.base.pusher) self.base.pusher.addCollider(solid,self.node, self.base.drive.node()) # init players floor collisions ray = CollisionRay() ray.setOrigin(0,0,-.2) ray.setDirection(0,0,-1) cn = CollisionNode('playerRay') cn.setFromCollideMask(COLLISIONMASKS['player']) cn.setIntoCollideMask(BitMask32.allOff()) cn.addSolid(ray) solid = self.node.attachNewNode(cn) self.nodeGroundHandler = CollisionHandlerQueue() self.base.cTrav.addCollider(solid, self.nodeGroundHandler) # init players ceil collisions ray = CollisionRay() ray.setOrigin(0,0,.2) ray.setDirection(0,0,1) cn = CollisionNode('playerUpRay') cn.setFromCollideMask(COLLISIONMASKS['player']) cn.setIntoCollideMask(BitMask32.allOff()) cn.addSolid(ray) solid = self.node.attachNewNode(cn) self.ceilGroundHandler = CollisionHandlerQueue() self.base.cTrav.addCollider(solid, self.ceilGroundHandler)
def addRalph(self, pos): ralphStartPos = pos self.ralph = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0,0,1000) self.ralphGroundRay.setDirection(0,0,-1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0)) self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0,0,1000) self.camGroundRay.setDirection(0,0,-1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
def setUpCamera(self): """ puts camera behind the player in third person """ # Set up the camera # Adding the camera to actor is a simple way to keep the camera locked # in behind actor regardless of actor's movement. base.camera.reparentTo(self.actor) # We don't actually want to point the camera at actors's feet. # This value will serve as a vertical offset so we can look over the actor self.cameraTargetHeight = 0.5 # How far should the camera be from the actor self.cameraDistance = 10 # Initialize the pitch of the camera self.cameraPitch = 45 # The mouse moves rotates the camera so lets get rid of the cursor props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) #set up FOV pl = base.cam.node().getLens() pl.setFov(70) base.cam.node().setLens(pl) # A CollisionRay beginning above the camera and going down toward the # ground is used to detect camera collisions and the height of the # camera above the ground. A ray may hit the terrain, or it may hit a # rock or a tree. If it hits the terrain, we detect the camera's # height. If it hits anything else, the camera is in an illegal # position. """ TODO:: This will need to be changed to bullet """ self.cTrav = CollisionTraverser() self.groundRay = CollisionRay() self.groundRay.setOrigin(0,0,1000) self.groundRay.setDirection(0,0,-1) self.groundCol = CollisionNode('camRay') self.groundCol.addSolid(self.groundRay) self.groundCol.setFromCollideMask(BitMask32.bit(1)) self.groundCol.setIntoCollideMask(BitMask32.allOff()) self.groundColNp = base.camera.attachNewNode(self.groundCol) self.groundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.groundColNp, self.groundHandler) # We will detect anything obstructing the camera's view of the player self.cameraRay = CollisionSegment((0,0,self.cameraTargetHeight),(0,5,5)) self.cameraCol = CollisionNode('cameraRay') self.cameraCol.addSolid(self.cameraRay) self.cameraCol.setFromCollideMask(BitMask32.bit(0)) self.cameraCol.setIntoCollideMask(BitMask32.allOff()) self.cameraColNp = self.actor.attachNewNode(self.cameraCol) self.cameraColHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.cameraColNp, self.cameraColHandler)
class Tree(object): def __init__(self, app, pos, level, index): self.hp = 200 * level self.app = app self.np = app.render.attachNewNode("tree%d" % index) self.np.setPos(pos) self.level = level self.pursuers = [] self.model = app.loader.loadModel('models/tree1') tex = app.loader.loadTexture("textures/"+'tree1'+".jpg") #Load the texture tex.setWrapU(Texture.WMClamp) # default is repeat, which will give tex.setWrapV(Texture.WMClamp) # artifacts at the edges self.model.setTexture(tex, 1) #Set the texture self.model.reparentTo(self.np) self.model.setHpr(uniform(-180,180),0,0) self.model.setScale(2) self.cn = self.np.attachNewNode(CollisionNode('tree_c_%d' % index)) self.cs = CollisionSphere(0,0.0,0.0,6) self.cn.node().addSolid(self.cs) self.cn.node().setFromCollideMask(BitMask32(0x01)) self.cn.node().setIntoCollideMask(BitMask32(0x00)) self.cqueue = CollisionHandlerQueue() app.cTrav.addCollider(self.cn, self.cqueue) def update(self, timer): for i in range(self.cqueue.getNumEntries()): collided_name = self.cqueue.getEntry(i).getIntoNodePath().getName() #enemy collision if collided_name[0] == 'e': self.app.enemy_manager.handle_collision(collided_name, self, timer) # drop loot when killed by panda if self.hp < 0: self.app.item_manager.add_item(self.np.getPos(), "upgrade", self.level) #hit by bullet if collided_name[0] == 'b': if self.hp < 0: bullet = self.app.bullet_manager.get_bullet(collided_name) bullet.apply_effect(self) self.app.bullet_manager.remove_bullet(collided_name) # tree is dead if self.hp < 0: for p in self.pursuers: p.ai_b.pursue(self.app.player.np) self.app.scene.remove(self) self.np.detachNode()
def __init__(self): ShowBase.__init__(self) ## wp = WindowProperties(base.win.getProperties()) ## wp.setSize(1280,720) ## base.win.requestProperties(wp) base.setBackgroundColor(255,250,250) self.listAudio3d = [] self.allSounds() self.energyTime = 0 self.collHandQue = CollisionHandlerQueue() self.collHandQueEne = CollisionHandlerQueue() self.SPEED = .5 self.speedv = 4 base.cTrav = CollisionTraverser() self.bossLvl = False self.bossDead = False self.isMoving = False self.pause = True self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) self.currentLevel = "start" self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, "cam-right":0, "cam-up":0, "cam-down":0, "fire-down":0, "p":0} ###Disable the default camera controls### base.disableMouse() self.pusher = CollisionHandlerPusher() base.cTrav.setRespectPrevTransform(True) #Uncomment to show collisions with environment #base.cTrav.showCollisions(render) self.setAcceptKeys() self.MainMenu() ## List to keep track of all actors added in each level ## to make it easier to cleanup level when destroyed self.crAct = [] self.extraElements = [] self.laserAmo = [] self.beamC = [] self.laserAmoCount = 0 self.enemyTimer = 0 self.gunAmmoCount = 0 self.loaded = [] self.bulletC = []
class Mouse(DirectObject): def __init__(self, levelNP): self.setCursor() # store the nodepath to the level collisions # will be used to check for intersections with the mouse ray self.levelNP = levelNP # Setup a traverser for the picking collisions self.picker = CollisionTraverser() # Setup mouse ray self.pq = CollisionHandlerQueue() # Create a collision Node pickerNode = CollisionNode('MouseRay') # set the nodes collision bitmask pickerNode.setFromCollideMask(BitMask32.bit(1))#GeomNode.getDefaultCollideMask()) # create a collision ray self.pickerRay = CollisionRay() # add the ray as a solid to the picker node pickerNode.addSolid(self.pickerRay) # create a nodepath with the camera to the picker node self.pickerNP = base.camera.attachNewNode(pickerNode) # add the nodepath to the base traverser self.picker.addCollider(self.pickerNP, self.pq) def setCursor(self): base.win.clearRejectedProperties() props = WindowProperties() if sys.platform.startswith('linux'): props.setCursorFilename("./assets/cursor.x11") else: props.setCursorFilename("./assets/cursor.ico") base.win.requestProperties(props) def getMousePos(self): # check if we have a mouse on the window if base.mouseWatcherNode.hasMouse(): # get the mouse position on the screen mpos = base.mouseWatcherNode.getMouse() # set the ray's position self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) # Now call the traverse function to let the traverser check for collisions # with the added colliders and the levelNP self.picker.traverse(self.levelNP) # check if we have a collision if self.pq.getNumEntries() > 0: # sort the entries to get the closest first self.pq.sortEntries() # This is the point at where the mouse ray and the level plane intersect hitPos = self.pq.getEntry(0).getSurfacePoint(render) return hitPos return Point3(0, 0, 0) task.cont
def get_dist_to_cell(self, pos): """Given a position, return the distance to the nearest cell below that position. If no cell is found, returns None.""" self.ray.setOrigin(pos) queue = CollisionHandlerQueue() self.traverser.addCollider(self.ray_nodepath, queue) self.traverser.traverse(self.cell_picker_world) self.traverser.removeCollider(self.ray_nodepath) queue.sortEntries() if not queue.getNumEntries(): return None entry = queue.getEntry(0) return (entry.getSurfacePoint(self.cell_picker_world) - pos).length()
class Projectile(NetEnt): def __init__(self, parent=None, pitch=None, id=None): NetEnt.__init__(self, id) self.node = NetNodePath(PandaNode('projectile')) if parent: self.parent = parent self.node.setPos(parent.node.getPos() + (0,0,1)) self.node.setHpr(parent.node.getHpr()) self.node.setP(pitch) self.node.reparentTo(render) ProjectilePool.add(self) #print 'there are',len(ProjectilePool.values()),'projectiles' self.flyTime = 0 self.sprite = Sprite2d('resources/missile.png', rows=3, cols=1, rowPerFace=(0,1,2,1), anchorY=Sprite2d.ALIGN_CENTER) self.sprite.node.reparentTo(self.node) # set up 'from' collisions - for detecting projectile hitting things self.collisionHandler = CollisionHandlerQueue() self.fromCollider = self.node.attachNewNode(CollisionNode('fromCollider')) self.fromCollider.node().addSolid(CollisionRay(0,0,0,0,1,0)) self.fromCollider.node().setIntoCollideMask(BITMASK_EMPTY) self.fromCollider.node().setFromCollideMask(BITMASK_TERRAIN | BITMASK_CHARACTER) if SHOW_COLLISIONS: self.fromCollider.show() Character.collisionTraverser.addCollider(self.fromCollider,self.collisionHandler) def getState(self): dataDict = NetObj.getState(self) dataDict[0] = self.node.getState() return dataDict def setState(self, weightOld, dataDictOld, weightNew, dataDictNew): oldNode = None if not dataDictOld else dataDictOld.get(0,None) self.node.setState(weightOld, oldNode, weightNew, dataDictNew[0]) def movePostCollide(self, deltaT): desiredDistance = 30*deltaT self.collisionHandler.sortEntries() ch = self.collisionHandler for e in [ch.getEntry(i) for i in range(ch.getNumEntries())]: collisionDist = (self.node.getPos() - e.getSurfacePoint(render)).length() if collisionDist > desiredDistance: break # only accept collisions that aren't with parent if e.getIntoNode().getParent(0).getTag('ID') != str(self.parent.id): return False self.node.setY(self.node, desiredDistance) self.flyTime += deltaT return self.flyTime < 4 def __del__(self): #print 'PROJECTILE BEING REMOVED' self.node.removeNode()
def create(self): self.mPickerTraverser = CollisionTraverser() self.mCollisionQue = CollisionHandlerQueue() self.mPickRay = CollisionRay() self.mPickRay.setOrigin(base.camera.getPos(base.render)) self.mPickRay.setDirection(base.render.getRelativeVector(base.camera, Vec3(0, 1, 0))) # create our collison Node to hold the ray self.mPickNode = CollisionNode(self.nodeName) self.mPickNode.addSolid(self.mPickRay) # Attach that node to the camera since the ray will need to be positioned # relative to it, returns a new nodepath # well use the default geometry mask # this is inefficent but its for mouse picking only self.mPickNP = base.camera.attachNewNode(self.mPickNode) # we'll use what panda calls the "from" node. This is reall a silly convention # but from nodes are nodes that are active, while into nodes are usually passive environments # this isnt a hard rule, but following it usually reduces processing # Everything to be picked will use bit 1. This way if we were doing other # collision we could seperate it, we use bitmasks to determine what we check other objects against # if they dont have a bitmask for bit 1 well skip them! self.mPickNode.setFromCollideMask(BitMask32(1)) # Register the ray as something that can cause collisions self.mPickerTraverser.addCollider(self.mPickNP, self.mCollisionQue) # Setup 2D picker self.mPickerTraverser2D = CollisionTraverser() self.mCollisionQue2D = CollisionHandlerQueue() self.mPickNode2D = CollisionNode("2D PickNode") self.mPickNode2D.setFromCollideMask(BitMask32(1)) self.mPickNode2D.setIntoCollideMask(BitMask32.allOff()) self.mPick2DNP = base.camera2d.attachNewNode(self.mPickNode2D) self.mPickRay2D = CollisionRay() self.mPickNode2D.addSolid(self.mPickRay2D) self.mPickerTraverser2D.addCollider(self.mPick2DNP, self.mCollisionQue2D) if self.showCollisions: self.mPickerTraverser.showCollisions(base.render) self.mPickerTraverser2D.showCollisions(base.aspect2d)
def __init__(self, render, objid, start_pos, gameclient): self.client = gameclient self.id = objid self.motion_controller = None self.is_player = False # state management self.isAnimating = False self.state = state.IDLE self.render = render # scene graph root # create the panda3d actor: just load a default model for now self.actor = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"}) self.actor.reparentTo(render) self.actor.setScale(.2) self.actor.setPos(start_pos) # prepare collision handling self.cTrav = CollisionTraverser() self.GroundRay = CollisionRay() self.GroundRay.setOrigin(0,0,1000) self.GroundRay.setDirection(0,0,-1) self.GroundCol = CollisionNode('actorRay') self.GroundCol.addSolid(self.GroundRay) self.GroundCol.setFromCollideMask(BitMask32.bit(0)) self.GroundCol.setIntoCollideMask(BitMask32.allOff()) self.GroundColNp = self.actor.attachNewNode(self.GroundCol) self.GroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.GroundColNp, self.GroundHandler)
def __init__(self, energy, jeep): self.bebidas = 0 self.energy = energy self.crash = [] self.jeep = jeep """ ---------------------- Prepara las Colisiones ---------------------- """ self.cs = CollisionSphere(0, 0, 0, 20) cont = 0 while( cont < 80 ): self.crash.append( self.energy[cont].attachNewNode(CollisionNode(str(cont))) ) self.crash[cont].node().addSolid(self.cs) #self.crash[cont].show() Uncomment this line to see the colisions cont = cont + 1 self.css = CollisionSphere(0, 0, 0, 12) self.cnodePath = self.jeep.attachNewNode(CollisionNode('cnode')) self.cnodePath.node().addSolid(self.css) #self.cnodePath.show() Uncomment this line to see the colisions self.traverser = CollisionTraverser() self.queue = CollisionHandlerQueue() """ --------------------------------------------------------------------- """ taskMgr.add(self.choque, "choque")
class RayThatCollidesWithScene: def __init__(self): self.hitters = [self.setup_collision_ray(offset, bitmask) for offset, bitmask in [ (-3, BM_LEFT), (3, BM_RIGHT), ]] self.queue = CollisionHandlerQueue() self.traverser = CollisionTraverser('Collision Traverser') self.traverser.showCollisions(base.render) for ray in self.hitters: self.traverser.add_collider(ray, self.queue) base.taskMgr.add(self.collide, "Collision Task") def setup_collision_ray(self, offset, bitmask): # Hitter. Do note that not every combination of object works, # there is a table for that in the manual. hitter = CollisionRay(0, 0, 0, 0, 1, 0) hitter_node = CollisionNode('collision_hitter') hitter_node.setFromCollideMask(bitmask) hitter_nodepath = base.render.attach_new_node(hitter_node) hitter_nodepath.node().addSolid(hitter) hitter_nodepath.set_pos(offset, -2, 0) hitter_nodepath.show() return hitter_nodepath def collide(self, task): self.traverser.traverse(render) for entry in self.queue.get_entries(): print(entry) return task.cont
def __init__(self, app, pos, level, index): self.hp = 200 * level self.app = app self.np = app.render.attachNewNode("tree%d" % index) self.np.setPos(pos) self.level = level self.pursuers = [] self.model = app.loader.loadModel('models/tree1') tex = app.loader.loadTexture("textures/"+'tree1'+".jpg") #Load the texture tex.setWrapU(Texture.WMClamp) # default is repeat, which will give tex.setWrapV(Texture.WMClamp) # artifacts at the edges self.model.setTexture(tex, 1) #Set the texture self.model.reparentTo(self.np) self.model.setHpr(uniform(-180,180),0,0) self.model.setScale(2) self.cn = self.np.attachNewNode(CollisionNode('tree_c_%d' % index)) self.cs = CollisionSphere(0,0.0,0.0,6) self.cn.node().addSolid(self.cs) self.cn.node().setFromCollideMask(BitMask32(0x01)) self.cn.node().setIntoCollideMask(BitMask32(0x00)) self.cqueue = CollisionHandlerQueue() app.cTrav.addCollider(self.cn, self.cqueue)
def __init__(self, nick): self.player = player.Player(nick=nick) self.controller = controller.ClientController(self.player) self.handgui = hand.HandGUI(self.player.hand) camera.setPos(0, -20, 0) self.accept("turn_time_changed", self.update_turn_time) self.turn_timer = TurnTimer() # Mouse detection: base.cTrav = CollisionTraverser() self.mouse_ray_handler = CollisionHandlerQueue() mouse_ray_node = CollisionNode('mouse_ray') mouse_ray_np = camera.attachNewNode(mouse_ray_node) mouse_ray_node.setFromCollideMask(GeomNode.getDefaultCollideMask()) mouse_ray_node.setIntoCollideMask(0) self.mouse_ray = CollisionRay() mouse_ray_node.addSolid(self.mouse_ray) base.cTrav.addCollider(mouse_ray_np, self.mouse_ray_handler) self.mouse_overed_entry = None self.accept("mouse_enter", self.enlarge_entry) self.accept("mouse_leave", self.shrink_entry) self.accept("p-up", self.change_card_picture) taskMgr.doMethodLater(0.1, self.check_mouse_over, "check_mouse_over")
def __init__(self): #selection detection self.picker = CollisionTraverser() self.pq = CollisionHandlerQueue() self.pickerNode = CollisionNode('mouseRay') self.pickerNP = camera.attachNewNode(self.pickerNode) #self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) #TODO WOW geometry collision is SUPER slow... self.pickerNode.setFromCollideMask(BitMask32.bit(BITMASK_COLL_CLICK)) #render.find('**selectable').node().setIntoCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.picker.addCollider(self.pickerNP, self.pq) #self.picker.showCollisions(render) #box selection detection HINT: start with drawing the 2d thing yo! self.__shift__ = False self.accept("shift", self.shiftOn) self.accept("shift-up", self.shiftOff) self.__ctrl__ = False self.accept("control", self.ctrlOn) self.accept("control-up", self.ctrlOff) #mouse handling self.accept("mouse1", self.clickHandler) self.accept("shift-mouse1", self.clickHandler) self.accept("mouse1-up", self.releaseHandler) #dragging self.dragTask = taskMgr.add(self.dragTask, 'dragTask')
def __init__(self, parent=None, pitch=None, id=None): NetEnt.__init__(self, id) self.node = NetNodePath(PandaNode('projectile')) if parent: self.parent = parent self.node.setPos(parent.node.getPos() + (0,0,1)) self.node.setHpr(parent.node.getHpr()) self.node.setP(pitch) self.node.reparentTo(render) ProjectilePool.add(self) #print 'there are',len(ProjectilePool.values()),'projectiles' self.flyTime = 0 self.sprite = Sprite2d('resources/missile.png', rows=3, cols=1, rowPerFace=(0,1,2,1), anchorY=Sprite2d.ALIGN_CENTER) self.sprite.node.reparentTo(self.node) # set up 'from' collisions - for detecting projectile hitting things self.collisionHandler = CollisionHandlerQueue() self.fromCollider = self.node.attachNewNode(CollisionNode('fromCollider')) self.fromCollider.node().addSolid(CollisionRay(0,0,0,0,1,0)) self.fromCollider.node().setIntoCollideMask(BITMASK_EMPTY) self.fromCollider.node().setFromCollideMask(BITMASK_TERRAIN | BITMASK_CHARACTER) if SHOW_COLLISIONS: self.fromCollider.show() Character.collisionTraverser.addCollider(self.fromCollider,self.collisionHandler)
def placeItem(self, item): # Add ground collision detector to the health item self.collectGroundRay = CollisionRay() self.collectGroundRay.setOrigin(0,0,300) self.collectGroundRay.setDirection(0,0,-1) self.collectGroundCol = CollisionNode('colRay') self.collectGroundCol.addSolid(self.collectGroundRay) self.collectGroundCol.setFromCollideMask(BitMask32.bit(0)) self.collectGroundCol.setIntoCollideMask(BitMask32.allOff()) self.collectGroundColNp = item.attachNewNode(self.collectGroundCol) self.collectGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.collectGroundColNp, self.collectGroundHandler) placed = False; while placed == False: # re-randomize position item.setPos(-random.randint(0,140),-random.randint(0,40),0) base.cTrav.traverse(render) # Get Z position from terrain collision entries = [] for j in range(self.collectGroundHandler.getNumEntries()): entry = self.collectGroundHandler.getEntry(j) entries.append(entry) entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"): item.setZ(entries[0].getSurfacePoint(render).getZ()+1) placed = True # remove placement collider self.collectGroundColNp.removeNode()
def __init__(self,gmap,gaming_zone): DirectObject.__init__(self) #gaming zone (used for mouse movement), as a tools.Rectangle self.gaming_zone=gaming_zone #actual camera node self.p3dcam=base.camera #what the cam is oriented to self._target=base.render.attachNewNode('GaminCam.target') #range=[0,1] between min and max closeness to ground self.level=.7 # #keys_down acts as a pool containing keys (+mouse buttons) currently down self.keys_down=[] update_list.append(self.update) #setup for mouse picking picker_node=CollisionNode('gcam_to_mouse_ray')#general collision node picker_node.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.picker_ray=CollisionRay()#solid ray to attach to coll node picker_node.addSolid(self.picker_ray) self.picker_np=self.p3dcam.attachNewNode(picker_node)#attach this node to gcam self.collision_queue=CollisionHandlerQueue()#stores collisions self.collision_traverser=CollisionTraverser('gcam_traverser')#actual computer self.collision_traverser.addCollider(self.picker_np,self.collision_queue) base.cTrav=self.collision_traverser self.gmap=gmap #stack of states (state=pos+zoom) self.states_stack=[] #enable the cam to move according to keyboard and mouse self.move_enabled=True
def __init__(self, cr): DistributedObject.__init__(self, cr) #self.model = loader.loadModel('environment') #self.model.setZ(0) #self.builder = Builder(self, "map.txt", "development") plane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) cnode = CollisionNode('cnode') cnode.setIntoCollideMask(BitMask32.bit(1)) cnode.setFromCollideMask(BitMask32.bit(1)) cnode.addSolid(plane) self.planeNP = self.model.attachNewNode(cnode) self.planeNP.show() # Setup a traverser for the picking collisions self.picker = CollisionTraverser() # Setup mouse ray self.pq = CollisionHandlerQueue() # Create a collision Node pickerNode = CollisionNode('MouseRay') # set the nodes collision bitmask pickerNode.setFromCollideMask(BitMask32.bit(1)) # create a collision ray self.pickerRay = CollisionRay() # add the ray as a solid to the picker node pickerNode.addSolid(self.pickerRay) # create a nodepath with the camera to the picker node self.pickerNP = base.camera.attachNewNode(pickerNode) # add the nodepath to the base traverser self.picker.addCollider(self.pickerNP, self.pq) print "model loaded" #TODO: check how to load multiple levels and set players in specific levels! self.accept("mouse1", self.mouseClick)
class EntityCollision: def __init__(self, entity): self.entity = entity self.setup_collision() self.queue = CollisionHandlerQueue() self.traverser = CollisionTraverser('Collision Traverser') self.traverser.showCollisions(render) self.traverser.add_collider(self.target_nodepath, self.queue) base.taskMgr.add(self.collide, "Collision Task") def setup_collision(self): self.target = CollisionSphere(0, 0, 0, 1) self.target_node = CollisionNode('collision_entity') self.target_node.setFromCollideMask(ALLIES) # unused self.target_node.setIntoCollideMask(ENEMIES) self.target_nodepath = self.entity.model.attach_new_node(self.target_node) self.target_nodepath.node().addSolid(self.target) self.target_nodepath.show() def collide(self, task): self.traverser.traverse(render) for entry in self.queue.get_entries(): # print("Entity:") pos = entry.getSurfacePoint(self.entity.model) pos_x = pos[0] pos_z = pos[2] self.entity.spawn_particles(pos_x, pos_z) self.entity.life -= 1 return task.cont
class ShipCollision: def __init__(self, ship): self.ship = ship self.setup_collision() self.queue = CollisionHandlerQueue() self.traverser = CollisionTraverser('Collision Traverser') self.traverser.showCollisions(render) self.traverser.add_collider(self.target_nodepath, self.queue) base.taskMgr.add(self.collide, "Collision Task") def setup_collision(self): self.target = CollisionSphere(0, 0, 0, 0.5) self.target_node = CollisionNode('collision_ship') self.target_node.setFromCollideMask(ENEMIES) self.target_node.setIntoCollideMask(ALLIES) self.target_nodepath = self.ship.model.attach_new_node(self.target_node) self.target_nodepath.node().addSolid(self.target) #self.target_nodepath.show() def collide(self, task): self.traverser.traverse(render) for entry in self.queue.get_entries(): #print("Ship:") #print(entry) self.ship.model.cleanup() self.ship.model.removeNode() return task.cont
def __init__(self): self.initialize() self.WALLS = self.MAZE.find("**/Wall.004") self.WALLS.node().setIntoCollideMask(BitMask32.bit(0)) # collision with the ground. different bit mask #self.mazeGround = self.maze.find("**/ground_collide") #self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) self.MAZEGROUND = self.MAZE.find("**/Cube.004") self.MAZEGROUND.node().setIntoCollideMask(BitMask32.bit(1)) # add collision to the rock cs = CollisionSphere(0, 0, 0, 0.5) self.cnodePath = self.rock.attachNewNode(CollisionNode('cnode')) self.cnodePath.node().addSolid(cs) self.cnodePath.show() self.cnodePath.node().setIntoCollideMask(BitMask32.bit(0)) # load the ball and attach it to the scene. # it is on a dummy node so that we can rotate the ball # without rotating the ray that will be attached to it # CollisionTraversers calculate collisions self.cTrav = CollisionTraverser() #self.cTrav.showCollisions(render) #self.cTrav.showCollisions(render) # A list collision handler queue self.cHandler = CollisionHandlerQueue() # add collision nodes to the traverse. # maximum nodes per traverser: 32 self.cTrav.addCollider(self.ballSphere,self.cHandler) self.cTrav.addCollider(self.ballGroundColNp,self.cHandler) self.cTrav.addCollider(self.cnodePath, self.cHandler) # collision traversers have a built-in tool to visualize collisons #self.cTrav.showCollisions(render) self.start()
def __init__(self): self.pNode = render.attachNewNode('playerRoot') # The root node of the player self.eyeHeight = 1.5 # The z height of the camera self.selectedBlock = 0 self.adjacentBlock = 0 self.selectedPlayer = None self.playerState = PlayerState(self) self.inputBuffer = InputBuffer() self.currentItem = None self.itemModels = {} self.playerModel = None # The bounding box of the player for collision with environment geometry self.boundingBoxCenterNode = self.pNode.attachNewNode('bboxCenter') self.boundingBoxCenterNode.setPos(0, 0, 0.9) self.boundingBox = BoundingBox(self.boundingBoxCenterNode, [0.2, 0.2, 0.9]) self.animFSM = PlayerAnimationFSM(self) self.animFSM.request('Idle') self.camNode = self.pNode.attachNewNode('cam') # The position of the player's eyes self.camNode.setPos(0, 0, self.eyeHeight) self.playerParent = self.pNode.attachNewNode('playerParent') # Change this back so items follow player turning #self.itemNode = self.playerParent.attachNewNode('3rdPersonItem') self.itemNode = self.pNode.attachNewNode('3rdPersonItem') self.itemNode.setPos(0, 0, 1.2) self.camItemNode = self.camNode.attachNewNode('1stPersonItem') # Node for name text self.nameText = None self.nameNode = self.pNode.attachNewNode('NameNode') self.nameNode.setPos(0, 0, 1.97) self.lookingRayNode = self.pNode.attachNewNode('lookingRayNode') self.lookingRayNode.setPos(0, 0, self.eyeHeight) lookingSeg = CollisionSegment(0, 0, 0, 0, 100, 0) self.lookingRay = self.lookingRayNode.attachNewNode(CollisionNode('lookingRay')) self.lookingRay.node().addSolid(lookingSeg) self.lookingRay.node().setFromCollideMask(Globals.BLOCK_PICKER_BITMASK | Globals.PLAYER_BITMASK) self.lookingRay.node().setIntoCollideMask(BitMask32.allOff()) self.lookingRayCollisionEntry = None self.pickerCollisionHandler = CollisionHandlerQueue() self.pickerTraverser = CollisionTraverser('pickerTraverser') self.pickerTraverser.addCollider(self.lookingRay, self.pickerCollisionHandler) if(not Settings.IS_SERVER): self.selectionGeom = SelectionGeom() else: self.selectionGeom = None self.CreateCollisionGeoms() self.LoadModels()
def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) self.orbCollisionHandler = CollisionHandlerQueue() self.cTrav = CollisionTraverser() #hbPath = NodePath() utilsKristina.HealthBar() utilsKristina.setUpKeys(self) utilsKristina.loadModels(self) utilsKristina.setUpLighting(self) utilsKristina.setUpFloatingSpheres(self) utilsKristina.setUpRalphsShot(self) utilsKristina.setUpCamera(self) utilsKristina.setUpCollisionSpheres(self) self.healthTxt = utilsKristina.addInstructions(.06,"Health: 100") self.orbTxt = utilsKristina.addInstructions(.18,"Orbs: 0") self.vec = LVector3(0,1,0)#vector for pawns shot # Create a frame #frame = DirectFrame(text = "main", scale = 0.001) # Add button #bar = DirectWaitBar(text = "", value = 50, pos = (0,.4,.4)) #bar.reparent(render) # Game state variables self.isMoving = False self.jumping = False self.vz = 0 self.numOrbs = 0 self.healthCount = 100 #self.shotList = [] taskMgr.add(self.move, "moveTask") #taskMgr.add(utils2.moveChris,"moveChrisTask") self.sphere = CollisionSphere(0,0,4,2) self.sphere2 = CollisionSphere(0,0,2,2) self.cnodePath = self.ralph.attachNewNode((CollisionNode('ralphColNode'))) self.cnodePath.node().addSolid(self.sphere) self.cnodePath.node().addSolid(self.sphere2) #self.cnodePath.show() self.pusher = CollisionHandlerPusher() self.pusher.addCollider(self.cnodePath, self.ralph) #self.cTrav.addCollider(self.cnodePath, self.ralphCollisionHandler) self.cTrav.addCollider(self.cnodePath, self.pusher) # Uncomment this line to show a visual representation of the # collisions occuring self.cTrav.showCollisions(render) self.chrisLastShotTime = globalClock.getFrameTime() self.chrisTimer = globalClock.getDt()
def get_cell(self, pos): """Given a position, return the nearest cell below that position. If no cell is found, returns None.""" self.ray.setOrigin(pos) queue = CollisionHandlerQueue() self.traverser.addCollider(self.ray_nodepath, queue) self.traverser.traverse(self.cell_picker_world) self.traverser.removeCollider(self.ray_nodepath) queue.sortEntries() if not queue.getNumEntries(): return None entry = queue.getEntry(0) cnode = entry.getIntoNode() try: return self.cells_by_collider[cnode] except KeyError: raise Warning('collision ray collided with something ' 'other than a cell: %s' % cnode)
def loadCursorPicker(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)
class Colisiones: def __init__(self, energy, jeep): self.bebidas = 0 self.energy = energy self.crash = [] self.jeep = jeep """ ---------------------- Prepara las Colisiones ---------------------- """ self.cs = CollisionSphere(0, 0, 0, 20) cont = 0 while( cont < 80 ): self.crash.append( self.energy[cont].attachNewNode(CollisionNode(str(cont))) ) self.crash[cont].node().addSolid(self.cs) #self.crash[cont].show() Uncomment this line to see the colisions cont = cont + 1 self.css = CollisionSphere(0, 0, 0, 12) self.cnodePath = self.jeep.attachNewNode(CollisionNode('cnode')) self.cnodePath.node().addSolid(self.css) #self.cnodePath.show() Uncomment this line to see the colisions self.traverser = CollisionTraverser() self.queue = CollisionHandlerQueue() """ --------------------------------------------------------------------- """ taskMgr.add(self.choque, "choque") def choque(self, task): self.traverser.addCollider(self.cnodePath, self.queue) self.traverser.traverse(render) for i in range(self.queue.getNumEntries()): entry = self.queue.getEntry(i) self.energy[int( entry.getIntoNode().getName() )].setPos(0,0,5000) self.bebidas = self.bebidas + 1 global texta texta.destroy() texta = addText( 0.9, -1.2, "Hasta Ahora LLevamos " + str(self.bebidas) + " Bebidas", 0.07 ) return Task.cont
def __init__(self, ship): self.ship = ship self.setup_collision() self.queue = CollisionHandlerQueue() self.traverser = CollisionTraverser('Collision Traverser') self.traverser.showCollisions(render) self.traverser.add_collider(self.target_nodepath, self.queue) base.taskMgr.add(self.collide, "Collision Task")
def setupPicker(self): self.pickerTrav = CollisionTraverser('LT.pickerTrav') self.pickerRay = CollisionRay() rayNode = CollisionNode('LT.pickerNode') rayNode.addSolid(self.pickerRay) rayNode.setCollideMask(BitMask32(0)) rayNode.setFromCollideMask(CIGlobals.WallBitmask) self.pickerRayNode = base.camera.attachNewNode(rayNode) self.pickerHandler = CollisionHandlerQueue() self.pickerTrav.addCollider(self.pickerRayNode, self.pickerHandler)
def __init__(self, name, root, route, mass, movforce, maxforce): AICharacter.__init__(self, name, root, mass, movforce, maxforce) self.state = Hooded.STATE_PATROL self.initTimer = True self.attackTimer = True # we create a spotlight that will be the sentinel's eye and will be used to fire the inView method self.slight = Spotlight('slight') self.slight.setColor((1, 1, 1, 1)) lens = PerspectiveLens() lens.setNear(0.1) lens.setFar(Hooded.SIGHT) lens.setFov(Hooded.FOV) self.slight.setLens(lens) self.slnp = self.get_node_path().attachNewNode(self.slight) #TODO: Substitute for a collision polygon, so that the player class alerts an enemy of its presence #self.slight.showFrustum() self.slnp.setH(self.slnp.getH()-180) self.slnp.setPos(0, 0, Hooded.HEIGHT) self.hearing = 5.0 self.dynamicObstacles = [] self.detected = False self.pathfinding = False self.lostTarget = False self.countTime = False self.goingBack = False self.heard = False self.isProtected = False self.attacked = False self.started = False self.sentinelHandler = CollisionHandlerQueue() #TODO: Intruders should be added via an external method self.intruders = [] # this is important: as we said the inView method don't cull geometry but take everything is in sight frustum - therefore to simulate an hide and seek feature we gotta cheat a little: this ray is masked to collide with walls and so if the avatar is behind a wall the ray will be 'deflected' (we'll see how later in the sent_traverse function) - so we know who's behind a wall but we fake we can't see it. sentraygeom = CollisionSegment(0, 0, Hooded.HEIGHT, 0, Hooded.SIGHT, Hooded.HEIGHT) sentinelRay = self.get_node_path().attachNewNode(CollisionNode('sentinelray')) sentinelRay.node().addSolid(sentraygeom) # we set to the ray a cumulative masking using the or operator to detect either the avatar's body and the wall geometry sentinelRay.node().setFromCollideMask(CollisionMask.PLAYER) sentinelRay.node().setIntoCollideMask(CollisionMask.NONE) # we add the ray to the sentinel collider and now it is ready to go base.cTrav.addCollider(sentinelRay, self.sentinelHandler) self.screechsound = loader.loadSfx("assets/sounds/enemies/nazgul_scream.mp3") self.setPatrolPos(route)
def __init__(self): self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0 } self.separators = [] self.crash = [] self.statua = [] self.lamp = [] self.terrain = [] self.bombero = [] self.energy = [] self.balloons = [] self.buildings = [ loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss") ] self.angleDegrees = 0 self.isMoving = False self.isCollision = False self.mayor = 190.0 self.bebidas = 0 self.idStop = 0 self.textIni = 0 self.Perdio = 0 self.sonidito = 0 self.activate = 0 base.disableMouse() base.camera.setZ(base.camera, 3 * globalClock.getDt()) # Initialization CameraZ base.camera.setY(base.camera, -10 * globalClock.getDt()) # Initialization CameraY """self.Lvl1 = base.loader.loadSfx("tales.mp3") self.Lvl1.setLoop(True) self.Lvl1.setVolume(0.0) self.Lvl1.play()""" self.Lvl2 = base.loader.loadSfx("vel3.wav") self.Lvl2.setLoop(True) self.Lvl2.setVolume(0.6) self.Lvl4 = base.loader.loadSfx("instru.wav") self.Lvl4.setLoop(False) self.Lvl4.setVolume(1.0) self.punch = base.loader.loadSfx("punch.mp3") self.punch.setVolume(1.0) """ ---------------------------- Load the World ------------------------ """ # this section of rendering will be extract in one class extern the wich # instace a segment of world acord to the position of the character. cont = 0 while (cont < 79): self.terrain.append(loader.loadModel("modelos/pista/calle")) self.terrain[cont].reparentTo(render) self.terrain[cont].setScale(25) self.terrain[cont].setPos(-85, 130 + (308 * cont), -69) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Buildings ------------------------ """ # Load all buildings in the Game for segments the last two of each part # Are diferents. PD. each part have 3 segments and each segment have # 5 buildings. cont = 0 conta = -1 while (cont < 200): self.buildings[cont].reparentTo(render) conta = conta + 1 if (conta == 4): self.buildings[cont].setScale(3.5) self.buildings[cont].setPos(-68, 380 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(90.0) conta = -1 if (conta == 3): self.buildings[cont].setScale(.8) self.buildings[cont].setPos(32, 338 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(180.0) if (conta == 2): self.buildings[cont].setScale(.2) self.buildings[cont].setPos(80, 295 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(90.0) if (conta == 1): self.buildings[cont].setScale(.2) self.buildings[cont].setPos(-85, 295 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(270.0) if (conta == 0): self.buildings[cont].setScale(.5) self.buildings[cont].setPos(-34, 260 + ((308 * ((cont) / 5) * 2)), -8) cont = cont + 1 cont = 1 while (cont < 14): self.buildings[(cont * 15) - 2].setScale(5.2) self.buildings[(cont * 15) - 2].setPos( 96, 375 + (cont * (308 * 4)) + 13, -8) self.buildings[(cont * 15) - 2].setH(180.0) self.buildings[(15 * cont) - 1].setScale(3.2) self.buildings[(15 * cont) - 1].setPos( -85, 380 + (cont * (308 * 4)) + 8, -8) self.buildings[(15 * cont) - 1].setH(180.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Separators ----------------------- """ # Charge the Models of the separators between two segments of terrain only # only charge 8 and move the first 4 in the time. cont = 0 ident = -1 while (cont < 16): self.separators.append( loader.loadModel("modelos/separador/roadblock")) self.separators[cont].reparentTo(render) self.separators[cont].setScale(1.0) self.separators[cont].setH(90.0) posi = (308 * int(cont / 8)) ident = ident + 1 if (ident == 0): self.separators[cont].setPos(37, posi + 137, -8) if (ident == 1): self.separators[cont].setPos(37, posi + 152, -8) if (ident == 2): self.separators[cont].setPos(37, posi + 167, -8) if (ident == 3): self.separators[cont].setPos(37, posi + 182, -8) if (ident == 4): self.separators[cont].setPos(-38, posi + 137, -8) if (ident == 5): self.separators[cont].setPos(-38, posi + 152, -8) if (ident == 6): self.separators[cont].setPos(-38, posi + 167, -8) if (ident == 7): self.separators[cont].setPos(-38, posi + 182, -8) ident = -1 cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Objects ------------------------- """ # Charge the estatuas , lamparas , hidrantes, etc in the world. cont = 0 while (cont < 50): self.statua.append(loader.loadModel("modelos/estatua/estatua")) self.lamp.append(loader.loadModel("modelos/lampara/lampara")) self.statua[cont].reparentTo(render) self.lamp[cont].reparentTo(render) self.statua[cont].setScale(4.0) self.lamp[cont].setScale(4.0) self.statua[cont].setPos(-38, 95 + (308 * (cont * 2)), -8) self.lamp[cont].setPos(-38, 115 + (308 * (cont * 2)), -8) self.statua[cont].setH(270.0) self.lamp[cont].setH(270.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Energy --------------------------- """ # Charge models of the energy bottle. cont = 0 while (cont < 200): self.energy.append(loader.loadModel("modelos/energia/energia")) cont = cont + 1 """ --------------------------------------------------------------------- """ """ -------------------- Load The Principal Actor ---------------------- """ # It's the Actor In the Game. self.jeep = Actor("modelos/jeep/jeep", {"walk": "modelos/jeep/jeep-start"}) self.jeep.setScale(0.7) self.jeep.setPos(0, 30, -6.8) self.jeep.reparentTo(render) self.jeep.setH(180.0) """ --------------------------------------------------------------------- """ """ -------------------- Load The Secondary Actor ---------------------- """ # This actor is the narrator of the game. """self.broman = Actor( "modelos/tutman/bullyactormodel", {"ani": "modelos/tutman/bullyactoranimpieceofcrap", "ani2": "modelos/tutman/bullyactoranimnoneofthese", "ani3": "modelos/tutman/bullyactoranimfoodstamps", "ani4": "modelos/tutman/bullyactoranimbeatme"}) self.broman.setScale(15.0) self.broman.setPos(0,100,1.0) self.broman.reparentTo(render) # Loop its animation. self.broman.loop("ani2") self.broman.setH( 90.0 )""" """ --------------------------------------------------------------------- """ """ -------------------- Load The Secondary Actor ---------------------- """ # These are children who run for the sidewalk cont = 1 posIni = -3400 while (cont < 40): self.bombero.append( Actor( "modelos/bombero/bombero", { "ani": "modelos/bombero/bombero1", "ani2": "modelos/bombero/bombero2", "ani3": "modelos/bombero/bombero3" })) self.bombero[cont - 1].reparentTo(render) self.bombero[cont - 1].setScale(1.0) if ((cont % 2) == 0): self.bombero[cont - 1].setPos(-26, posIni, -7.0) else: self.bombero[cont - 1].setPos(24, posIni, -7.0) self.bombero[cont - 1].loop("ani2") self.bombero[cont - 1].setH(180.0) posIni = posIni + 600 cont = cont + 1 """ --------------------------------------------------------------------- """ """ -------------------- Load The Secondary Actor ---------------------- """ # These are children who have balloons. cont = 0 while (cont < 50): self.balloons.append( Actor("modelos/nino/nino", {"ani": "modelos/nino/nino2"})) self.balloons[cont].reparentTo(render) self.balloons[cont].setScale(.05) self.balloons[cont].setPos(30, 100 + (308 * (cont * 2)), 3.0) self.balloons[cont].loop("ani") self.balloons[cont].setH(270.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ------------------ Load posicions of the bottles ------------------- """ cont = 0 while (cont < 80): x = random.randint(-26, 26) y = random.randint(0, 24090) self.energy[cont].reparentTo(render) self.energy[cont].setScale(.5) self.energy[cont].setPos(x, y, 0) self.energy[cont].setH(270.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------- Prepara las Colisiones ---------------------- """ self.cs = CollisionSphere(0, 0, 0, 15) cont = 0 while (cont < 80): self.crash.append(self.energy[cont].attachNewNode( CollisionNode(str(cont)))) self.crash[cont].node().addSolid(self.cs) #self.crash[cont].show() cont = cont + 1 self.css = CollisionSphere(0, 0, 0, 12) self.cnodePath = self.jeep.attachNewNode(CollisionNode('cnode')) self.cnodePath.node().addSolid(self.css) #self.cnodePath.show() #self.cnodePath.show() self.traverser = CollisionTraverser() self.queue = CollisionHandlerQueue() """ --------------------------------------------------------------------- """ """ ----------------- when do you pressed one key ---------------------- """ self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_right", self.setKey, ["right", 1]) self.accept("arrow_up", self.setKey, ["forward", 1]) self.accept("a", self.setKey, ["cam-left", 1]) self.accept("s", self.setKey, ["cam-right", 1]) self.accept("r", self.setKey, ["look-back", 1]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_right-up", self.setKey, ["right", 0]) self.accept("arrow_up-up", self.setKey, ["forward", 0]) self.accept("a-up", self.setKey, ["cam-left", 0]) self.accept("s-up", self.setKey, ["cam-right", 0]) """ --------------------------------------------------------------------- """ taskMgr.add(self.move, "move") taskMgr.add(self.follow, "follow") taskMgr.add(self.stopSignal, "stopSignal") taskMgr.add(self.runBombero, "runBombero") taskMgr.add(self.collision, "collision")
def intersects(self, traverse_target=scene, ignore=(), debug=False): if not self.collision or not self.collider: return False from ursina.hit_info import HitInfo from ursina import distance if not hasattr(self, '_picker'): from panda3d.core import CollisionTraverser, CollisionNode, CollisionHandlerQueue from panda3d.core import CollisionRay, CollisionSegment, CollisionBox self._picker = CollisionTraverser() # Make a traverser self._pq = CollisionHandlerQueue() # Make a handler self._pickerNode = CollisionNode('raycaster') self._pickerNode.set_into_collide_mask(0) self._pickerNP = self.attach_new_node(self._pickerNode) self._picker.addCollider(self._pickerNP, self._pq) self._pickerNP.show() self._pickerNode.addSolid(self._collider.shape) if debug: self._pickerNP.show() else: self._pickerNP.hide() self._picker.traverse(traverse_target) if self._pq.get_num_entries() == 0: self.hit = HitInfo(hit=False) return self.hit ignore = (self, ) ignore += tuple([e for e in scene.entities if not e.collision]) self._pq.sort_entries() self.entries = [ # filter out ignored entities e for e in self._pq.getEntries() if e.get_into_node_path().parent not in ignore ] if len(self.entries) == 0: self.hit = HitInfo(hit=False) return self.hit collision = self.entries[0] nP = collision.get_into_node_path().parent point = collision.get_surface_point(nP) point = Vec3(*point) world_point = collision.get_surface_point(render) world_point = Vec3(*world_point) hit_dist = distance(self.world_position, world_point) if nP.name.endswith('.egg'): nP = nP.parent self.hit = HitInfo(hit=True) for e in scene.entities: if e == nP: self.hit.entity = e self.hit.point = point self.hit.world_point = world_point self.hit.distance = hit_dist normal = collision.get_surface_normal( collision.get_into_node_path().parent) self.hit.normal = Vec3(*normal) normal = collision.get_surface_normal(render) self.hit.world_normal = Vec3(*normal) return self.hit self.hit = HitInfo(hit=False) return self.hit
def __init__(self): ShowBase.__init__(self) self.disableMouse() camera.setPosHpr(0, -12, 8, 0, -35, 0) """ self.environ = self.loader.loadModel("models/environment") # Reparent the model to render. self.environ.reparentTo(self.render) # Apply scale and position transforms on the model. self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0) self.torus = loader.loadModel("torus.egg") self.torus.reparentTo(self.render) self.torus.setPos(circPos(0,1)) self.torus.setColor(BLACK) self.torus.setScale(0.5,0.5,0.5) """ self.setupLights() self.ended = False self.currentB = False self.firstTurn = True # Since we are using collision detection to do picking, we set it up like # any other collision detection system with a traverser and a handler self.picker = CollisionTraverser() # Make a traverser self.pq = CollisionHandlerQueue() # Make a handler # Make a collision node for our picker ray self.pickerNode = CollisionNode('mouseRay') # Attach that node to the camera since the ray will need to be positioned # relative to it self.pickerNP = camera.attachNewNode(self.pickerNode) # Everything to be picked will use bit 1. This way if we were doing other # collision we could seperate it self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() # Make our ray # Add it to the collision node self.pickerNode.addSolid(self.pickerRay) # Register the ray as something that can cause collisions self.picker.addCollider(self.pickerNP, self.pq) self.picker.showCollisions(render) self.whiteTurn = True # Now we create the chess board and its pieces # We will attach all of the squares to their own root. This way we can do the # collision pass just on the sqaures and save the time of checking the rest # of the scene self.batonsRoot = render.attachNewNode("batonsRoot") self.batons = [None for i in range(9)] self.torus = [[None for j in range(3)] for i in range(9)] self.org = [[[None for j in range(3)] for i in range(3)] for i in range(3)] for i in range(9): # Load, parent, color, and position the model (a single square # polygon) self.batons[i] = loader.loadModel("bois.egg") self.batons[i].reparentTo(self.batonsRoot) self.batons[i].setPos(circPos(i,0)) self.batons[i].setColor(0.75,0.5,0) self.batons[i].setScale(0.75,0.75,0.5) # Set the model itself to be collideable with the ray. If this model was # any more complex than a single polygon, you should set up a collision # sphere around it instead. But for single polygons this works # fine. self.batons[i].find("**/Cylinder").node().setIntoCollideMask( BitMask32.bit(1)) # Set a tag on the square's node so we can look up what square this is # later during the collision pass self.batons[i].find("**/Cylinder").setTag('baton', str(i)) # We will use this variable as a pointer to whatever piece is currently # in this square self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask') self.accept("mouse1", self.click) self.accept("w", self.bestPossibleMove)
class Raycaster(Entity): def __init__(self): super().__init__(name='raycaster', eternal=True) self._picker = CollisionTraverser() # Make a traverser self._pq = CollisionHandlerQueue() # Make a handler self._pickerNode = CollisionNode('raycaster') self._pickerNode.set_into_collide_mask(0) self._pickerNP = self.attach_new_node(self._pickerNode) self._picker.addCollider(self._pickerNP, self._pq) self._pickerNP.show() def distance(self, a, b): return math.sqrt(sum((a - b)**2 for a, b in zip(a, b))) def raycast(self, origin, direction=(0, 0, 1), distance=math.inf, traverse_target=scene, ignore=list(), debug=False): self.position = origin self.look_at(self.position + direction) self._pickerNode.clearSolids() # if thickness == (0,0): if distance == math.inf: ray = CollisionRay() ray.setOrigin(Vec3(0, 0, 0)) ray.setDirection(Vec3(0, 1, 0)) else: ray = CollisionSegment(Vec3(0, 0, 0), Vec3(0, distance, 0)) self._pickerNode.addSolid(ray) if debug: self._pickerNP.show() else: self._pickerNP.hide() self._picker.traverse(traverse_target) if self._pq.get_num_entries() == 0: self.hit = Hit(hit=False) return self.hit ignore += tuple([e for e in scene.entities if not e.collision]) self._pq.sort_entries() self.entries = [ # filter out ignored entities e for e in self._pq.getEntries() if e.get_into_node_path().parent not in ignore ] if len(self.entries) == 0: self.hit = Hit(hit=False) return self.hit self.collision = self.entries[0] nP = self.collision.get_into_node_path().parent point = self.collision.get_surface_point(nP) point = Vec3(point[0], point[2], point[1]) world_point = self.collision.get_surface_point(render) world_point = Vec3(world_point[0], world_point[2], world_point[1]) hit_dist = self.distance(self.world_position, world_point) if nP.name.endswith('.egg'): nP = nP.parent self.hit = Hit(hit=True) for e in scene.entities: if e == nP: # print('cast nP to Entity') self.hit.entity = e self.hit.point = point self.hit.world_point = world_point self.hit.distance = hit_dist normal = self.collision.get_surface_normal( self.collision.get_into_node_path().parent) self.hit.normal = (normal[0], normal[2], normal[1]) normal = self.collision.get_surface_normal(render) self.hit.world_normal = (normal[0], normal[2], normal[1]) return self.hit self.hit = Hit(hit=False) return self.hit def boxcast(self, origin, direction=(0, 0, 1), distance=math.inf, thickness=(1, 1), traverse_target=scene, ignore=list(), debug=False): if isinstance(thickness, (int, float, complex)): thickness = (thickness, thickness) resolution = 3 rays = list() debugs = list() for y in range(3): for x in range(3): pos = origin + Vec3( lerp(-(thickness[0] / 2), thickness[0] / 2, x / (3 - 1)), lerp(-(thickness[1] / 2), thickness[1] / 2, y / (3 - 1)), 0) ray = self.raycast(pos, direction, distance, traverse_target, ignore, False) rays.append(ray) if debug and ray.hit: d = Entity(model='cube', origin_z=-.5, position=pos, scale=(.02, .02, distance), ignore=True) d.look_at(pos + Vec3(direction)) debugs.append(d) # print(pos, hit.point) if ray.hit and ray.distance > 0: d.scale_z = ray.distance d.color = color.green from ursina import destroy # [destroy(e, 1/60) for e in debugs] rays.sort(key=lambda x: x.distance) closest = rays[0] return Hit( hit=sum([int(e.hit) for e in rays]) > 0, entity=closest.entity, point=closest.point, world_point=closest.world_point, distance=closest.distance, normal=closest.normal, world_normal=closest.world_normal, hits=[e.hit for e in rays], entities=list(set([e.entity for e in rays])), # get unique entities hit )
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 else: if 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) else: if 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
def intersects(self, traverse_target=scene, ignore=(), debug=False): if isinstance(self.collider, MeshCollider): raise Exception( '''error: mesh colliders can't intersect other shapes, only primitive shapes can. Mesh colliders can "recieve" collisions though.''' ) from ursina.hit_info import HitInfo if not self.collision or not self.collider: self.hit = HitInfo(hit=False) return self.hit from ursina import distance if not hasattr(self, '_picker'): from panda3d.core import CollisionTraverser, CollisionNode, CollisionHandlerQueue from panda3d.core import CollisionRay, CollisionSegment, CollisionBox self._picker = CollisionTraverser() # Make a traverser self._pq = CollisionHandlerQueue() # Make a handler self._pickerNode = CollisionNode('raycaster') self._pickerNode.set_into_collide_mask(0) self._pickerNP = self.attach_new_node(self._pickerNode) self._picker.addCollider(self._pickerNP, self._pq) self._pickerNP.show() self._pickerNode.addSolid(self._collider.shape) if debug: self._pickerNP.show() else: self._pickerNP.hide() self._picker.traverse(traverse_target) if self._pq.get_num_entries() == 0: self.hit = HitInfo(hit=False) return self.hit ignore += (self, ) ignore += tuple([e for e in scene.entities if not e.collision]) self._pq.sort_entries() self.entries = [ # filter out ignored entities e for e in self._pq.getEntries() if e.get_into_node_path().parent not in ignore ] if len(self.entries) == 0: self.hit = HitInfo(hit=False, distance=0) return self.hit collision = self.entries[0] nP = collision.get_into_node_path().parent point = collision.get_surface_point(nP) point = Vec3(*point) world_point = collision.get_surface_point(render) world_point = Vec3(*world_point) hit_dist = distance(self.world_position, world_point) self.hit = HitInfo(hit=True) self.hit.entity = next(e for e in scene.entities if e == nP) self.hit.point = point self.hit.world_point = world_point self.hit.distance = hit_dist normal = collision.get_surface_normal( collision.get_into_node_path().parent).normalized() self.hit.normal = Vec3(*normal) normal = collision.get_surface_normal(render).normalized() self.hit.world_normal = Vec3(*normal) self.hit.entities = [] for collision in self.entries: self.hit.entities.append( next(e for e in scene.entities if e == collision.get_into_node_path().parent)) return self.hit
class PositionExaminer(DirectObject, NodePath): def __init__(self): try: self.__initialized return except: self.__initialized = 1 NodePath.__init__(self, hidden.attachNewNode('PositionExaminer')) self.cRay = CollisionRay(0.0, 0.0, 6.0, 0.0, 0.0, -1.0) self.cRayNode = CollisionNode('cRayNode') self.cRayNode.addSolid(self.cRay) self.cRayNodePath = self.attachNewNode(self.cRayNode) self.cRayNodePath.hide() self.cRayBitMask = CIGlobals.FloorBitmask self.cRayNode.setFromCollideMask(self.cRayBitMask) self.cRayNode.setIntoCollideMask(BitMask32.allOff()) self.cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.5) self.cSphereNode = CollisionNode('cSphereNode') self.cSphereNode.addSolid(self.cSphere) self.cSphereNodePath = self.attachNewNode(self.cSphereNode) self.cSphereNodePath.hide() self.cSphereBitMask = CIGlobals.WallBitmask self.cSphereNode.setFromCollideMask(self.cSphereBitMask) self.cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.ccLine = CollisionSegment(0.0, 0.0, 0.0, 1.0, 0.0, 0.0) self.ccLineNode = CollisionNode('ccLineNode') self.ccLineNode.addSolid(self.ccLine) self.ccLineNodePath = self.attachNewNode(self.ccLineNode) self.ccLineNodePath.hide() self.ccLineBitMask = CIGlobals.CameraBitmask self.ccLineNode.setFromCollideMask(self.ccLineBitMask) self.ccLineNode.setIntoCollideMask(BitMask32.allOff()) self.cRayTrav = CollisionTraverser('PositionExaminer.cRayTrav') self.cRayTrav.setRespectPrevTransform(False) self.cRayQueue = CollisionHandlerQueue() self.cRayTrav.addCollider(self.cRayNodePath, self.cRayQueue) self.cSphereTrav = CollisionTraverser('PositionExaminer.cSphereTrav') self.cSphereTrav.setRespectPrevTransform(False) self.cSphereQueue = CollisionHandlerQueue() self.cSphereTrav.addCollider(self.cSphereNodePath, self.cSphereQueue) self.ccLineTrav = CollisionTraverser('PositionExaminer.ccLineTrav') self.ccLineTrav.setRespectPrevTransform(False) self.ccLineQueue = CollisionHandlerQueue() self.ccLineTrav.addCollider(self.ccLineNodePath, self.ccLineQueue) def delete(self): del self.cRay del self.cRayNode self.cRayNodePath.removeNode() del self.cRayNodePath del self.cSphere del self.cSphereNode self.cSphereNodePath.removeNode() del self.cSphereNodePath del self.ccLine del self.ccLineNode self.ccLineNodePath.removeNode() del self.ccLineNodePath del self.cRayTrav del self.cRayQueue del self.cSphereTrav del self.cSphereQueue del self.ccLineTrav del self.ccLineQueue def consider(self, node, pos, eyeHeight): self.reparentTo(node) self.setPos(pos) result = None self.cRayTrav.traverse(render) if self.cRayQueue.getNumEntries() != 0: self.cRayQueue.sortEntries() floorPoint = self.cRayQueue.getEntry(0).getSurfacePoint(self.cRayNodePath) if abs(floorPoint[2]) <= 4.0: pos += floorPoint self.setPos(pos) self.cSphereTrav.traverse(render) if self.cSphereQueue.getNumEntries() == 0: self.ccLine.setPointA(0, 0, eyeHeight) self.ccLine.setPointB(-pos[0], -pos[1], eyeHeight) self.ccLineTrav.traverse(render) if self.ccLineQueue.getNumEntries() == 0: result = pos self.reparentTo(hidden) self.cRayQueue.clearEntries() self.cSphereQueue.clearEntries() self.ccLineQueue.clearEntries() return result
def __init__(self, base): DirectObject.__init__(self) self.base = base self.lastUpdate = 0.0 # Parameters self.wheelBaseOffset = 3.4 self.wheelSideOffset = 3.1 self.speedMax = 50.0 self.steerAngleMax = 20.0 self.numSensors = 5 self.sensorHeight = 2.0 # Collisions self.collisionHandler = CollisionHandlerQueue() # Load car model self.car = self.base.loader.loadModel("models/carBody") self.car.reparentTo(self.base.render) self.wheelFrontLeft = self.base.loader.loadModel("models/carWheel") self.wheelFrontLeft.reparentTo(self.car) self.wheelFrontLeft.setX(self.wheelBaseOffset) self.wheelFrontLeft.setY(self.wheelSideOffset) self.wheelFrontRight = self.base.loader.loadModel("models/carWheel") self.wheelFrontRight.reparentTo(self.car) self.wheelFrontRight.setX(self.wheelBaseOffset) self.wheelFrontRight.setY(-self.wheelSideOffset) self.wheelBackLeft = self.base.loader.loadModel("models/carWheel") self.wheelBackLeft.reparentTo(self.car) self.wheelBackLeft.setX(-self.wheelBaseOffset) self.wheelBackLeft.setY(self.wheelSideOffset) self.wheelBackRight = self.base.loader.loadModel("models/carWheel") self.wheelBackRight.reparentTo(self.car) self.wheelBackRight.setX(-self.wheelBaseOffset) self.wheelBackRight.setY(-self.wheelSideOffset) # Car properties self.steerAngle = 0.0 self.speed = 0.0 self.wheelFront = Vec3(1.0, 0.0, 0.0) * self.wheelBaseOffset self.wheelBack = Vec3(-1.0, 0.0, 0.0) * self.wheelBaseOffset self.initSensors(self.numSensors, self.sensorHeight) # Controls self.arrowUpDown = False self.arrowLeftDown = False self.arrowRightDown = False self.accept("arrow_up", self.onUpArrow, [True]) self.accept("arrow_up-up", self.onUpArrow, [False]) self.accept("arrow_left", self.onLeftArrow, [True]) self.accept("arrow_left-up", self.onLeftArrow, [False]) self.accept("arrow_right", self.onRightArrow, [True]) self.accept("arrow_right-up", self.onRightArrow, [False]) self.base.taskMgr.add(self.updateCar, "UpdateCarTask") # DEBUG self.drawAxis(10) self.drawWheelBase()
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) # Create a traverser and a handler self.cTrav = CollisionTraverser() self.cQueue = CollisionHandlerQueue() # Create the collision node that will store the collision # ray solid self.pickerNode = CollisionNode('mouseRay') # Set bitmask for efficiency, only hit from objects with same mask self.pickerNode.setFromCollideMask(BitMask32.bit(1)) # Attach collision node to camera, since that is the source self.pickerNP = camera.attachNewNode(self.pickerNode) # Add collision solid(ray) to collision node self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) # Add collidable node(pickerNP) to the traverser # Collisions detected when traversed will go to cQueue self.cTrav.addCollider(self.pickerNP, self.cQueue) # Create visible sphere self.tmpSphere = self.loader.loadModel("models/misc/sphere") self.tmpSphere.reparentTo(self.render) self.tmpSphere.setColor(1, 1, 1, 1) self.tmpSphere.setPos(0, 100, 0) # Create collision sphere and attach to tmpSphere cSphere = CollisionSphere(0, 0, 0, 3) cnodePath = self.tmpSphere.attachNewNode(CollisionNode('cnode')) # Add collision solid(sphere) to collision node # Because tmpSphere/cSphere is child of render, which we traverse # later, it becomes a from collider automatically, we don't # need to addCollider since that is only for from collision nodes cnodePath.node().addSolid(cSphere) # Set bitmask to match the from collisionnode mask for efficiency cnodePath.setCollideMask(BitMask32.bit(1)) # Show the collision sphere visibly, for debugging. cnodePath.show() # Set a custom tag on the collision node which becomes available # inside the collision event stored in the collision handler cnodePath.setTag('someTag', '1') # Add task to run every frame - set collision solid(ray) # to start at the current camera position, self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask') def mouseTask(self, task): if self.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() # Set collision ray to start at camera lens and endpoint at mouse self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) # Perform the collision traverse - follows the ray and logs # all collisions to the handler set earlier self.cTrav.traverse(self.render) # Get info from entries and use them if self.cQueue.getNumEntries() > 0: self.cQueue.sortEntries() print("Collision!") entry = self.cQueue.getEntry(0) print(entry) someTag = int(entry.getIntoNode().getTag('someTag')) print(someTag) # Collision detected, mouse must be over sphere self.tmpSphere.setColor(0, 1, 0, 1) else: # No collisions, mouse is not over sphere, unset color # Not ideal to "unset" the color each frame self.tmpSphere.setColor(1, 1, 1, 1) return task.cont
class KeyboardController(DirectObject): def __init__(self, base): DirectObject.__init__(self) self.base = base self.lastUpdate = 0.0 # Parameters self.wheelBaseOffset = 3.4 self.wheelSideOffset = 3.1 self.speedMax = 50.0 self.steerAngleMax = 20.0 self.numSensors = 5 self.sensorHeight = 2.0 # Collisions self.collisionHandler = CollisionHandlerQueue() # Load car model self.car = self.base.loader.loadModel("models/carBody") self.car.reparentTo(self.base.render) self.wheelFrontLeft = self.base.loader.loadModel("models/carWheel") self.wheelFrontLeft.reparentTo(self.car) self.wheelFrontLeft.setX(self.wheelBaseOffset) self.wheelFrontLeft.setY(self.wheelSideOffset) self.wheelFrontRight = self.base.loader.loadModel("models/carWheel") self.wheelFrontRight.reparentTo(self.car) self.wheelFrontRight.setX(self.wheelBaseOffset) self.wheelFrontRight.setY(-self.wheelSideOffset) self.wheelBackLeft = self.base.loader.loadModel("models/carWheel") self.wheelBackLeft.reparentTo(self.car) self.wheelBackLeft.setX(-self.wheelBaseOffset) self.wheelBackLeft.setY(self.wheelSideOffset) self.wheelBackRight = self.base.loader.loadModel("models/carWheel") self.wheelBackRight.reparentTo(self.car) self.wheelBackRight.setX(-self.wheelBaseOffset) self.wheelBackRight.setY(-self.wheelSideOffset) # Car properties self.steerAngle = 0.0 self.speed = 0.0 self.wheelFront = Vec3(1.0, 0.0, 0.0) * self.wheelBaseOffset self.wheelBack = Vec3(-1.0, 0.0, 0.0) * self.wheelBaseOffset self.initSensors(self.numSensors, self.sensorHeight) # Controls self.arrowUpDown = False self.arrowLeftDown = False self.arrowRightDown = False self.accept("arrow_up", self.onUpArrow, [True]) self.accept("arrow_up-up", self.onUpArrow, [False]) self.accept("arrow_left", self.onLeftArrow, [True]) self.accept("arrow_left-up", self.onLeftArrow, [False]) self.accept("arrow_right", self.onRightArrow, [True]) self.accept("arrow_right-up", self.onRightArrow, [False]) self.base.taskMgr.add(self.updateCar, "UpdateCarTask") # DEBUG self.drawAxis(10) self.drawWheelBase() def initSensors(self, n, h): origin = Point3(0.0, 0.0, h) angles = [math.pi * t / (n - 1) for t in range(n)] sensors = [Vec3(math.sin(ang), math.cos(ang), h) for ang in angles] # Create collision nodes for sensors sensorNode = CollisionNode('sensor') sensorRay = CollisionRay(origin, Vec3(1.0, 0.0, 0.0)) sensorNode.addSolid(sensorRay) # Add collision node to car and handler sensorNodePath = self.car.attachNewNode(sensorNode) self.base.cTrav.addCollider(sensorNodePath, self.collisionHandler) self.base.taskMgr.add(self.checkCollisions, "CheckCollisionsTask") def checkCollisions(self, task): for entry in self.collisionHandler.getEntries(): pass return task.cont def getNodePath(self): return self.car def onUpArrow(self, down): self.arrowUpDown = down def onLeftArrow(self, down): self.arrowLeftDown = down def onRightArrow(self, down): self.arrowRightDown = down def degToRad(self, deg): return deg * (math.pi / 180.0) def radToDeg(self, rad): return rad * (180.0 / math.pi) def updateCar(self, task): # Register controls if self.arrowUpDown: self.speed = self.speedMax else: self.speed = 0.0 if self.arrowLeftDown and not self.arrowRightDown: self.steerAngle = self.steerAngleMax if self.arrowRightDown and not self.arrowLeftDown: self.steerAngle = -self.steerAngleMax if not self.arrowLeftDown and not self.arrowRightDown: self.steerAngle = 0.0 # Update car pose dt = task.time - self.lastUpdate self.lastUpdate = task.time wheelFrontUpdate = self.wheelFront + Vec3( math.cos(self.degToRad(self.steerAngle)), math.sin(self.degToRad(self.steerAngle)), 0.0) * self.speed * dt wheelBackUpdate = self.wheelBack + Vec3(1.0, 0.0, 0.0) * self.speed * dt positionLocalUpdate = (wheelFrontUpdate + wheelBackUpdate) / 2.0 headingLocalUpdate = math.atan2( wheelFrontUpdate.getY() - wheelBackUpdate.getY(), wheelFrontUpdate.getX() - wheelBackUpdate.getX()) self.car.setPos(self.car, positionLocalUpdate) self.car.setH(self.car, self.radToDeg(headingLocalUpdate)) self.wheelFrontLeft.setH(self.steerAngle) self.wheelFrontRight.setH(self.steerAngle) return task.cont def drawAxis(self, scale): axisSegs = LineSegs("axis") axisSegs.setThickness(5) axisSegs.setColor(1.0, 0.0, 0.0) axisSegs.moveTo(Point3(0.0, 0.0, 0.0)) axisSegs.drawTo(Point3(1.0, 0.0, 0.0) * scale) axisSegs.setColor(0.0, 1.0, 0.0) axisSegs.moveTo(Point3(0.0, 0.0, 0.0)) axisSegs.drawTo(Point3(0.0, 1.0, 0.0) * scale) axisSegs.setColor(0.0, 0.0, 1.0) axisSegs.moveTo(Point3(0.0, 0.0, 0.0)) axisSegs.drawTo(Point3(0.0, 0.0, 1.0) * scale) axisNode = axisSegs.create() axisNodePath = self.car.attachNewNode(axisNode) axisNodePath.setZ(axisNodePath, 1.0) return axisNodePath def drawWheelBase(self): wheelSegs = LineSegs("wheelBase") wheelSegs.setThickness(5) wheelSegs.moveTo(self.wheelFront + Vec3(0.0, 5.0, 1.44)) wheelSegs.drawTo(self.wheelFront + Vec3(0.0, -5.0, 1.44)) wheelSegs.moveTo(self.wheelBack + Vec3(0.0, 5.0, 1.44)) wheelSegs.drawTo(self.wheelBack + Vec3(0.0, -5.0, 1.44)) wheelNode = wheelSegs.create() wheelNodePath = self.car.attachNewNode(wheelNode) return wheelNodePath
def __init__(self, name='NONAME', id=None): NetEnt.__init__(self, id) self.node = NetNodePath(PandaNode('A Character')) self.node.setTag('ID', str(self.id)) if not id: self.spawn() self.node.reparentTo(render) CharacterPool.add(self) self.xVelocity = 0 self.yVelocity = 0 self.vertVelocity = None self.duck = False self.deltaT = 0 self.sprite = Sprite2d('resources/origsprite.png', rows=3, cols=8, rowPerFace=(0, 1, 2, 1)) self.sprite.createAnim('walk', (1, 0, 2, 0)) self.sprite.createAnim('kick', (5, 6, 7, 6, 5)) self.sprite.node.reparentTo(self.node) # set up character's name label self.nameNode = NodePath(TextNode('Char Name')) self.nameNode.node().setText(name) self.nameNode.node().setAlign(TextNode.ACenter) self.nameNode.node().setCardColor(0.2, 0.2, 0.2, 0.5) self.nameNode.node().setCardAsMargin(0, 0, 0, 0) self.nameNode.node().setCardDecal(True) self.nameNode.setZ(1.7) self.nameNode.setScale(0.2) self.nameNode.setBillboardAxis() self.nameNode.reparentTo(self.node) # collision self.collisionHandler = CollisionHandlerQueue() # set up 'from' collision - for detecting char hitting things self.fromCollider = self.node.attachNewNode( CollisionNode('fromCollider')) self.fromCollider.node().addSolid(CollisionRay(0, 0, 2, 0, 0, -1)) self.fromCollider.node().setIntoCollideMask(BITMASK_EMPTY) self.fromCollider.node().setFromCollideMask(BITMASK_TERRAIN) if SHOW_COLLISIONS: self.fromCollider.show() Character.collisionTraverser.addCollider(self.fromCollider, self.collisionHandler) # set up 'into' collision - for detecting things hitting char self.intoCollider = self.node.attachNewNode( CollisionNode('intoCollider')) self.intoCollider.node().addSolid( CollisionTube(0, 0, 0.5, 0, 0, 1, 0.5)) self.intoCollider.node().setIntoCollideMask(BITMASK_CHARACTER) self.intoCollider.node().setFromCollideMask(BITMASK_EMPTY) if SHOW_COLLISIONS: self.intoCollider.show() self.oldPosition = self.node.getPos() self.collisionZ = self.node.getZ() # set up weapons self.sinceShoot = 10 # speculated client history - used for input prediction self.posHistory = []
class Projectile(NetEnt): def __init__(self, parent=None, pitch=None, id=None): NetEnt.__init__(self, id) self.node = NetNodePath(PandaNode('projectile')) if parent: self.parent = parent self.node.setPos(parent.node.getPos() + (0, 0, 1)) self.node.setHpr(parent.node.getHpr()) self.node.setP(pitch) self.node.reparentTo(render) ProjectilePool.add(self) #print 'there are',len(ProjectilePool.values()),'projectiles' self.flyTime = 0 self.sprite = Sprite2d('resources/missile.png', rows=3, cols=1, rowPerFace=(0, 1, 2, 1), anchorY=Sprite2d.ALIGN_CENTER) self.sprite.node.reparentTo(self.node) # set up 'from' collisions - for detecting projectile hitting things self.collisionHandler = CollisionHandlerQueue() self.fromCollider = self.node.attachNewNode( CollisionNode('fromCollider')) self.fromCollider.node().addSolid(CollisionRay(0, 0, 0, 0, 1, 0)) self.fromCollider.node().setIntoCollideMask(BITMASK_EMPTY) self.fromCollider.node().setFromCollideMask(BITMASK_TERRAIN | BITMASK_CHARACTER) if SHOW_COLLISIONS: self.fromCollider.show() Character.collisionTraverser.addCollider(self.fromCollider, self.collisionHandler) def getState(self): dataDict = NetObj.getState(self) dataDict[0] = self.node.getState() return dataDict def setState(self, weightOld, dataDictOld, weightNew, dataDictNew): oldNode = None if not dataDictOld else dataDictOld.get(0, None) self.node.setState(weightOld, oldNode, weightNew, dataDictNew[0]) def movePostCollide(self, deltaT): desiredDistance = 30 * deltaT self.collisionHandler.sortEntries() ch = self.collisionHandler for e in [ch.getEntry(i) for i in range(ch.getNumEntries())]: collisionDist = (self.node.getPos() - e.getSurfacePoint(render)).length() if collisionDist > desiredDistance: break # only accept collisions that aren't with parent if e.getIntoNode().getParent(0).getTag('ID') != str( self.parent.id): return False self.node.setY(self.node, desiredDistance) self.flyTime += deltaT return self.flyTime < 4 def __del__(self): #print 'PROJECTILE BEING REMOVED' self.node.removeNode()
class World(ShowBase): def __init__(self): # Setup window size, title and so on load_prc_file_data("", """ win-size 1600 900 window-title Render Pipeline - Roaming Ralph Demo """) # ------ Begin of render pipeline code ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../../RenderPipeline/" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "7:40" # Use a special effect for rendering the scene, this is because the # roaming ralph model has no normals or valid materials self.render_pipeline.set_effect(render, "scene-effect.yaml", {}, sort=250) self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, "cam-right":0} self.speed = 1.0 base.win.setClearColor(Vec4(0,0,0,1)) # Post the instructions self.inst1 = addInstructions(0.95, "[ESC] Quit") self.inst4 = addInstructions(0.90, "[W] Run Ralph Forward") self.inst4 = addInstructions(0.85, "[S] Run Ralph Backward") self.inst2 = addInstructions(0.80, "[A] Rotate Ralph Left") self.inst3 = addInstructions(0.75, "[D] Rotate Ralph Right") self.inst6 = addInstructions(0.70, "[Left Arrow] Rotate Camera Left") self.inst7 = addInstructions(0.65, "[Right Arrow] Rotate Camera Right") # Set up the environment # # This environment model contains collision meshes. If you look # in the egg file, you will see the following: # # <Collide> { Polyset keep descend } # # This tag causes the following mesh to be converted to a collision # mesh -- a mesh which is optimized for collision, not rendering. # It also keeps the original mesh, so there are now two copies --- # one optimized for rendering, one for collisions. self.environ = loader.loadModel("resources/world") self.environ.reparentTo(render) self.environ.setPos(0,0,0) # Remove wall nodes self.environ.find("**/wall").remove_node() # Create the main character, Ralph self.ralph = Actor("resources/ralph", {"run":"resources/ralph-run", "walk":"resources/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(Vec3(-110.9, 29.4, 1.8)) # Create a floater object. We use the "floater" as a temporary # variable in a variety of calculations. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("a", self.setKey, ["left",1]) self.accept("d", self.setKey, ["right",1]) self.accept("w", self.setKey, ["forward",1]) self.accept("s", self.setKey, ["backward",1]) self.accept("arrow_left", self.setKey, ["cam-left",1]) self.accept("arrow_right", self.setKey, ["cam-right",1]) self.accept("a-up", self.setKey, ["left",0]) self.accept("d-up", self.setKey, ["right",0]) self.accept("w-up", self.setKey, ["forward",0]) self.accept("s-up", self.setKey, ["backward",0]) self.accept("arrow_left-up", self.setKey, ["cam-left",0]) self.accept("arrow_right-up", self.setKey, ["cam-right",0]) self.accept("=", self.adjustSpeed, [0.25]) self.accept("+", self.adjustSpeed, [0.25]) self.accept("-", self.adjustSpeed, [-0.25]) taskMgr.add(self.move,"moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX() + 10,self.ralph.getY() + 10, 2) base.camLens.setFov(80) # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above ralph's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0,0,1000) self.ralphGroundRay.setDirection(0,0,-1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0)) self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0,0,1000) self.camGroundRay.setDirection(0,0,-1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays #self.ralphGroundColNp.show() #self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(-5, -5, -5)) directionalLight.setColor(Vec4(1, 1, 1, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) #Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value # Adjust movement speed def adjustSpeed(self, delta): newSpeed = self.speed + delta if 0 <= newSpeed <= 3: self.speed = newSpeed # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"]!=0): base.camera.setX(base.camera, +20 * globalClock.getDt()) if (self.keyMap["cam-right"]!=0): base.camera.setX(base.camera, -20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) elif (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -25 * self.speed * globalClock.getDt()) elif (self.keyMap["backward"]!=0): self.ralph.setY(self.ralph, 25 * self.speed * globalClock.getDt()) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if (self.keyMap["forward"]!=0) or (self.keyMap["backward"]!=0) or \ (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk",5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) camdist = 5.0 # Now check for collisions. self.cTrav.traverse(render) # Adjust ralph's Z coordinate. If ralph's ray hit terrain, # update his Z. If it hit anything else, or didn't hit anything, put # him back where he was last frame. entries = [] for i in range(self.ralphGroundHandler.getNumEntries()): entry = self.ralphGroundHandler.getEntry(i) entries.append(entry) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"): self.ralph.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.ralph.setPos(startpos) # Keep the camera at one foot above the terrain, # or two feet above ralph, whichever is greater. entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class Draw(DirectObject): def __init__(self): self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0 } self.separators = [] self.crash = [] self.statua = [] self.lamp = [] self.terrain = [] self.bombero = [] self.energy = [] self.balloons = [] self.buildings = [ loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("modelos/building/building"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa7/dojo"), loader.loadModel("edificios/casas/casa12/funhouse"), loader.loadModel("edificios/casas/casa13/ringtoss") ] self.angleDegrees = 0 self.isMoving = False self.isCollision = False self.mayor = 190.0 self.bebidas = 0 self.idStop = 0 self.textIni = 0 self.Perdio = 0 self.sonidito = 0 self.activate = 0 base.disableMouse() base.camera.setZ(base.camera, 3 * globalClock.getDt()) # Initialization CameraZ base.camera.setY(base.camera, -10 * globalClock.getDt()) # Initialization CameraY """self.Lvl1 = base.loader.loadSfx("tales.mp3") self.Lvl1.setLoop(True) self.Lvl1.setVolume(0.0) self.Lvl1.play()""" self.Lvl2 = base.loader.loadSfx("vel3.wav") self.Lvl2.setLoop(True) self.Lvl2.setVolume(0.6) self.Lvl4 = base.loader.loadSfx("instru.wav") self.Lvl4.setLoop(False) self.Lvl4.setVolume(1.0) self.punch = base.loader.loadSfx("punch.mp3") self.punch.setVolume(1.0) """ ---------------------------- Load the World ------------------------ """ # this section of rendering will be extract in one class extern the wich # instace a segment of world acord to the position of the character. cont = 0 while (cont < 79): self.terrain.append(loader.loadModel("modelos/pista/calle")) self.terrain[cont].reparentTo(render) self.terrain[cont].setScale(25) self.terrain[cont].setPos(-85, 130 + (308 * cont), -69) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Buildings ------------------------ """ # Load all buildings in the Game for segments the last two of each part # Are diferents. PD. each part have 3 segments and each segment have # 5 buildings. cont = 0 conta = -1 while (cont < 200): self.buildings[cont].reparentTo(render) conta = conta + 1 if (conta == 4): self.buildings[cont].setScale(3.5) self.buildings[cont].setPos(-68, 380 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(90.0) conta = -1 if (conta == 3): self.buildings[cont].setScale(.8) self.buildings[cont].setPos(32, 338 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(180.0) if (conta == 2): self.buildings[cont].setScale(.2) self.buildings[cont].setPos(80, 295 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(90.0) if (conta == 1): self.buildings[cont].setScale(.2) self.buildings[cont].setPos(-85, 295 + ((308 * ((cont) / 5) * 2)), -8) self.buildings[cont].setH(270.0) if (conta == 0): self.buildings[cont].setScale(.5) self.buildings[cont].setPos(-34, 260 + ((308 * ((cont) / 5) * 2)), -8) cont = cont + 1 cont = 1 while (cont < 14): self.buildings[(cont * 15) - 2].setScale(5.2) self.buildings[(cont * 15) - 2].setPos( 96, 375 + (cont * (308 * 4)) + 13, -8) self.buildings[(cont * 15) - 2].setH(180.0) self.buildings[(15 * cont) - 1].setScale(3.2) self.buildings[(15 * cont) - 1].setPos( -85, 380 + (cont * (308 * 4)) + 8, -8) self.buildings[(15 * cont) - 1].setH(180.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Separators ----------------------- """ # Charge the Models of the separators between two segments of terrain only # only charge 8 and move the first 4 in the time. cont = 0 ident = -1 while (cont < 16): self.separators.append( loader.loadModel("modelos/separador/roadblock")) self.separators[cont].reparentTo(render) self.separators[cont].setScale(1.0) self.separators[cont].setH(90.0) posi = (308 * int(cont / 8)) ident = ident + 1 if (ident == 0): self.separators[cont].setPos(37, posi + 137, -8) if (ident == 1): self.separators[cont].setPos(37, posi + 152, -8) if (ident == 2): self.separators[cont].setPos(37, posi + 167, -8) if (ident == 3): self.separators[cont].setPos(37, posi + 182, -8) if (ident == 4): self.separators[cont].setPos(-38, posi + 137, -8) if (ident == 5): self.separators[cont].setPos(-38, posi + 152, -8) if (ident == 6): self.separators[cont].setPos(-38, posi + 167, -8) if (ident == 7): self.separators[cont].setPos(-38, posi + 182, -8) ident = -1 cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Objects ------------------------- """ # Charge the estatuas , lamparas , hidrantes, etc in the world. cont = 0 while (cont < 50): self.statua.append(loader.loadModel("modelos/estatua/estatua")) self.lamp.append(loader.loadModel("modelos/lampara/lampara")) self.statua[cont].reparentTo(render) self.lamp[cont].reparentTo(render) self.statua[cont].setScale(4.0) self.lamp[cont].setScale(4.0) self.statua[cont].setPos(-38, 95 + (308 * (cont * 2)), -8) self.lamp[cont].setPos(-38, 115 + (308 * (cont * 2)), -8) self.statua[cont].setH(270.0) self.lamp[cont].setH(270.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------------- Load Energy --------------------------- """ # Charge models of the energy bottle. cont = 0 while (cont < 200): self.energy.append(loader.loadModel("modelos/energia/energia")) cont = cont + 1 """ --------------------------------------------------------------------- """ """ -------------------- Load The Principal Actor ---------------------- """ # It's the Actor In the Game. self.jeep = Actor("modelos/jeep/jeep", {"walk": "modelos/jeep/jeep-start"}) self.jeep.setScale(0.7) self.jeep.setPos(0, 30, -6.8) self.jeep.reparentTo(render) self.jeep.setH(180.0) """ --------------------------------------------------------------------- """ """ -------------------- Load The Secondary Actor ---------------------- """ # This actor is the narrator of the game. """self.broman = Actor( "modelos/tutman/bullyactormodel", {"ani": "modelos/tutman/bullyactoranimpieceofcrap", "ani2": "modelos/tutman/bullyactoranimnoneofthese", "ani3": "modelos/tutman/bullyactoranimfoodstamps", "ani4": "modelos/tutman/bullyactoranimbeatme"}) self.broman.setScale(15.0) self.broman.setPos(0,100,1.0) self.broman.reparentTo(render) # Loop its animation. self.broman.loop("ani2") self.broman.setH( 90.0 )""" """ --------------------------------------------------------------------- """ """ -------------------- Load The Secondary Actor ---------------------- """ # These are children who run for the sidewalk cont = 1 posIni = -3400 while (cont < 40): self.bombero.append( Actor( "modelos/bombero/bombero", { "ani": "modelos/bombero/bombero1", "ani2": "modelos/bombero/bombero2", "ani3": "modelos/bombero/bombero3" })) self.bombero[cont - 1].reparentTo(render) self.bombero[cont - 1].setScale(1.0) if ((cont % 2) == 0): self.bombero[cont - 1].setPos(-26, posIni, -7.0) else: self.bombero[cont - 1].setPos(24, posIni, -7.0) self.bombero[cont - 1].loop("ani2") self.bombero[cont - 1].setH(180.0) posIni = posIni + 600 cont = cont + 1 """ --------------------------------------------------------------------- """ """ -------------------- Load The Secondary Actor ---------------------- """ # These are children who have balloons. cont = 0 while (cont < 50): self.balloons.append( Actor("modelos/nino/nino", {"ani": "modelos/nino/nino2"})) self.balloons[cont].reparentTo(render) self.balloons[cont].setScale(.05) self.balloons[cont].setPos(30, 100 + (308 * (cont * 2)), 3.0) self.balloons[cont].loop("ani") self.balloons[cont].setH(270.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ------------------ Load posicions of the bottles ------------------- """ cont = 0 while (cont < 80): x = random.randint(-26, 26) y = random.randint(0, 24090) self.energy[cont].reparentTo(render) self.energy[cont].setScale(.5) self.energy[cont].setPos(x, y, 0) self.energy[cont].setH(270.0) cont = cont + 1 """ --------------------------------------------------------------------- """ """ ---------------------- Prepara las Colisiones ---------------------- """ self.cs = CollisionSphere(0, 0, 0, 15) cont = 0 while (cont < 80): self.crash.append(self.energy[cont].attachNewNode( CollisionNode(str(cont)))) self.crash[cont].node().addSolid(self.cs) #self.crash[cont].show() cont = cont + 1 self.css = CollisionSphere(0, 0, 0, 12) self.cnodePath = self.jeep.attachNewNode(CollisionNode('cnode')) self.cnodePath.node().addSolid(self.css) #self.cnodePath.show() #self.cnodePath.show() self.traverser = CollisionTraverser() self.queue = CollisionHandlerQueue() """ --------------------------------------------------------------------- """ """ ----------------- when do you pressed one key ---------------------- """ self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_right", self.setKey, ["right", 1]) self.accept("arrow_up", self.setKey, ["forward", 1]) self.accept("a", self.setKey, ["cam-left", 1]) self.accept("s", self.setKey, ["cam-right", 1]) self.accept("r", self.setKey, ["look-back", 1]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_right-up", self.setKey, ["right", 0]) self.accept("arrow_up-up", self.setKey, ["forward", 0]) self.accept("a-up", self.setKey, ["cam-left", 0]) self.accept("s-up", self.setKey, ["cam-right", 0]) """ --------------------------------------------------------------------- """ taskMgr.add(self.move, "move") taskMgr.add(self.follow, "follow") taskMgr.add(self.stopSignal, "stopSignal") taskMgr.add(self.runBombero, "runBombero") taskMgr.add(self.collision, "collision") def runBombero(self, task): next = 0 while (next < 39 and self.Perdio == 0): self.bombero[next].setY(self.bombero[next].getY() + 8) next = next + 1 return Task.cont def collision(self, task): """if( (160 - time.clock()) >= 150 and self.Perdio == 1 ): if( self.sonidito == 0 ): self.Lvl4.play() self.sonidito = 1 if( (160 - time.clock()) < 150 ): if( self.activate == 0 ): self.activate = 1 self.perdio = 0""" if (self.Perdio == 0): global tempo tempo.destroy() #tiempito = "%.2f" % (time.clock()) tiempito2 = 120 - time.clock() tiempito = "%.2f" % (tiempito2) tempo = addText(0.9, 0.3, "Tiempo Restante: " + tiempito + " Seg", 0.07) if (tiempito2 <= 0): self.Perdio = 1 global text text.destroy() text = addText(0.01, -0.6, " GAME OVER ", 0.2) global tempo tempo.destroy() tempo = addText(0.9, 0.3, "Tiempo Restante: 0.0 Seg", 0.07) self.jeep.stop() self.Lvl2.stop() self.isMoving = False if (self.bebidas >= 30): self.Perdio = 1 global text text.destroy() text = addText(0.01, -0.9, " CONGRATULATIONS ", 0.2) self.jeep.stop() self.Lvl2.stop() self.isMoving = False #print self.jeep.getX() return Task.cont def setk(self, value): if (value == 1): self.angleDegrees = self.angleDegrees + 2.0 else: self.angleDegrees = self.angleDegrees - 2.0 def setKey(self, key, value): self.keyMap[key] = value """ -------cam-left and cam-right move the camera en circles --------------- """ """ ----------- follow with the camera to the character ------------------- """ def move(self, task): if (self.Perdio == 0): if ((self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or (self.keyMap["right"] != 0)): if self.isMoving is False: self.jeep.loop("walk", 1) self.isMoving = True self.Lvl2.play() else: if self.isMoving: self.jeep.stop() self.Lvl2.stop() self.isMoving = False if (self.keyMap["cam-left"] != 0): self.setk(0) angleRadians = self.angleDegrees * (pi / 180) base.camera.setPos( 40 * sin(angleRadians) + self.jeep.getX(), -40.0 * cos(angleRadians) + self.jeep.getY(), 3) base.camera.setHpr(self.angleDegrees, 0, 0) if (self.keyMap["cam-right"] != 0): self.setk(1) angleRadians = self.angleDegrees * (pi / 180) base.camera.setPos( 40 * sin(angleRadians) + self.jeep.getX(), -40.0 * cos(angleRadians) + self.jeep.getY(), 3) base.camera.setHpr(self.angleDegrees, 0, 0) if (self.keyMap["left"] != 0): self.jeep.setH(self.jeep.getH() + 2.0) if (self.jeep.getH() > 210000.0): self.jeep.setH(self.jeep.getH() - 2.0) else: self.setk(1) angleRadians = self.angleDegrees * (pi / 180) base.camera.setPos( 40 * sin(angleRadians) + self.jeep.getX(), -40.0 * cos(angleRadians) + self.jeep.getY(), 3) base.camera.setHpr(self.angleDegrees, 0, 0) if (self.keyMap["right"] != 0): self.jeep.setH(self.jeep.getH() - 2.0) if (self.jeep.getH() < -150000.0): self.jeep.setH(self.jeep.getH() + 2.0) else: self.setk(0) angleRadians = self.angleDegrees * (pi / 180) base.camera.setPos( 40 * sin(angleRadians) + self.jeep.getX(), -40.0 * cos(angleRadians) + self.jeep.getY(), 3) base.camera.setHpr(self.angleDegrees, 0, 0) if (self.keyMap["forward"] != 0): self.jeep.setY(self.jeep, -205 * globalClock.getDt()) if (self.jeep.getX() < -30 or self.jeep.getX() > 25): if (self.isCollision == False): self.punch.play() self.isCollision = True text.destroy() if (self.jeep.getX() < -30): text = addText(-0.2, -0.6, "Hemos Chocado", 0.1) if (self.jeep.getX() > 25): text = addText(-0.2, -0.4, "Procura Tener Mas Cuidado", 0.1) self.jeep.setY(self.jeep, 205 * globalClock.getDt()) #imageObject.destroy() #imageObject = OnscreenImage(image = 'myImage.jpg', pos = (-0.5, 0, 0.02), scale=(0.2,0,0.2) ) #imageObject.setTransparency(TransparencyAttrib.MAlpha) #text = addText(-0.2, -0.6, "Hemos Chocado") else: global text text.destroy() self.isCollision = False #global imageObject #imageObject.destroy() base.camera.setY( base.camera, -143.5 * (cos(self.jeep.getH() * (pi / 180))) * globalClock.getDt()) self.traverser.addCollider(self.cnodePath, self.queue) self.traverser.traverse(render) for i in range(self.queue.getNumEntries()): entry = self.queue.getEntry(i) self.energy[int(entry.getIntoNode().getName())].setPos( 0, 0, 5000) self.bebidas = self.bebidas + 1 global texta texta.destroy() texta = addText( 0.9, -1.2, "Hasta Ahora LLevamos " + str(self.bebidas) + " Bebidas", 0.07) return Task.cont """ ------------------------------------------------------------------------ """ """ ------------------------------------------------------------------------ """ def showMsge(self, task): self.inst1 = addText(-0.2, -0.6, "Ouch") def stopSignal(self, task): if (self.jeep.getY() > self.mayor): self.mayor = (self.mayor + 308) if (self.idStop == 0): self.separators[0].setY(self.separators[0].getY() + 616) self.separators[1].setY(self.separators[1].getY() + 616) self.separators[2].setY(self.separators[2].getY() + 616) self.separators[3].setY(self.separators[3].getY() + 616) self.separators[4].setY(self.separators[4].getY() + 616) self.separators[5].setY(self.separators[5].getY() + 616) self.separators[6].setY(self.separators[6].getY() + 616) self.separators[7].setY(self.separators[7].getY() + 616) self.idStop = 1 else: self.separators[8].setY(self.separators[8].getY() + 616) self.separators[9].setY(self.separators[9].getY() + 616) self.separators[10].setY(self.separators[10].getY() + 616) self.separators[11].setY(self.separators[11].getY() + 616) self.separators[12].setY(self.separators[12].getY() + 616) self.separators[13].setY(self.separators[13].getY() + 616) self.separators[14].setY(self.separators[14].getY() + 616) self.separators[15].setY(self.separators[15].getY() + 616) self.idStop = 0 return Task.cont def follow(self, task): print "hola"
def __init__(self): # Setup window size, title and so on load_prc_file_data("", """ win-size 1600 900 window-title Render Pipeline - Roaming Ralph Demo """) # ------ Begin of render pipeline code ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../../RenderPipeline/" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "7:40" # Use a special effect for rendering the scene, this is because the # roaming ralph model has no normals or valid materials self.render_pipeline.set_effect(render, "scene-effect.yaml", {}, sort=250) self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, "cam-right":0} self.speed = 1.0 base.win.setClearColor(Vec4(0,0,0,1)) # Post the instructions self.inst1 = addInstructions(0.95, "[ESC] Quit") self.inst4 = addInstructions(0.90, "[W] Run Ralph Forward") self.inst4 = addInstructions(0.85, "[S] Run Ralph Backward") self.inst2 = addInstructions(0.80, "[A] Rotate Ralph Left") self.inst3 = addInstructions(0.75, "[D] Rotate Ralph Right") self.inst6 = addInstructions(0.70, "[Left Arrow] Rotate Camera Left") self.inst7 = addInstructions(0.65, "[Right Arrow] Rotate Camera Right") # Set up the environment # # This environment model contains collision meshes. If you look # in the egg file, you will see the following: # # <Collide> { Polyset keep descend } # # This tag causes the following mesh to be converted to a collision # mesh -- a mesh which is optimized for collision, not rendering. # It also keeps the original mesh, so there are now two copies --- # one optimized for rendering, one for collisions. self.environ = loader.loadModel("resources/world") self.environ.reparentTo(render) self.environ.setPos(0,0,0) # Remove wall nodes self.environ.find("**/wall").remove_node() # Create the main character, Ralph self.ralph = Actor("resources/ralph", {"run":"resources/ralph-run", "walk":"resources/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(Vec3(-110.9, 29.4, 1.8)) # Create a floater object. We use the "floater" as a temporary # variable in a variety of calculations. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("a", self.setKey, ["left",1]) self.accept("d", self.setKey, ["right",1]) self.accept("w", self.setKey, ["forward",1]) self.accept("s", self.setKey, ["backward",1]) self.accept("arrow_left", self.setKey, ["cam-left",1]) self.accept("arrow_right", self.setKey, ["cam-right",1]) self.accept("a-up", self.setKey, ["left",0]) self.accept("d-up", self.setKey, ["right",0]) self.accept("w-up", self.setKey, ["forward",0]) self.accept("s-up", self.setKey, ["backward",0]) self.accept("arrow_left-up", self.setKey, ["cam-left",0]) self.accept("arrow_right-up", self.setKey, ["cam-right",0]) self.accept("=", self.adjustSpeed, [0.25]) self.accept("+", self.adjustSpeed, [0.25]) self.accept("-", self.adjustSpeed, [-0.25]) taskMgr.add(self.move,"moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX() + 10,self.ralph.getY() + 10, 2) base.camLens.setFov(80) # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above ralph's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0,0,1000) self.ralphGroundRay.setDirection(0,0,-1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0)) self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0,0,1000) self.camGroundRay.setDirection(0,0,-1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays #self.ralphGroundColNp.show() #self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(-5, -5, -5)) directionalLight.setColor(Vec4(1, 1, 1, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight))
class MouseHandler(object): def __init__(self,pandaScene): self.pandaScene = pandaScene def setupMouseCollisionWM(self): self.mouseTraverser = CollisionTraverser() self.mouseCollisionQueue = CollisionHandlerQueue() self.mouseRay = CollisionRay() self.mouseRay.setOrigin(self.pandaScene.worldMapCam.getPos(self.pandaScene.render)) self.mouseRay.setDirection(self.pandaScene.render.getRelativeVector(self.pandaScene.worldMapCam, Vec3(0,1,0))) self.mouseNode = CollisionNode('mouseRay') self.mouseNode.addSolid(self.mouseRay) self.mouseNodePath = self.pandaScene.worldMapCam.attachNewNode(self.mouseNode) self.mouseNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.mouseTraverser.addCollider(self.mouseNodePath, self.mouseCollisionQueue) # uncomment to see the collisions # self.mouseTraverser.showCollisions(self.pandaScene.render) def selectedObjectIdWM(self): if (self.pandaScene.worldMapMouse.hasMouse() == False): return 0,None mpos = self.pandaScene.worldMapMouse.getMouse() self.mouseRay.setFromLens(self.pandaScene.camNode, mpos.getX(), mpos.getY()) self.mouseTraverser.traverse(self.pandaScene.render) if (self.mouseCollisionQueue.getNumEntries() > 0): self.mouseCollisionQueue.sortEntries() entry = self.mouseCollisionQueue.getEntry(0); selectedObj = entry.getIntoNodePath() selectedObj = selectedObj.findNetTag('selectable') if not selectedObj.isEmpty(): return selectedObj.getTag('id'),selectedObj else: return 0,None return 0,None def selectedObjectId(self): if (self.pandaScene.mouseWatcherNode.hasMouse() == False): return 0,None mpos = base.mouseWatcherNode.getMouse() self.mouseRay.setFromLens(self.pandaScene.camNode, mpos.getX(), mpos.getY()) self.mouseTraverser.traverse(self.pandaScene.render) if (self.mouseCollisionQueue.getNumEntries() > 0): self.mouseCollisionQueue.sortEntries() entry = self.mouseCollisionQueue.getEntry(0); selectedObj = entry.getIntoNodePath() selectedObj = selectedObj.findNetTag('selectable') if not selectedObj.isEmpty(): return selectedObj.getTag('id'),selectedObj else: return 0,None return 0,None def setupMouseCollision(self): self.mouseTraverser = CollisionTraverser() self.mouseCollisionQueue = CollisionHandlerQueue() self.mouseRay = CollisionRay() self.mouseRay.setOrigin(self.pandaScene.camera.getPos(self.pandaScene.render)) self.mouseRay.setDirection(self.pandaScene.render.getRelativeVector(self.pandaScene.camera, Vec3(0,1,0))) self.mouseNode = CollisionNode('mouseRay') self.mouseNode.addSolid(self.mouseRay) self.mouseNodePath = self.pandaScene.camera.attachNewNode(self.mouseNode) self.mouseNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.mouseTraverser.addCollider(self.mouseNodePath, self.mouseCollisionQueue)
class moveMario(ShowBase): def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) self.ser = serial.Serial('/dev/tty.usbmodem1421', 9600) # Set the background color to black self.win.setClearColor((0, 0, 0, 1)) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "reverse": 0, "cam-left": 0, "cam-right": 0 } #Initialize Track self.track = self.loader.loadModel("luigi_circuit") self.track.setScale(1.5) self.track.reparentTo(render) #Intitial where Mario needs to be #marioStartPos = self.track.find("**/start_point").getPos() marioStartPos = Vec3(50, -29, 0.35) #Actual start possition #Using ralph because the model is made with correct collision masking and animation self.marioActor = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.marioActor.setScale(0.1, 0.1, 0.1) self.marioActor.setH(self.marioActor, 270) self.marioActor.reparentTo(self.render) self.marioActor.setPos(marioStartPos + (0, 0, 0.5)) #Floater above so Camera has something to look at self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.marioActor) self.floater.setZ(2.0) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera self.disableMouse() self.camera.setPos(self.marioActor.getX() + 100, self.marioActor.getY(), 1) #Collision Rays self.cTrav = CollisionTraverser() self.marioGroundRay = CollisionRay() self.marioGroundRay.setOrigin(0, 0, 9) self.marioGroundRay.setDirection(0, 0, -1) self.marioGroundCol = CollisionNode('marioRay') self.marioGroundCol.addSolid(self.marioGroundRay) self.marioGroundCol.setFromCollideMask(CollideMask.bit(0)) self.marioGroundCol.setIntoCollideMask(CollideMask.allOff()) self.marioGroundColNp = self.marioActor.attachNewNode( self.marioGroundCol) self.marioGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.marioGroundColNp, self.marioGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def move(self, task): elapsed = globalClock.getDt() # If a move-key is pressed, move Mario in the specified direction. startpos = self.marioActor.getPos() line = self.ser.readline() listOfCoord = line.split(":") if (len(listOfCoord) == 7): x = listOfCoord[1] g = listOfCoord[3] r = listOfCoord[5] if (10 <= float(x) <= 180): #MAKE IT TURN RIGHT self.setKey("right", True) self.setKey("left", False) elif (180 < float(x) <= 350): #MAKE IT TURN LEFT self.setKey("right", False) self.setKey("left", True) else: self.setKey("right", False) self.setKey("left", False) #Make it move forward if (int(g) == 1): self.setKey("forward", True) else: self.setKey("forward", False) #Make it move in Reverse if (int(r) == 1): self.setKey("reverse", True) else: self.setKey("reverse", False) if self.keyMap["left"]: self.marioActor.setH(self.marioActor.getH() + 50 * elapsed) self.camera.setX(self.camera, +5 * elapsed) if self.keyMap["right"]: self.marioActor.setH(self.marioActor.getH() - 50 * elapsed) self.camera.setX(self.camera, -5 * elapsed) if self.keyMap["forward"]: self.marioActor.setY(self.marioActor, -100 * elapsed) if self.keyMap["reverse"]: self.marioActor.setY(self.marioActor, 100 * elapsed) #When moving - run the animation - Taken from roaming ralph example if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap[ "right"]: if self.isMoving is False: self.marioActor.loop("run") self.isMoving = True else: if self.isMoving: self.marioActor.stop() self.marioActor.pose("walk", 5) self.isMoving = False #Camera uses - modified from roaming ralph camvec = self.marioActor.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 5.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 5)) camdist = 5.0 if camdist < 2.5: self.camera.setPos(self.camera.getPos() - camvec * (2.5 - camdist)) camdist = 2.5 #Collission terrain checking - taken from roaming ralph entries = list(self.marioGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0 and entries[0].getIntoNode().getName( ) == "terrain": self.marioActor.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.marioActor.setPos(startpos) # Keep the camera at level - taken from roaming ralph entries = list(self.camGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0 and entries[0].getIntoNode().getName( ) == "terrain": self.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if self.camera.getZ() < self.marioActor.getZ() + 1.0: self.camera.setZ(self.marioActor.getZ() + 1.0) self.camera.lookAt(self.floater) return task.cont
class World(DirectObject): def __init__(self): # Create a Controller object to receive events self.leap = Leap.Controller() # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Panda3D and Leap Motion", style=1, fg=(1,1,1,1), pos=(0.7,-0.95), scale = .07) self.instructions = OnscreenText(text="Hand Tilts the Board", pos = (-1.3, .95), fg=(1,1,1,1), align = TextNode.ALeft, scale = .05) self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Most times, you want collisions to be tested against invisible geometry # rather than every polygon. This is because testing against every polygon # in the scene is usually too slow. You can have simplified or approximate # geometry for the solids and still get good results. # # Sometimes you'll want to create and position your own collision solids in # code, but it's often easier to have them built automatically. This can be # done by adding special tags into an egg file. Check maze.egg and ball.egg # and look for lines starting with <Collide>. The part is brackets tells # Panda exactly what to do. Polyset means to use the polygons in that group # as solids, while Sphere tells panda to make a collision sphere around them # Keep means to keep the polygons in the group as visable geometry (good # for the ball, not for the triggers), and descend means to make sure that # the settings are applied to any subgroups. # # Once we have the collision tags in the models, we can get to them using # NodePath's find command # Find the collision node named wall_collide self.walls = self.maze.find("**/wall_collide") # Collision objects are sorted using BitMasks. BitMasks are ordinary numbers # with extra methods for working with them as binary bits. Every collision # solid has both a from mask and an into mask. Before Panda tests two # objects, it checks to make sure that the from and into collision masks # have at least one bit in common. That way things that shouldn't interact # won't. Normal model nodes have collision masks as well. By default they # are set to bit 20. If you want to collide against actual visable polygons, # set a from collide mask to include bit 20 # # For this example, we will make everything we want the ball to collide with # include bit 0 self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # CollisionNodes are usually invisible but can be shown. Uncomment the next # line to see the collision walls # self.walls.show() # We will now find the triggers for the holes and set their masks to 0 as # well. We also set their names to make them easier to identify during # collisions self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTrigger") self.loseTriggers.append(trigger) # Uncomment this line to see the triggers # trigger.show() # Ground_collide is a single polygon on the same plane as the ground in the # maze. We will use a ray to collide with it so that we will know exactly # what height to put the ball at every frame. Since this is not something # that we want the ball itself to collide with, it has a different # bitmask. self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # Find the collison sphere for the ball which was created in the egg file # Notice that it has a from collision mask of bit 0, and an into collison # mask of no bits. This means that the ball can only cause collisions, not # be collided into self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) # 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.ballGroundRay = CollisionRay() # Create the ray self.ballGroundRay.setOrigin(0,0,10) # Set its origin self.ballGroundRay.setDirection(0,0,-1) # And its direction # Collision solids go in CollisionNode self.ballGroundCol = CollisionNode('groundRay') # Create and name the node self.ballGroundCol.addSolid(self.ballGroundRay) # Add the ray self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) # Set its bitmasks self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) # 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.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # Uncomment this line to see the ray # self.ballGroundColNp.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.cHandler = 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.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # Collision traversers have a built in tool to help visualize collisions. # Uncomment the next line to see it. # self.cTrav.showCollisions(render) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1,1,1,1)) m.setShininess(96) self.ball.setMaterial(m, 1) # Finally, we call start for more initialization self.start() def start(self): # The maze model also has a locator in it for where to start the ball # To access it we use the find command startPos = self.maze.find("**/start").getPos() self.ballRoot.setPos(startPos) # Set the ball in the starting position self.ballV = Vec3(0,0,0) # Initial velocity is 0 self.accelV = Vec3(0,0,0) # Initial acceleration is 0 # For a traverser to actually do collisions, you need to call # traverser.traverse() on a part of the scene. Fortunatly, base has a # task that does this for the entire scene once a frame. This sets up our # traverser as the one to be called automatically base.cTrav = self.cTrav # Create the movement task, but first make sure it is not already running taskMgr.remove("rollTask") self.mainLoop = taskMgr.add(self.rollTask, "rollTask") self.mainLoop.last = 0 # This function handles the collision between the ray and the ground # Information about the interaction is passed in colEntry def groundCollideHandler(self, colEntry): # Set the ball to the appropriate Z value for it to be exactly on the ground newZ = colEntry.getSurfacePoint(render).getZ() self.ballRoot.setZ(newZ+.4) # Find the acceleration direction. First the surface normal is crossed with # the up vector to get a vector perpendicular to the slope norm = colEntry.getSurfaceNormal(render) accelSide = norm.cross(UP) # Then that vector is crossed with the surface normal to get a vector that # points down the slope. By getting the acceleration in 3D like this rather # than in 2D, we reduce the amount of error per-frame, reducing jitter self.accelV = norm.cross(accelSide) # This function handles the collision between the ball and a wall def wallCollideHandler(self, colEntry): # First we calculate some numbers we need to do a reflection norm = colEntry.getSurfaceNormal(render) * -1 # The normal of the wall curSpeed = self.ballV.length() # The current speed inVec = self.ballV / curSpeed # The direction of travel velAngle = norm.dot(inVec) # Angle of incidance hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos() hitDir.normalize() hitAngle = norm.dot(hitDir) # The angle between the ball and the normal # Ignore the collision if the ball is either moving away from the wall # already (so that we don't accidentally send it back into the wall) # and ignore it if the collision isn't dead-on (to avoid getting caught on # corners) if velAngle > 0 and hitAngle > .995: # Standard reflection equation reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec # This makes the velocity half of what it was if the hit was dead-on # and nearly exactly what it was if this is a glancing blow self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5)) # Since we have a collision, the ball is already a little bit buried in # the wall. This calculates a vector needed to move it so that it is # exactly touching the wall disp = (colEntry.getSurfacePoint(render) - colEntry.getInteriorPoint(render)) newPos = self.ballRoot.getPos() + disp self.ballRoot.setPos(newPos) # This is the task that deals with making everything interactive def rollTask(self, task): # Get the most recent frame frame = self.leap.frame() hands = frame.hands numHands = len(hands) if numHands >= 1: # Get the normal vector of the first hand hand = hands[0] handNormal = hand.palm_normal if handNormal is not None: # Standard technique for finding the amount of time since the last frame dt = task.time - task.last task.last = task.time # If dt is large, then there has been a # hiccup that could cause the ball # to leave the field if this functions runs, so ignore the frame if dt > .2: return Task.cont # 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.cHandler.getNumEntries()): entry = self.cHandler.getEntry(i) name = entry.getIntoNode().getName() if name == "wall_collide": self.wallCollideHandler(entry) elif name == "ground_collide": self.groundCollideHandler(entry) elif name == "loseTrigger": self.loseGame(entry) # Read the hands normal vector and tilt the maze accordingly self.maze.setP(handNormal.z * -30) self.maze.setR(handNormal.x * -30) # Finally, we move the ball # Update the velocity based on acceleration self.ballV += self.accelV * dt * ACCEL # Clamp the velocity to the maximum speed if self.ballV.lengthSquared() > MAX_SPEED_SQ: self.ballV.normalize() self.ballV *= MAX_SPEED # Update the position based on the velocity self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV * dt)) # This block of code rotates the ball. It uses something called a quaternion # to rotate the ball around an arbitrary axis. That axis perpendicular to # the balls rotation, and the amount has to do with the size of the ball # This is multiplied on the previous rotation to incrimentally turn it. prevRot = LRotationf(self.ball.getQuat()) axis = UP.cross(self.ballV) newRot = LRotationf(axis, 45.5 * dt * self.ballV.length()) self.ball.setQuat(prevRot * newRot) return Task.cont # Continue the task indefinitely # If the ball hits a hole trigger, then it should fall in the hole. # This is faked rather than dealing with the actual physics of it. def loseGame(self, entry): # The triggers are set up so that the center of the ball should move to the # collision point to be in the hole toPos = entry.getInteriorPoint(render) taskMgr.remove('rollTask') # Stop the maze task # Move the ball into the hole over a short sequence of time. Then wait a # second and call start to reset the game Sequence( Parallel( LerpFunc(self.ballRoot.setX, fromData = self.ballRoot.getX(), toData = toPos.getX(), duration = .1), LerpFunc(self.ballRoot.setY, fromData = self.ballRoot.getY(), toData = toPos.getY(), duration = .1), LerpFunc(self.ballRoot.setZ, fromData = self.ballRoot.getZ(), toData = self.ballRoot.getZ() - .9, duration = .2)), Wait(1), Func(self.start)).start()
class Picker(object): """ Generic object picker class for Panda3d. Given a top Node Path to search, it finds the closest collision object under the mouse pointer. Picker takes a topNode to test for mouse ray collisions. the pick() method returns (NodePathPicked, 3dPosition, rawNode) underneath the mouse position. If no collision was detected, it returns None, None, None. 'NodePathPicked' is the deepest NAMED node path that was collided with, this is usually what you want. rawNode is the deep node (such as geom) if you want to play with that. 3dPosition is where the mouse ray touched the surface. The picker object uses base.camera to collide, so if you have a custom camera, well, sorry bout that. pseudo code: p = Picker(mycollisionTopNode) thingPicked, positionPicked, rawNode = p.pick() if thingPicked: # do something here like thingPicked.ls() """ def __init__(self, topNode, cameraObject = None): self.traverser = CollisionTraverser() self.handler = CollisionHandlerQueue() self.topNode = topNode self.cam = cameraObject pickerNode = CollisionNode('MouseRay') #NEEDS to be set to global camera. boo hoo self.pickerNP = base.camera.attachNewNode(pickerNode) # this seems to enter the bowels of the node graph, making it # difficult to perform logic on pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickRay = CollisionRay() #pickerNode.setCollideMask(BitMask32.allOff()) pickerNode.addSolid(self.pickRay) self.traverser.addCollider(self.pickerNP, self.handler) def setTopNode(self, topNode): """set the topmost node to traverse when detecting collisions""" self.topNode = topNode def destroy(self): """clean up my stuff.""" self.ignoreAll() # remove colliders, subnodes and such self.pickerNP.remove() self.traverser.clearColliders() def pick(self): """ pick closest object under the mouse if available. returns ( NodePathPicked, surfacePoint, rawNode ) or (None, None None) """ if not self.topNode: return None, None, None if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.traverser.traverse(self.topNode) if self.handler.getNumEntries() > 0: self.handler.sortEntries() picked = self.handler.getEntry(0).getIntoNodePath() thepoint = self.handler.getEntry(0).getSurfacePoint(self.topNode) return self.getFirstParentWithName(picked), thepoint, picked return None, None, None def getFirstParentWithName(self, pickedObject): """ return first named object up the node chain from the picked node. This helps remove drudgery when you just want to find a simple object to work with. Normally, you wouldn't use this method directly. """ name = pickedObject.getName() parent = pickedObject while not name: parent = parent.getParent() if not parent: raise Exception("Node '%s' needs a parent with a name to accept clicks." % (str(pickedObject))) name = parent.getName() if parent == self.topNode: raise Exception("Collision parent '%s' is top Node, surely you wanted to click something beneath it..." % (str(parent))) return parent
def __init__(self): # Create a Controller object to receive events self.leap = Leap.Controller() # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Panda3D and Leap Motion", style=1, fg=(1,1,1,1), pos=(0.7,-0.95), scale = .07) self.instructions = OnscreenText(text="Hand Tilts the Board", pos = (-1.3, .95), fg=(1,1,1,1), align = TextNode.ALeft, scale = .05) self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Most times, you want collisions to be tested against invisible geometry # rather than every polygon. This is because testing against every polygon # in the scene is usually too slow. You can have simplified or approximate # geometry for the solids and still get good results. # # Sometimes you'll want to create and position your own collision solids in # code, but it's often easier to have them built automatically. This can be # done by adding special tags into an egg file. Check maze.egg and ball.egg # and look for lines starting with <Collide>. The part is brackets tells # Panda exactly what to do. Polyset means to use the polygons in that group # as solids, while Sphere tells panda to make a collision sphere around them # Keep means to keep the polygons in the group as visable geometry (good # for the ball, not for the triggers), and descend means to make sure that # the settings are applied to any subgroups. # # Once we have the collision tags in the models, we can get to them using # NodePath's find command # Find the collision node named wall_collide self.walls = self.maze.find("**/wall_collide") # Collision objects are sorted using BitMasks. BitMasks are ordinary numbers # with extra methods for working with them as binary bits. Every collision # solid has both a from mask and an into mask. Before Panda tests two # objects, it checks to make sure that the from and into collision masks # have at least one bit in common. That way things that shouldn't interact # won't. Normal model nodes have collision masks as well. By default they # are set to bit 20. If you want to collide against actual visable polygons, # set a from collide mask to include bit 20 # # For this example, we will make everything we want the ball to collide with # include bit 0 self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # CollisionNodes are usually invisible but can be shown. Uncomment the next # line to see the collision walls # self.walls.show() # We will now find the triggers for the holes and set their masks to 0 as # well. We also set their names to make them easier to identify during # collisions self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTrigger") self.loseTriggers.append(trigger) # Uncomment this line to see the triggers # trigger.show() # Ground_collide is a single polygon on the same plane as the ground in the # maze. We will use a ray to collide with it so that we will know exactly # what height to put the ball at every frame. Since this is not something # that we want the ball itself to collide with, it has a different # bitmask. self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # Find the collison sphere for the ball which was created in the egg file # Notice that it has a from collision mask of bit 0, and an into collison # mask of no bits. This means that the ball can only cause collisions, not # be collided into self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) # 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.ballGroundRay = CollisionRay() # Create the ray self.ballGroundRay.setOrigin(0,0,10) # Set its origin self.ballGroundRay.setDirection(0,0,-1) # And its direction # Collision solids go in CollisionNode self.ballGroundCol = CollisionNode('groundRay') # Create and name the node self.ballGroundCol.addSolid(self.ballGroundRay) # Add the ray self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) # Set its bitmasks self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) # 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.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # Uncomment this line to see the ray # self.ballGroundColNp.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.cHandler = 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.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # Collision traversers have a built in tool to help visualize collisions. # Uncomment the next line to see it. # self.cTrav.showCollisions(render) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1,1,1,1)) m.setShininess(96) self.ball.setMaterial(m, 1) # Finally, we call start for more initialization self.start()
class CollisionZoom: collision: CollisionNode = field(default_factory=lambda: CollisionNode("cam collisions")) traverser: CollisionTraverser = field(default_factory=lambda: CollisionTraverser("cam traverser")) queue: CollisionHandlerQueue = field(default_factory=lambda: CollisionHandlerQueue()) body_width: float = 0.5
def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) self.ser = serial.Serial('/dev/tty.usbmodem1421', 9600) # Set the background color to black self.win.setClearColor((0, 0, 0, 1)) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "reverse": 0, "cam-left": 0, "cam-right": 0 } #Initialize Track self.track = self.loader.loadModel("luigi_circuit") self.track.setScale(1.5) self.track.reparentTo(render) #Intitial where Mario needs to be #marioStartPos = self.track.find("**/start_point").getPos() marioStartPos = Vec3(50, -29, 0.35) #Actual start possition #Using ralph because the model is made with correct collision masking and animation self.marioActor = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.marioActor.setScale(0.1, 0.1, 0.1) self.marioActor.setH(self.marioActor, 270) self.marioActor.reparentTo(self.render) self.marioActor.setPos(marioStartPos + (0, 0, 0.5)) #Floater above so Camera has something to look at self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.marioActor) self.floater.setZ(2.0) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera self.disableMouse() self.camera.setPos(self.marioActor.getX() + 100, self.marioActor.getY(), 1) #Collision Rays self.cTrav = CollisionTraverser() self.marioGroundRay = CollisionRay() self.marioGroundRay.setOrigin(0, 0, 9) self.marioGroundRay.setDirection(0, 0, -1) self.marioGroundCol = CollisionNode('marioRay') self.marioGroundCol.addSolid(self.marioGroundRay) self.marioGroundCol.setFromCollideMask(CollideMask.bit(0)) self.marioGroundCol.setIntoCollideMask(CollideMask.allOff()) self.marioGroundColNp = self.marioActor.attachNewNode( self.marioGroundCol) self.marioGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.marioGroundColNp, self.marioGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
class Mouse(): def __init__(self): self.enabled = False self.locked = False self.position = Vec3(0, 0, 0) self.delta = Vec3(0, 0, 0) self.prev_x = 0 self.prev_y = 0 self.start_x = 0 self.start_y = 0 self.velocity = Vec3(0, 0, 0) self.prev_click_time = time.time() self.double_click_distance = .5 self.hovered_entity = None self.left = False self.right = False self.middle = False self.delta_drag = Vec3(0, 0, 0) self.update_step = 1 self._i = 0 self._mouse_watcher = None self._picker = CollisionTraverser() # Make a traverser self._pq = CollisionHandlerQueue() # Make a handler self._pickerNode = CollisionNode('mouseRay') self._pickerNP = camera.attach_new_node(self._pickerNode) self._pickerRay = CollisionRay() # Make our ray self._pickerNode.addSolid(self._pickerRay) self._picker.addCollider(self._pickerNP, self._pq) self._pickerNode.set_into_collide_mask(0) self.raycast = True self.collision = None self.collisions = list() self.enabled = True @property def x(self): if not self._mouse_watcher.has_mouse(): return 0 return self._mouse_watcher.getMouseX( ) / 2 * window.aspect_ratio # same space as ui stuff @x.setter def x(self, value): self.position = (value, self.y) @property def y(self): if not self._mouse_watcher.has_mouse(): return 0 return self._mouse_watcher.getMouseY() / 2 @y.setter def y(self, value): self.position = (self.x, value) @property def position(self): return Vec3(self.x, self.y, 0) @position.setter def position(self, value): base.win.move_pointer( 0, int(value[0] + (window.size[0] / 2) + (value[0] / 2 * window.size[0]) * 1.123), # no idea why I have * with 1.123 int(value[1] + (window.size[1] / 2) - (value[1] * window.size[1])), ) def __setattr__(self, name, value): if name == 'visible': window.set_cursor_hidden(not value) application.base.win.requestProperties(window) if name == 'locked': try: object.__setattr__(self, name, value) window.set_cursor_hidden(value) application.base.win.requestProperties(window) except: pass try: super().__setattr__(name, value) # return except: pass def input(self, key): if not self.enabled: return if key.endswith('mouse down'): self.start_x = self.x self.start_y = self.y elif key.endswith('mouse up'): self.delta_drag = Vec3(self.x - self.start_x, self.y - self.start_y, 0) if key == 'left mouse down': self.left = True if self.hovered_entity: if hasattr(self.hovered_entity, 'on_click'): self.hovered_entity.on_click() for s in self.hovered_entity.scripts: if hasattr(s, 'on_click'): s.on_click() # double click if time.time( ) - self.prev_click_time <= self.double_click_distance: base.input('double click') if self.hovered_entity: if hasattr(self.hovered_entity, 'on_double_click'): self.hovered_entity.on_double_click() for s in self.hovered_entity.scripts: if hasattr(s, 'on_double_click'): s.on_double_click() self.prev_click_time = time.time() if key == 'left mouse up': self.left = False if key == 'right mouse down': self.right = True if key == 'right mouse up': self.right = False if key == 'middle mouse down': self.middle = True if key == 'middle mouse up': self.middle = False def update(self): if not self.enabled or not self._mouse_watcher.has_mouse(): self.velocity = Vec3(0, 0, 0) return self.moving = self.x + self.y != self.prev_x + self.prev_y if self.moving: if self.locked: self.velocity = self.position self.position = (0, 0) else: self.velocity = Vec3(self.x - self.prev_x, (self.y - self.prev_y) / window.aspect_ratio, 0) else: self.velocity = Vec3(0, 0, 0) if self.left or self.right or self.middle: self.delta = Vec3(self.x - self.start_x, self.y - self.start_y, 0) self.prev_x = self.x self.prev_y = self.y self._i += 1 if self._i < self.update_step: return # collide with ui self._pickerNP.reparent_to(scene.ui_camera) self._pickerRay.set_from_lens(camera._ui_lens_node, self.x * 2 / window.aspect_ratio, self.y * 2) self._picker.traverse(camera.ui) if self._pq.get_num_entries() > 0: # print('collided with ui', self._pq.getNumEntries()) self.find_collision() return # collide with world self._pickerNP.reparent_to(camera) self._pickerRay.set_from_lens(scene.camera.lens_node, self.x * 2 / window.aspect_ratio, self.y * 2) try: self._picker.traverse(base.render) except: print('error: mouse._picker could not traverse base.render') return if self._pq.get_num_entries() > 0: self.find_collision() else: # print('mouse miss', base.render) # unhover all if it didn't hit anything for entity in scene.entities: if hasattr(entity, 'hovered') and entity.hovered: entity.hovered = False self.hovered_entity = None if hasattr(entity, 'on_mouse_exit'): entity.on_mouse_exit() for s in entity.scripts: if hasattr(s, 'on_mouse_exit'): s.on_mouse_exit() @property def normal(self): if not self.collision: return None return self.collision.normal @property def world_normal(self): if not self.collision: return None return self.collision.world_normal @property def point(self): if self.collision: return self.collision.point return None @property def world_point(self): if self.collision: return self.collision.world_point return None def find_collision(self): self.collisions = list() self.collision = None if not self.raycast or self._pq.get_num_entries() == 0: self.unhover_everything_not_hit() return False self._pq.sortEntries() for entry in self._pq.getEntries(): for entity in scene.entities: if entry.getIntoNodePath( ).parent == entity and entity.collision: if entity.collision: hit = Hit( hit=entry.collided(), entity=entity, distance=distance(entry.getSurfacePoint(scene), camera.getPos()), point=entry.getSurfacePoint(entity), world_point=entry.getSurfacePoint(scene), normal=entry.getSurfaceNormal(entity), world_normal=entry.getSurfaceNormal(scene), ) hit.point = Vec3(hit.point[0], hit.point[2], hit.point[1]) hit.world_point = Vec3(hit.world_point[0], hit.world_point[2], hit.world_point[1]) hit.normal = Vec3(hit.normal[0], hit.normal[2], hit.normal[1]) hit.world_normal = Vec3(hit.world_normal[0], hit.world_normal[2], hit.world_normal[1]) self.collisions.append(hit) break if self.collisions: self.collision = self.collisions[0] self.hovered_entity = self.collision.entity if not self.hovered_entity.hovered: self.hovered_entity.hovered = True if hasattr(self.hovered_entity, 'on_mouse_enter'): self.hovered_entity.on_mouse_enter() for s in self.hovered_entity.scripts: if hasattr(s, 'on_mouse_enter'): s.on_mouse_enter() self.unhover_everything_not_hit() def unhover_everything_not_hit(self): for e in scene.entities: if e == self.hovered_entity: continue if e.hovered: e.hovered = False if hasattr(e, 'on_mouse_exit'): e.on_mouse_exit() for s in e.scripts: if hasattr(s, 'on_mouse_exit'): s.on_mouse_exit()
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) props = WindowProperties() props.setTitle("Gesture Maze") base.win.requestProperties(props) self.tital = OnscreenText(text="Gesture Maze Control", parent=base.a2dTopLeft, align=TextNode.ALeft, pos=(0.05, -0.08), fg=(1, 1, 1, 1), scale=0.06, shadow=(0, 0, 0, 0.5)) self.accept("escape", sys.exit) camera_num = 0 self.gesture_controler = gesture_control.GestureControler(0) self.disableMouse() camera.setPosHpr(0, 0, 25, 0, -90, 0) self.maze = loader.loadModel("models/%s" % settings.maze_id) self.maze.reparentTo(render) self.walls = self.maze.find("**/wall_collide") self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # self.walls.show() self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTriggers") self.loseTriggers.append(trigger) # trigger.show() self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) self.ballGroundRay = CollisionRay() self.ballGroundRay.setOrigin(0, 0, 10) self.ballGroundRay.setDirection(0, 0, -1) self.ballGroundCol = CollisionNode("groundRay") self.ballGroundCol.addSolid(self.ballGroundRay) self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # self.ballGroundColNp.show() self.cTrav = CollisionTraverser() self.cHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # self.cTrav.showCollisions(render) ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(LVector3(0, 0, -1)) directionalLight.setColor((0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) m = Material() m.setSpecular((1, 1, 1, 1)) m.setShininess(96) self.ball.setMaterial(m, 1) self.start() def start(self): startPos = self.maze.find("**/start").getPos() self.ballRoot.setPos(startPos) self.ballV = LVector3(0, 0, 0) self.accelV = LVector3(0, 0, 0) taskMgr.remove("roolTask") self.mainLoop = taskMgr.add(self.rollTask, "rollTask") def groundCollideHander(self, colEntry): newZ = colEntry.getSurfacePoint(render).getZ() self.ballRoot.setZ(newZ + 0.4) norm = colEntry.getSurfaceNormal(render) accelSide = norm.cross(LVector3.up()) self.accelV = norm.cross(accelSide) def wallCollideHandler(self, colEntry): norm = colEntry.getSurfaceNormal(render) * -1 curSpeed = self.ballV.length() inVec = self.ballV / curSpeed velAngle = norm.dot(inVec) hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos() hitDir.normalize() hitAngle = norm.dot(hitDir) if velAngle > 0 and hitAngle > 0.995: reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec self.ballV = reflectVec * (curSpeed * (((1 - velAngle) * 0.5) + 0.5)) disp = (colEntry.getSurfacePoint(render) - colEntry.getInteriorPoint(render)) newPos = self.ballRoot.getPos() + disp self.ballRoot.setPos(newPos) def rollTask(self, task): self.gesture_controler.track() dt = globalClock.getDt() if dt > 0.2: return Task.cont if self.gesture_controler.getPause(): return Task.cont # if self.gesture_controler.getQuit(): # print("Gesture: Quit. You will quit from the game.") # sys.exit() # if self.gesture_controler.getReset(): # self.resetGame() # return Task.cont for i in range(self.cHandler.getNumEntries()): entry = self.cHandler.getEntry(i) name = entry.getIntoNode().getName() if name == "wall_collide": self.wallCollideHandler(entry) elif name == "ground_collide": self.groundCollideHander(entry) elif name == "loseTriggers": self.loseGame(entry) if self.gesture_controler.isMoving(): cur_pos = self.gesture_controler.getPos() mpos = LPoint2f(cur_pos[0], cur_pos[1]) # print(mpos) self.maze.setP(mpos.getY() * -10) self.maze.setR(mpos.getX() * 10) self.ballV += self.accelV * dt * ACCEL if self.ballV.lengthSquared() > MAX_SPEED_SQ: self.ballV.normalize() self.ballV *= MAX_SPEED self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV * dt)) prevRot = LRotationf(self.ball.getQuat()) axis = LVector3.up().cross(self.ballV) newRot = LRotationf(axis, 45.5 * dt * self.ballV.length()) self.ball.setQuat(prevRot * newRot) return Task.cont def resetGame(self): self.start() def loseGame(self, entry): toPos = entry.getInteriorPoint(render) taskMgr.remove("rollTask") Sequence( Parallel( LerpFunc(self.ballRoot.setX, fromData=self.ballRoot.getX(), toData=toPos.getX(), duration=0.1), LerpFunc(self.ballRoot.setY, fromData=self.ballRoot.getY(), toData=toPos.getY(), duration=0.1), LerpFunc(self.ballRoot.setZ, fromData=self.ballRoot.getZ(), toData=self.ballRoot.getZ() - .9, duration=0.2)), Wait(1), Func(self.start)).start()
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.disableMouse() camera.setPosHpr(0, -12, 8, 0, -35, 0) """ self.environ = self.loader.loadModel("models/environment") # Reparent the model to render. self.environ.reparentTo(self.render) # Apply scale and position transforms on the model. self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0) self.torus = loader.loadModel("torus.egg") self.torus.reparentTo(self.render) self.torus.setPos(circPos(0,1)) self.torus.setColor(BLACK) self.torus.setScale(0.5,0.5,0.5) """ self.setupLights() self.ended = False self.currentB = False self.firstTurn = True # Since we are using collision detection to do picking, we set it up like # any other collision detection system with a traverser and a handler self.picker = CollisionTraverser() # Make a traverser self.pq = CollisionHandlerQueue() # Make a handler # Make a collision node for our picker ray self.pickerNode = CollisionNode('mouseRay') # Attach that node to the camera since the ray will need to be positioned # relative to it self.pickerNP = camera.attachNewNode(self.pickerNode) # Everything to be picked will use bit 1. This way if we were doing other # collision we could seperate it self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() # Make our ray # Add it to the collision node self.pickerNode.addSolid(self.pickerRay) # Register the ray as something that can cause collisions self.picker.addCollider(self.pickerNP, self.pq) self.picker.showCollisions(render) self.whiteTurn = True # Now we create the chess board and its pieces # We will attach all of the squares to their own root. This way we can do the # collision pass just on the sqaures and save the time of checking the rest # of the scene self.batonsRoot = render.attachNewNode("batonsRoot") self.batons = [None for i in range(9)] self.torus = [[None for j in range(3)] for i in range(9)] self.org = [[[None for j in range(3)] for i in range(3)] for i in range(3)] for i in range(9): # Load, parent, color, and position the model (a single square # polygon) self.batons[i] = loader.loadModel("bois.egg") self.batons[i].reparentTo(self.batonsRoot) self.batons[i].setPos(circPos(i,0)) self.batons[i].setColor(0.75,0.5,0) self.batons[i].setScale(0.75,0.75,0.5) # Set the model itself to be collideable with the ray. If this model was # any more complex than a single polygon, you should set up a collision # sphere around it instead. But for single polygons this works # fine. self.batons[i].find("**/Cylinder").node().setIntoCollideMask( BitMask32.bit(1)) # Set a tag on the square's node so we can look up what square this is # later during the collision pass self.batons[i].find("**/Cylinder").setTag('baton', str(i)) # We will use this variable as a pointer to whatever piece is currently # in this square self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask') self.accept("mouse1", self.click) self.accept("w", self.bestPossibleMove) def setupLights(self): # This function sets up some default lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.8, .8, .8, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(LVector3(0, 45, -45)) directionalLight.setColor((0.2, 0.2, 0.2, 1)) render.setLight(render.attachNewNode(directionalLight)) render.setLight(render.attachNewNode(ambientLight)) def mouseTask(self, task): # This task deals with the highlighting and dragging based on the mouse # Check to see if we can access the mouse. We need it to do anything # else if self.mouseWatcherNode.hasMouse(): # get the mouse position mpos = self.mouseWatcherNode.getMouse() # Set the position of the ray based on the mouse position self.pickerRay.setFromLens(self.camNode, mpos.getX(), mpos.getY()) if self.currentB is not False: self.batons[self.currentB].setColor(0.75,0.5,0) self.currentB = False # Do the actual collision pass (Do it only on the squares for # efficiency purposes) self.picker.traverse(self.batonsRoot) 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() self.currentB = int(self.pq.getEntry(0).getIntoNode().getTag('baton')) # Set the highlight on the picked square self.batons[self.currentB].setColor(HIGHLIGHT) self.currentB return Task.cont def click(self): if self.currentB is not False and not self.ended: self.addTorus(self.currentB) def testMorp(self, z, y, x): print(z,y,x) print([j for j in [self.org[w][y][w]for w in range(3)]if j == None]) print([j for j in [self.org[w][y][w]for w in range(3)]if j == False]) print(len([j for j in [self.org[w][y][w]for w in range(3)]if j == False])) if len([j for j in self.org[z][y] if j == None]) == 0: if len([j for j in self.org[z][y] if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in self.org[z][y] if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[z][w][x]for w in range(3)] if j == None]) == 0: if len([j for j in [self.org[z][w][x]for w in range(3)] if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[z][w][x]for w in range(3)] if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[w][y][x]for w in range(3)] if j==None]) == 0: if len([j for j in [self.org[w][y][x]for w in range(3)] if j==False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[w][y][x]for w in range(3)] if j==True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[z][w][w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[z][w][w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[z][w][w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[z][w][2 - w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[z][w][2 - w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[z][w][2 - w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[w][w][x]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[w][w][x]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[w][w][x]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[w][2-w][x]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[w][2-w][x]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[w][2-w][x]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[w][y][w]for w in range(3)]if j == None]) == 0: print("wyw") if len([j for j in [self.org[w][y][w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[w][y][w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[2-w][y][w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[2-w][y][w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[2-w][y][w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[w][w][w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[w][w][w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[w][w][w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[2-w][w][w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[2-w][w][w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[2-w][w][w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[w][w][2-w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[w][w][2-w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[w][w][2-w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" if len([j for j in [self.org[2-w][w][2-w]for w in range(3)]if j == None]) == 0: if len([j for j in [self.org[2-w][w][2-w]for w in range(3)]if j == False]) == 0: self.ended = True return "whiteWin" elif len([j for j in [self.org[2-w][w][2-w]for w in range(3)]if j == True]) == 0: self.ended = True return "blackWin" return "launched" def addTorus(self, i): minim = False for j,x in enumerate(self.torus[i]): if x is None: minim = j break if minim is not False: print(minim) print(self.whiteTurn) print() if (self.whiteTurn and not self.firstTurn) or (self.firstTurn and not (minim == 0 and i//3 == 1 and i%3 == 1)): self.torus[i][minim] = loader.loadModel("torus.egg") self.torus[i][minim].reparentTo(self.render) self.torus[i][minim].setPos(circPos(i,j-1)) self.torus[i][minim].setColor(WHITE) self.torus[i][minim].setScale(0.75,0.75,1.5) self.org[minim][i//3][i%3] = self.whiteTurn self.whiteTurn = not self.whiteTurn if self.firstTurn: self.firstTurn = False elif not self.firstTurn: self.torus[i][minim] = loader.loadModel("torus.egg") self.torus[i][minim].reparentTo(self.render) self.torus[i][minim].setPos(circPos(i,j-1)) self.torus[i][minim].setColor(BLACK) self.torus[i][minim].setScale(0.75,0.75,1.5) self.org[minim][i//3][i%3] = self.whiteTurn self.whiteTurn = not self.whiteTurn print(self.testMorp(minim, i//3, i%3)) def possibleMoves(self, state, first): possibilities = [] for r in range(9): if (((r is not 4) and first) or (not first)) and state[2][r//3][r%3] == None: possibilities.append(r) return possibilities def bestPossibleMove(self): temp = state for p in possibleMoves(self, state, first): p = 0 def valeurBranche(self, state, first, Wturn, n): vblancs = 0 vnoirs = 0 pos = [None for p in possibleMoves(self, state, first) ] depth = pos for i,p in enumerate(possibleMoves(self, state, first)): tempEtat = addTorustemp(p, WTurn, state) temp = testMorptemp(tempEtat) if temp == 1 and Wturn: pos[i] = 1 depth[i] = n + 1 elif temp ==0 and Wturn: if first: temp2 = valeurBranche(self, temp,not first, not Wturn,n+1) if not (temp2[0] == 0): pos[i] = -temp2[0] depth[i] = temp2[1] else: pos[i] = 0 depth[i] = temp2[1] else: temp2 = valeurBranche(self, temp, first, not Wturn,n+1) if not (temp2[0] == 0): pos[i] = -temp2[0] depth[i] = temp2[1] else : pos[i] = 0 depth[i] = temp2[1] elif temp == 2 and (not Wturn): pos[i] = 1 elif temp ==0 and (not Wturn): if first: temp2 = valeurBranche(self, temp,not first, not Wturn,n+1) if not (temp2[0] == 0): pos[i] = -temp2[0] depth[i] = temp2[1] else: pos[i] = 0 depth[i] = temp2[1] else: temp2 = valeurBranche(self, temp, first, not Wturn,n+1) if not (temp2[0] == 0): pos[i] = -temp2[0] depth[i] = temp2[1] else : pos[i] = 0 depth[i] = temp2[1] else: print("tu sais pas coder guillaume") if pos == []: return (0, n) else: vic = [] zero = [] for i,j in enumerate(pos): if j == 1: vic.append(i) elif j == 0: zero.append(i) if vic is not []: return 1, n elif zero is not []: dmax = 0 for i in zero: if depth[i] > dmax: dmax = depth[i] return 0, dmax else: return -1, n def addTorustemp(self, i, whiteTurn, state): minim = False temp = state for j,x in enumerate([state[w][i//3][i%3] for w in range(3)]): if x is None: minim = j break if minim is not False: print(minim) print(whiteTurn) temp[minim][i//3][i%3] = whiteTurn return temp def testMorptemp(self, torg): for m in range(27): z = m//9 y = m//3 x = m%3 if len([j for j in torg[z][y] if j == None]) == 0: if len([j for j in torg[z][y] if j == False]) == 0: return 1 elif len([j for j in torg[z][y] if j == True]) == 0: return 2 if len([j for j in [torg[z][w][x]for w in range(3)] if j == None]) == 0: if len([j for j in [torg[z][w][x]for w in range(3)] if j == False]) == 0: return 1 elif len([j for j in [torg[z][w][x]for w in range(3)] if j == True]) == 0: return 2 if len([j for j in [torg[w][y][x]for w in range(3)] if j==None]) == 0: if len([j for j in [torg[w][y][x]for w in range(3)] if j==False]) == 0: return 1 elif len([j for j in [torg[w][y][x]for w in range(3)] if j==True]) == 0: return 2 if len([j for j in [torg[z][w][w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[z][w][w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[z][w][w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[z][w][2 - w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[z][w][2 - w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[z][w][2 - w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[w][w][x]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[w][w][x]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[w][w][x]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[w][2-w][x]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[w][2-w][x]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[w][2-w][x]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[w][y][w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[w][y][w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[w][y][w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[2-w][y][w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[2-w][y][w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[2-w][y][w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[w][w][w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[w][w][w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[w][w][w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[2-w][w][w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[2-w][w][w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[2-w][w][w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[w][w][2-w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[w][w][2-w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[w][w][2-w]for w in range(3)]if j == True]) == 0: return 2 if len([j for j in [torg[2-w][w][2-w]for w in range(3)]if j == None]) == 0: if len([j for j in [torg[2-w][w][2-w]for w in range(3)]if j == False]) == 0: return 1 elif len([j for j in [torg[2-w][w][2-w]for w in range(3)]if j == True]) == 0: return 2 return 0
def __init__(self): ShowBase.__init__(self) props = WindowProperties() props.setTitle("Gesture Maze") base.win.requestProperties(props) self.tital = OnscreenText(text="Gesture Maze Control", parent=base.a2dTopLeft, align=TextNode.ALeft, pos=(0.05, -0.08), fg=(1, 1, 1, 1), scale=0.06, shadow=(0, 0, 0, 0.5)) self.accept("escape", sys.exit) camera_num = 0 self.gesture_controler = gesture_control.GestureControler(0) self.disableMouse() camera.setPosHpr(0, 0, 25, 0, -90, 0) self.maze = loader.loadModel("models/%s" % settings.maze_id) self.maze.reparentTo(render) self.walls = self.maze.find("**/wall_collide") self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # self.walls.show() self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTriggers") self.loseTriggers.append(trigger) # trigger.show() self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) self.ballGroundRay = CollisionRay() self.ballGroundRay.setOrigin(0, 0, 10) self.ballGroundRay.setDirection(0, 0, -1) self.ballGroundCol = CollisionNode("groundRay") self.ballGroundCol.addSolid(self.ballGroundRay) self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # self.ballGroundColNp.show() self.cTrav = CollisionTraverser() self.cHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # self.cTrav.showCollisions(render) ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(LVector3(0, 0, -1)) directionalLight.setColor((0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) m = Material() m.setSpecular((1, 1, 1, 1)) m.setShininess(96) self.ball.setMaterial(m, 1) self.start()
def __init__(self, music, serverVersion): self.music = music self.serverVersion = serverVersion AstronClientRepository.__init__( self, ['phase_3/etc/direct.dc', 'phase_3/etc/toon.dc']) self.loginFSM = ClassicFSM('login', [ State('off', self.enterOff, self.exitOff), State('connect', self.enterConnect, self.exitConnect), State('disconnect', self.enterDisconnect, self.exitDisconnect), State('avChoose', self.enterAvChoose, self.exitAvChoose), State('playingGame', self.enterPlayingGame, self.exitPlayingGame), State('serverUnavailable', self.enterServerUnavailable, self.exitServerUnavailable), State('makeAToon', self.enterMakeAToon, self.exitMakeAToon), State('submitNewToon', self.enterSubmitNewToon, self.exitSubmitNewToon), State('noShards', self.enterNoShards, self.exitNoShards), State('waitForSetAvatarResponse', self.enterWaitForSetAvatarResponse, self.exitWaitForSetAvatarResponse), State('waitForShardList', self.enterWaitForShardList, self.exitWaitForShardList), State('ejected', self.enterEjected, self.exitEjected), State('districtReset', self.enterDistrictReset, self.exitDistrictReset), State('died', self.enterDied, self.exitDied), State('betaInform', self.enterBetaInform, self.exitBetaInform) ], 'off', 'off') self.loginFSM.enterInitialState() self.gameFSM = ClassicFSM('game', [ State('off', self.enterGameOff, self.exitGameOff), State('waitForGameEnterResponse', self.enterWaitForGameEnterResponse, self.exitWaitForGameEnterResponse), State('playGame', self.enterPlayGame, self.exitPlayGame), State('closeShard', self.enterCloseShard, self.exitCloseShard), State('switchShards', self.enterSwitchShards, self.exitSwitchShards) ], 'off', 'off') self.gameFSM.enterInitialState() #self.taskNameAllocator = UniqueIdAllocator(0, 1000000000) self.avChooser = AvChooser(self.loginFSM) self.playGame = PlayGame(self.gameFSM, "playGameDone") self.hoodMgr = HoodMgr() self.makeAToon = MakeAToon() self.loginToken = os.environ.get("LOGIN_TOKEN") self.serverAddress = os.environ.get("GAME_SERVER") self.serverURL = URLSpec("http://%s" % self.serverAddress) self.parentMgr.registerParent(CIGlobals.SPRender, render) self.parentMgr.registerParent(CIGlobals.SPHidden, hidden) self.adminAccess = False self.localAvChoice = None self.SuitsActive = 0 self.BossActive = 0 self.accServerTimesNA = 0 self.maxAccServerTimesNA = 10 self.setZonesEmulated = 0 self.old_setzone_interest_handle = None self.setZoneQueue = Queue() self.accept(self.SetZoneDoneEvent, self._handleEmuSetZoneDone) self.handler = None self.__currentAvId = 0 self.myDistrict = None self.activeDistricts = {} self.shardListHandle = None self.uberZoneInterest = None self.isShowingPlayerIds = False self.doBetaInform = True self.dTutorial = None self.requestedName = None self.whisperNoise = base.loadSfx( 'phase_3.5/audio/sfx/GUI_whisper_3.ogg') self.checkHttp() #self.http.addPreapprovedServerCertificateFilename(self.serverURL, Filename('phase_3/etc/gameserver.crt')) #self.tournamentMusicChunks = {} #self.threadedTaskChain = taskMgr.setupTaskChain("threadedTaskChainForSoundIntervals", numThreads = 2) # Setup 3d audio base.audio3d = Audio3DManager(base.sfxManagerList[0], camera) #base.audio3d.setDistanceFactor(25) base.audio3d.setDropOffFactor(0) base.audio3d.setDopplerFactor(3.0) # Setup collision handlers base.lifter = CollisionHandlerFloor() base.pusher = CollisionHandlerPusher() base.queue = CollisionHandlerQueue() base.minigame = None base.finalExitCallbacks.insert(0, self.__handleExit) self.accountName = os.environ.get('ACCOUNT_NAME', '') self.csm = self.generateGlobalObject(DO_ID_CLIENT_SERVICES_MANAGER, 'ClientServicesManager') self.friendsManager = self.generateGlobalObject( DO_ID_FRIENDS_MANAGER, 'FriendsManager') SpeedHackChecker.startChecking() self.loginFSM.request('connect') return
class Entity(NodePath): rotation_directions = (-1, -1, 1) default_shader = None def __init__(self, add_to_scene_entities=True, **kwargs): super().__init__(self.__class__.__name__) self.name = camel_to_snake(self.type) self.enabled = True # disabled entities wil not be visible nor run code. self.visible = True self.ignore = False # if True, will not try to run code. self.eternal = False # eternal entities does not get destroyed on scene.clear() self.ignore_paused = False # if True, will still run when application is paused. useful when making a pause menu for example. self.ignore_input = False self.parent = scene # default parent is scene, which means it's in 3d space. to use UI space, set the parent to camera.ui instead. self.add_to_scene_entities = add_to_scene_entities # set to False to be ignored by the engine, but still get rendered. if add_to_scene_entities: scene.entities.append(self) self.model = None # set model with model='model_name' (without file type extention) self.color = color.white self.texture = None # set model with texture='texture_name'. requires a model to be set beforehand. self.render_queue = 0 self.double_sided = False if Entity.default_shader: self.shader = Entity.default_shader self.collision = False # toggle collision without changing collider. self.collider = None # set to 'box'/'sphere'/'mesh' for auto fitted collider. self.scripts = list( ) # add with add_script(class_instance). will assign an 'entity' variable to the script. self.animations = list() self.hovered = False # will return True if mouse hovers entity. self.origin = Vec3(0, 0, 0) self.position = Vec3( 0, 0, 0) # right, up, forward. can also set self.x, self.y, self.z self.rotation = Vec3( 0, 0, 0 ) # can also set self.rotation_x, self.rotation_y, self.rotation_z self.scale = Vec3( 1, 1, 1) # can also set self.scale_x, self.scale_y, self.scale_z self.line_definition = None # returns a Traceback(filename, lineno, function, code_context, index). if application.trace_entity_definition and add_to_scene_entities: from inspect import getframeinfo, stack _stack = stack() caller = getframeinfo(_stack[1][0]) if len(_stack) > 2 and _stack[ 1].code_context and 'super().__init__()' in _stack[ 1].code_context[0]: caller = getframeinfo(_stack[2][0]) self.line_definition = caller if caller.code_context: self.code_context = caller.code_context[0] if (self.code_context.count('(') == self.code_context.count(')') and ' = ' in self.code_context and not 'name=' in self.code_context and not 'Ursina()' in self.code_context): self.name = self.code_context.split( ' = ')[0].strip().replace('self.', '') # print('set name to:', self.code_context.split(' = ')[0].strip().replace('self.', '')) if application.print_entity_definition: print( f'{Path(caller.filename).name} -> {caller.lineno} -> {caller.code_context}' ) for key, value in kwargs.items(): setattr(self, key, value) if self.enabled and hasattr(self, 'on_enable'): if callable(self.on_enable): self.on_enable() elif isinstance(self.on_enable, Sequence): self.on_enable.start() elif not self.enabled and hasattr(self, 'on_disable'): if callable(self.on_disable): self.on_disable() elif isinstance(self.on_disable, Sequence): self.on_disable.start() def _list_to_vec(self, value): if isinstance(value, (int, float, complex)): return Vec3(value, value, value) if len(value) % 2 == 0: new_value = Vec2() for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) if len(value) % 3 == 0: new_value = Vec3() for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(value[i + 2]) return new_value def enable(self): self.enabled = True def disable(self): self.enabled = False @property def enabled(self): if not hasattr(self, '_enabled'): return True return self._enabled @enabled.setter def enabled(self, value): if value and hasattr(self, 'on_enable') and not self.enabled: if callable(self.on_enable): self.on_enable() elif isinstance(self.on_disable, Sequence): self.on_enable.start() elif value == False and hasattr(self, 'on_disable') and self.enabled: if callable(self.on_disable): self.on_disable() elif isinstance(self.on_disable, Sequence): self.on_disable.start() if value == True: if hasattr(self, 'is_singleton') and not self.is_singleton(): self.unstash() else: if hasattr(self, 'is_singleton') and not self.is_singleton(): self.stash() self._enabled = value def __setattr__(self, name, value): if name == 'eternal': for c in self.children: c.eternal = value elif name == 'model': if value is None: if hasattr(self, 'model') and self.model: self.model.removeNode() # print('removed model') object.__setattr__(self, name, value) return None if isinstance(value, NodePath): # pass procedural model if self.model is not None and value != self.model: self.model.removeNode() object.__setattr__(self, name, value) elif isinstance(value, str): # pass model asset name m = load_model(value, application.asset_folder) if not m: m = load_model( value, application.internal_models_compressed_folder) if m: if self.model is not None: self.model.removeNode() object.__setattr__(self, name, m) # if isinstance(m, Mesh): # m.recipe = value # print('loaded model successively') else: # if '.' in value: # print(f'''trying to load model with specific filename extention. please omit it. '{value}' -> '{value.split('.')[0]}' ''') print('missing model:', value) return if self.model: self.model.reparentTo(self) self.model.setTransparency(TransparencyAttrib.M_dual) self.color = self.color # reapply color after changing model self.texture = self.texture # reapply texture after changing model self._vert_cache = None if isinstance(value, Mesh): if hasattr(value, 'on_assign'): value.on_assign(assigned_to=self) return elif name == 'color' and value is not None: if isinstance(value, str): value = color.hex(value) if not isinstance(value, Vec4): value = Vec4(value[0], value[1], value[2], value[3]) if self.model: self.model.setColorScaleOff( ) # prevent inheriting color from parent self.model.setColorScale(value) object.__setattr__(self, name, value) elif name == 'collision' and hasattr(self, 'collider') and self.collider: if value: self.collider.node_path.unstash() else: self.collider.node_path.stash() object.__setattr__(self, name, value) return elif name == 'render_queue': if self.model: self.model.setBin('fixed', value) elif name == 'double_sided': self.setTwoSided(value) try: super().__setattr__(name, value) except: pass # print('failed to set attribiute:', name) @property def parent(self): try: return self._parent except: return None @parent.setter def parent(self, value): self._parent = value if value is None: destroy(self) else: try: self.reparentTo(value) except: print('invalid parent:', value) @property def world_parent(self): return self.parent @world_parent.setter def world_parent( self, value): # change the parent, but keep position, rotation and scale self.reparent_to(value) @property def type(self): # get class name. return self.__class__.__name__ @property def types( self): # get all class names including those this inhertits from. from inspect import getmro return [c.__name__ for c in getmro(self.__class__)] @property def visible(self): return self._visible @visible.setter def visible(self, value): self._visible = value if value: self.show() else: self.hide() @property def visible_self( self): # set visibility of self, without affecting children. if not hasattr(self, '_visible_self'): return True return self._visible_self @visible_self.setter def visible_self(self, value): self._visible_self = value if not self.model: return if value: self.model.show() else: self.model.hide() @property def collider(self): return self._collider @collider.setter def collider(self, value): # destroy existing collider if value and hasattr(self, 'collider') and self._collider: self._collider.remove() self._collider = value if value == 'box': if self.model: self._collider = BoxCollider(entity=self, center=-self.origin, size=self.model_bounds) else: self._collider = BoxCollider(entity=self) self._collider.name = value elif value == 'sphere': self._collider = SphereCollider(entity=self, center=-self.origin) self._collider.name = value elif value == 'mesh' and self.model: self._collider = MeshCollider(entity=self, mesh=None, center=-self.origin) self._collider.name = value elif isinstance(value, Mesh): self._collider = MeshCollider(entity=self, mesh=value, center=-self.origin) elif isinstance(value, str): m = load_model(value) if not m: return self._collider = MeshCollider(entity=self, mesh=m, center=-self.origin) self._collider.name = value self.collision = bool(self.collider) return @property def origin(self): return self._origin @origin.setter def origin(self, value): if not self.model: self._origin = Vec3(0, 0, 0) return if not isinstance(value, (Vec2, Vec3)): value = self._list_to_vec(value) if isinstance(value, Vec2): value = Vec3(*value, self.origin_z) self._origin = value self.model.setPos(-value[0], -value[1], -value[2]) @property def origin_x(self): return self.origin[0] @origin_x.setter def origin_x(self, value): self.origin = (value, self.origin_y, self.origin_z) @property def origin_y(self): return self.origin[1] @origin_y.setter def origin_y(self, value): self.origin = (self.origin_x, value, self.origin_z) @property def origin_z(self): return self.origin[2] @origin_z.setter def origin_z(self, value): self.origin = (self.origin_x, self.origin_y, value) @property def world_position(self): return Vec3(self.get_position(render)) @world_position.setter def world_position(self, value): if not isinstance(value, (Vec2, Vec3)): value = self._list_to_vec(value) if isinstance(value, Vec2): value = Vec3(*value, self.z) self.setPos(render, Vec3(value[0], value[1], value[2])) @property def world_x(self): return self.getX(render) @property def world_y(self): return self.getY(render) @property def world_z(self): return self.getZ(render) @world_x.setter def world_x(self, value): self.setX(render, value) @world_y.setter def world_y(self, value): self.setY(render, value) @world_z.setter def world_z(self, value): self.setZ(render, value) @property def position(self): return Vec3(*self.getPos()) @position.setter def position(self, value): if not isinstance(value, (Vec2, Vec3)): value = self._list_to_vec(value) if isinstance(value, Vec2): value = Vec3(*value, self.z) self.setPos(value[0], value[1], value[2]) @property def x(self): return self.getX() @x.setter def x(self, value): self.setX(value) @property def y(self): return self.getY() @y.setter def y(self, value): self.setY(value) @property def z(self): return self.getZ() @z.setter def z(self, value): self.setZ(value) @property def X(self): # shortcut for int(entity.x) return int(self.x) @property def Y(self): # shortcut for int(entity.y) return int(self.y) @property def Z(self): # shortcut for int(entity.z) return int(self.z) @property def world_rotation(self): rotation = self.getHpr(scene) return Vec3(rotation[1], rotation[0], rotation[2]) * Entity.rotation_directions @world_rotation.setter def world_rotation(self, value): self.setHpr( scene, Vec3(value[1], value[0], value[2]) * Entity.rotation_directions) @property def world_rotation_x(self): return self.world_rotation[0] @world_rotation_x.setter def world_rotation_x(self, value): self.world_rotation = Vec3(value, self.world_rotation[1], self.world_rotation[2]) @property def world_rotation_y(self): return self.world_rotation[1] @world_rotation_y.setter def world_rotation_y(self, value): self.world_rotation = Vec3(self.world_rotation[0], value, self.world_rotation[2]) @property def world_rotation_z(self): return self.world_rotation[2] @world_rotation_z.setter def world_rotation_z(self, value): self.world_rotation = Vec3(self.world_rotation[0], self.world_rotation[1], value) @property def rotation(self): rotation = self.getHpr() return Vec3(rotation[1], rotation[0], rotation[2]) * Entity.rotation_directions @rotation.setter def rotation(self, value): if not isinstance(value, (Vec2, Vec3)): value = self._list_to_vec(value) if isinstance(value, Vec2): value = Vec3(*value, self.rotation_z) self.setHpr( Vec3(value[1], value[0], value[2]) * Entity.rotation_directions) @property def rotation_x(self): return self.rotation.x @rotation_x.setter def rotation_x(self, value): self.rotation = Vec3(value, self.rotation[1], self.rotation[2]) @property def rotation_y(self): return self.rotation.y @rotation_y.setter def rotation_y(self, value): self.rotation = Vec3(self.rotation[0], value, self.rotation[2]) @property def rotation_z(self): return self.rotation.z @rotation_z.setter def rotation_z(self, value): self.rotation = Vec3(self.rotation[0], self.rotation[1], value) @property def world_scale(self): return Vec3(*self.getScale(base.render)) @world_scale.setter def world_scale(self, value): if isinstance(value, (int, float, complex)): value = Vec3(value, value, value) self.setScale(base.render, value) @property def world_scale_x(self): return self.getScale(base.render)[0] @world_scale_x.setter def world_scale_x(self, value): self.setScale(base.render, Vec3(value, self.world_scale_y, self.world_scale_z)) @property def world_scale_y(self): return self.getScale(base.render)[1] @world_scale_y.setter def world_scale_y(self, value): self.setScale(base.render, Vec3(self.world_scale_x, value, self.world_scale_z)) @property def world_scale_z(self): return self.getScale(base.render)[2] @world_scale_z.setter def world_scale_z(self, value): self.setScale(base.render, Vec3(self.world_scale_x, value, self.world_scale_z)) @property def scale(self): scale = self.getScale() return Vec3(scale[0], scale[1], scale[2]) @scale.setter def scale(self, value): if not isinstance(value, (Vec2, Vec3)): value = self._list_to_vec(value) if isinstance(value, Vec2): value = Vec3(*value, self.scale_z) value = [e if e != 0 else .001 for e in value] self.setScale(value[0], value[1], value[2]) @property def scale_x(self): return self.scale[0] @scale_x.setter def scale_x(self, value): self.setScale(value, self.scale_y, self.scale_z) @property def scale_y(self): return self.scale[1] @scale_y.setter def scale_y(self, value): self.setScale(self.scale_x, value, self.scale_z) @property def scale_z(self): return self.scale[2] @scale_z.setter def scale_z(self, value): self.setScale(self.scale_x, self.scale_y, value) @property def transform(self): # get/set position, rotation and scale return (self.position, self.rotation, self.scale) @transform.setter def transform(self, value): self.position, self.rotation, self.scale = value @property def world_transform( self): # get/set world_position, world_rotation and world_scale return (self.world_position, self.world_rotation, self.world_scale) @transform.setter def world_transform(self, value): self.world_position, self.world_rotation, self.world_scale = value @property def forward(self): # get forward direction. return render.getRelativeVector(self, (0, 0, 1)) @property def back(self): # get backwards direction. return -self.forward @property def right(self): # get right direction. return render.getRelativeVector(self, (1, 0, 0)) @property def left(self): # get left direction. return -self.right @property def up(self): # get up direction. return render.getRelativeVector(self, (0, 1, 0)) @property def down(self): # get down direction. return -self.up @property def screen_position( self): # get screen position(ui space) from world space. from ursina import camera p3 = camera.getRelativePoint(self, Vec3.zero()) full = camera.lens.getProjectionMat().xform(Vec4(*p3, 1)) recip_full3 = 1 / full[3] p2 = Vec3(full[0], full[1], full[2]) * recip_full3 screen_pos = Vec3(p2[0] * camera.aspect_ratio / 2, p2[1] / 2, 0) return screen_pos @property def shader(self): return self._shader @shader.setter def shader(self, value): self._shader = value if value is None: self.setShaderAuto() return if isinstance(value, Panda3dShader): #panda3d shader self.setShader(value) return if isinstance(value, Shader): if not value.compiled: value.compile() self.setShader(value._shader) value.entity = self for key, value in value.default_input.items(): self.set_shader_input(key, value) return print(value, 'is not a Shader') def set_shader_input(self, name, value): if isinstance(value, Texture): value = value._texture # make sure to send the panda3d texture to the shader super().set_shader_input(name, value) @property def texture(self): if not hasattr(self, '_texture'): return None return self._texture @texture.setter def texture(self, value): if value is None and self._texture: # print('remove texture') # self._texture = None self.model.clearTexture() # del self.texture # self.setTextureOff(True) return if value.__class__ is Texture: texture = value elif isinstance(value, str): texture = load_texture(value) # print('loaded texture:', texture) if texture is None: print('no texture:', value) return self.model.setTextureOff(False) if texture.__class__ is MovieTexture: self._texture = texture self.model.setTexture(texture, 1) return self._texture = texture if self.model: self.model.setTexture(texture._texture, 1) @property def texture_scale(self): if not hasattr(self, '_texture_scale'): return Vec2(1, 1) return self._texture_scale @texture_scale.setter def texture_scale(self, value): self._texture_scale = value if self.model and self.texture: self.model.setTexScale(TextureStage.getDefault(), value[0], value[1]) @property def texture_offset(self): return self._texture_offset @texture_offset.setter def texture_offset(self, value): if self.model and self.texture: self.model.setTexOffset(TextureStage.getDefault(), value[0], value[1]) self.texture = self.texture self._texture_offset = value @property def alpha(self): return self.color[3] @alpha.setter def alpha(self, value): if value > 1: value = value / 255 self.color = color.color(self.color.h, self.color.s, self.color.v, value) @property def always_on_top(self): return self._always_on_top @always_on_top.setter def always_on_top(self, value): self._always_on_top = value self.set_bin("fixed", 0) self.set_depth_write(not value) self.set_depth_test(not value) @property def billboard( self): # set to True to make this Entity always face the camera. return self._billboard @billboard.setter def billboard(self, value): self._billboard = value if value: self.setBillboardPointEye(value) def generate_sphere_map(self, size=512, name=f'sphere_map_{len(scene.entities)}'): from ursina import camera _name = 'textures/' + name + '.jpg' org_pos = camera.position camera.position = self.position base.saveSphereMap(_name, size=size) camera.position = org_pos print('saved sphere map:', name) self.model.setTexGen(TextureStage.getDefault(), TexGenAttrib.MEyeSphereMap) self.reflection_map = name def generate_cube_map(self, size=512, name=f'cube_map_{len(scene.entities)}'): from ursina import camera _name = 'textures/' + name org_pos = camera.position camera.position = self.position base.saveCubeMap(_name + '.jpg', size=size) camera.position = org_pos print('saved cube map:', name + '.jpg') self.model.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldCubeMap) self.reflection_map = _name + '#.jpg' self.model.setTexture(loader.loadCubeMap(_name + '#.jpg'), 1) @property def model_bounds(self): if self.model: bounds = self.model.getTightBounds() bounds = Vec3( Vec3(bounds[1][0], bounds[1][1], bounds[1][2]) # max point - Vec3(bounds[0][0], bounds[0][1], bounds[0][2]) # min point ) return bounds return Vec3(0, 0, 0) @property def model_center(self): if not self.model: return Vec3(0, 0, 0) return self.model.getTightBounds.getCenter() @property def bounds(self): return Vec3(self.model_bounds[0] * self.scale_x, self.model_bounds[1] * self.scale_y, self.model_bounds[2] * self.scale_z) def reparent_to(self, entity): if entity is not None: self.wrtReparentTo(entity) self._parent = entity def get_position(self, relative_to=scene): return self.getPos(relative_to) def set_position(self, value, relative_to=scene): self.setPos(relative_to, Vec3(value[0], value[1], value[2])) def add_script(self, class_instance): if isinstance(class_instance, object) and type(class_instance) is not str: class_instance.entity = self class_instance.enabled = True setattr(self, camel_to_snake(class_instance.__class__.__name__), class_instance) self.scripts.append(class_instance) # print('added script:', camel_to_snake(name.__class__.__name__)) return class_instance def combine(self, analyze=False, auto_destroy=True, ignore=[]): from ursina.scripts.combine import combine self.model = combine(self, analyze, auto_destroy, ignore) return self.model def flip_faces(self): if not hasattr(self, '_vertex_order'): self._vertex_order = True self._vertex_order = not self._vertex_order if self._vertex_order: self.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullClockwise)) else: self.setAttrib( CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) def look_at(self, target, axis='forward'): from panda3d.core import Quat if not isinstance(target, Entity): target = Vec3(*target) self.lookAt(target) if axis == 'forward': return rotation_offset = { 'back': Quat(0, 0, 1, 0), 'down': Quat(-.707, .707, 0, 0), 'up': Quat(-.707, -.707, 0, 0), 'right': Quat(-.707, 0, .707, 0), 'left': Quat(-.707, 0, -.707, 0), }[axis] self.setQuat(rotation_offset * self.getQuat()) def look_at_2d(self, target, axis='z'): from math import degrees, atan2 if isinstance(target, Entity): target = Vec3(target.world_position) pos = target - self.world_position if axis == 'z': self.rotation_z = degrees(atan2(pos[0], pos[1])) def has_ancestor(self, possible_ancestor): p = self if isinstance(possible_ancestor, Entity): # print('ENTITY') for i in range(100): if p.parent: if p.parent == possible_ancestor: return True p = p.parent if isinstance(possible_ancestor, list) or isinstance( possible_ancestor, tuple): # print('LIST OR TUPLE') for e in possible_ancestor: for i in range(100): if p.parent: if p.parent == e: return True break p = p.parent elif isinstance(possible_ancestor, str): print('CLASS NAME', possible_ancestor) for i in range(100): if p.parent: if p.parent.__class__.__name__ == possible_ancestor: return True break p = p.parent return False @property def children(self): return [e for e in scene.entities if e.parent == self] @property def attributes(self): # attribute names. used by duplicate() for instance. return ( 'name', 'enabled', 'eternal', 'visible', 'parent', 'origin', 'position', 'rotation', 'scale', 'model', 'color', 'texture', 'texture_scale', 'texture_offset', # 'world_position', 'world_x', 'world_y', 'world_z', # 'world_rotation', 'world_rotation_x', 'world_rotation_y', 'world_rotation_z', # 'world_scale', 'world_scale_x', 'world_scale_y', 'world_scale_z', # 'x', 'y', 'z', # 'origin_x', 'origin_y', 'origin_z', # 'rotation_x', 'rotation_y', 'rotation_z', # 'scale_x', 'scale_y', 'scale_z', 'render_queue', 'always_on_top', 'collision', 'collider', 'scripts') #------------ # ANIMATIONS #------------ def animate(self, name, value, duration=.1, delay=0, curve=curve.in_expo, loop=False, resolution=None, interrupt='kill', time_step=None, auto_destroy=True): animator_name = name + '_animator' # print('start animating value:', name, animator_name ) if interrupt and hasattr(self, animator_name): getattr(getattr(self, animator_name), interrupt)( ) # call kill() or finish() depending on what the interrupt value is. # print('interrupt', interrupt, animator_name) sequence = Sequence(loop=loop, time_step=time_step, auto_destroy=auto_destroy) setattr(self, animator_name, sequence) self.animations.append(sequence) sequence.append(Wait(delay)) if not resolution: resolution = max(int(duration * 60), 1) for i in range(resolution + 1): t = i / resolution t = curve(t) sequence.append(Wait(duration / resolution)) sequence.append( Func(setattr, self, name, lerp(getattr(self, name), value, t))) sequence.start() return sequence def animate_position(self, value, duration=.1, **kwargs): x = self.animate('x', value[0], duration, **kwargs) y = self.animate('y', value[1], duration, **kwargs) z = None if len(value) > 2: z = self.animate('z', value[2], duration, **kwargs) return x, y, z def animate_rotation(self, value, duration=.1, **kwargs): x = self.animate('rotation_x', value[0], duration, **kwargs) y = self.animate('rotation_y', value[1], duration, **kwargs) z = self.animate('rotation_z', value[2], duration, **kwargs) return x, y, z def animate_scale(self, value, duration=.1, **kwargs): if isinstance(value, (int, float, complex)): value = Vec3(value, value, value) return self.animate('scale', value, duration, **kwargs) # generate animation functions for e in ('x', 'y', 'z', 'rotation_x', 'rotation_y', 'rotation_z', 'scale_x', 'scale_y', 'scale_z'): exec( dedent(f''' def animate_{e}(self, value, duration=.1, delay=0, **kwargs): return self.animate('{e}', value, duration=duration, delay=delay, **kwargs) ''')) def shake(self, duration=.2, magnitude=1, speed=.05, direction=(1, 1)): import random s = Sequence() original_position = self.world_position for i in range(int(duration / speed)): s.append( Func( self.set_position, Vec3( original_position[0] + (random.uniform(-.1, .1) * magnitude * direction[0]), original_position[1] + (random.uniform(-.1, .1) * magnitude * direction[1]), original_position[2], ))) s.append(Wait(speed)) s.append(Func(setattr, self, 'world_position', original_position)) s.start() return s def animate_color(self, value, duration=.1, interrupt='finish', **kwargs): return self.animate('color', value, duration, interrupt=interrupt, **kwargs) def fade_out(self, value=0, duration=.5, **kwargs): return self.animate( 'color', Vec4(self.color[0], self.color[1], self.color[2], value), duration, **kwargs) def fade_in(self, value=1, duration=.5, **kwargs): return self.animate( 'color', Vec4(self.color[0], self.color[1], self.color[2], value), duration, **kwargs) def blink(self, value=color.clear, duration=.1, delay=0, curve=curve.in_expo_boomerang, interrupt='finish', **kwargs): return self.animate_color(value, duration=duration, delay=delay, curve=curve, interrupt=interrupt, **kwargs) def intersects(self, traverse_target=scene, ignore=(), debug=False): if isinstance(self.collider, MeshCollider): raise Exception( '''error: mesh colliders can't intersect other shapes, only primitive shapes can. Mesh colliders can "recieve" collisions though.''' ) from ursina.hit_info import HitInfo if not self.collision or not self.collider: self.hit = HitInfo(hit=False) return self.hit from ursina import distance if not hasattr(self, '_picker'): from panda3d.core import CollisionTraverser, CollisionNode, CollisionHandlerQueue from panda3d.core import CollisionRay, CollisionSegment, CollisionBox self._picker = CollisionTraverser() # Make a traverser self._pq = CollisionHandlerQueue() # Make a handler self._pickerNode = CollisionNode('raycaster') self._pickerNode.set_into_collide_mask(0) self._pickerNP = self.attach_new_node(self._pickerNode) self._picker.addCollider(self._pickerNP, self._pq) self._pickerNP.show() self._pickerNode.addSolid(self._collider.shape) if debug: self._pickerNP.show() else: self._pickerNP.hide() self._picker.traverse(traverse_target) if self._pq.get_num_entries() == 0: self.hit = HitInfo(hit=False) return self.hit ignore += (self, ) ignore += tuple([e for e in scene.entities if not e.collision]) self._pq.sort_entries() self.entries = [ # filter out ignored entities e for e in self._pq.getEntries() if e.get_into_node_path().parent not in ignore ] if len(self.entries) == 0: self.hit = HitInfo(hit=False, distance=0) return self.hit collision = self.entries[0] nP = collision.get_into_node_path().parent point = collision.get_surface_point(nP) point = Vec3(*point) world_point = collision.get_surface_point(render) world_point = Vec3(*world_point) hit_dist = distance(self.world_position, world_point) self.hit = HitInfo(hit=True) self.hit.entity = next(e for e in scene.entities if e == nP) self.hit.point = point self.hit.world_point = world_point self.hit.distance = hit_dist normal = collision.get_surface_normal( collision.get_into_node_path().parent).normalized() self.hit.normal = Vec3(*normal) normal = collision.get_surface_normal(render).normalized() self.hit.world_normal = Vec3(*normal) self.hit.entities = [] for collision in self.entries: self.hit.entities.append( next(e for e in scene.entities if e == collision.get_into_node_path().parent)) return self.hit
class Raycaster(Entity): line_model = Mesh(vertices=[Vec3(0,0,0), Vec3(0,0,1)], mode='line') def __init__(self): super().__init__( name = 'raycaster', eternal = True ) self._picker = CollisionTraverser() # Make a traverser self._pq = CollisionHandlerQueue() # Make a handler self._pickerNode = CollisionNode('raycaster') self._pickerNode.set_into_collide_mask(0) self._pickerNP = self.attach_new_node(self._pickerNode) self._picker.addCollider(self._pickerNP, self._pq) def distance(self, a, b): return sqrt(sum( (a - b)**2 for a, b in zip(a, b))) def raycast(self, origin, direction=(0,0,1), distance=inf, traverse_target=scene, ignore=list(), debug=False): self.position = origin self.look_at(self.position + direction) self._pickerNode.clearSolids() ray = CollisionRay() ray.setOrigin(Vec3(0,0,0)) ray.setDirection(Vec3(0,0,1)) self._pickerNode.addSolid(ray) if debug: temp = Entity(position=origin, model=Raycaster.line_model, scale=Vec3(1,1,min(distance,9999)), add_to_scene_entities=False) temp.look_at(self.position + direction) destroy(temp, 1/30) self._picker.traverse(traverse_target) if self._pq.get_num_entries() == 0: self.hit = HitInfo(hit=False, distance=distance) return self.hit ignore += tuple([e for e in scene.entities if not e.collision]) self._pq.sort_entries() self.entries = [ # filter out ignored entities e for e in self._pq.getEntries() if e.get_into_node_path().parent not in ignore and self.distance(self.world_position, Vec3(*e.get_surface_point(render))) <= distance ] if len(self.entries) == 0: self.hit = HitInfo(hit=False, distance=distance) return self.hit self.collision = self.entries[0] nP = self.collision.get_into_node_path().parent point = Vec3(*self.collision.get_surface_point(nP)) world_point = Vec3(*self.collision.get_surface_point(render)) hit_dist = self.distance(self.world_position, world_point) self.hit = HitInfo(hit=True, distance=distance) for e in scene.entities: if e == nP: # print('cast nP to Entity') self.hit.entity = e self.hit.point = point self.hit.world_point = world_point self.hit.distance = hit_dist self.hit.normal = Vec3(*self.collision.get_surface_normal(self.collision.get_into_node_path().parent).normalized()) self.hit.world_normal = Vec3(*self.collision.get_surface_normal(render).normalized()) return self.hit self.hit = HitInfo(hit=False, distance=distance) return self.hit def boxcast(self, origin, direction=(0,0,1), distance=9999, thickness=(1,1), traverse_target=scene, ignore=list(), debug=False): if isinstance(thickness, (int, float, complex)): thickness = (thickness, thickness) temp = Entity( position=origin, model='cube', origin_z=-.5, scale=Vec3(abs(thickness[0]), abs(thickness[1]), abs(distance)), collider='box', color=color.white33, always_on_top=debug, visible=debug ) temp.look_at(origin + direction) hit_info = temp.intersects(traverse_target=traverse_target, ignore=ignore) if hit_info.world_point: hit_info.distance = ursinamath.distance(origin, hit_info.world_point) else: hit_info.distance = distance if debug: temp.collision = False temp.scale_z = hit_info.distance destroy(temp, delay=.2) else: destroy(temp) return hit_info
def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0, } # Post the instructions self.title = addTitle( "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.06, "[ESC]: Quit") self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward") self.inst5 = addInstructions(0.30, "[Down Arrow]: Walk Ralph Backward") self.inst6 = addInstructions(0.36, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.42, "[S]: Rotate Camera Right") # Set up the environment # # This environment model contains collision meshes. If you look # in the egg file, you will see the following: # # <Collide> { Polyset keep descend } # # This tag causes the following mesh to be converted to a collision # mesh -- a mesh which is optimized for collision, not rendering. # It also keeps the original mesh, so there are now two copies --- # one optimized for rendering, one for collisions. self.environ = loader.loadModel("models/world") self.environ.reparentTo(render) # We do not have a skybox, so we will just use a sky blue background color self.setBackgroundColor(0.53, 0.80, 0.92, 1) # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos + (0, 0, 1.5)) # Create a floater object, which floats 2 units above ralph. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.ralph) self.floater.setZ(2.0) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["backward", True]) self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["backward", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) taskMgr.add(self.move, "moveTask") # Set up the camera self.disableMouse() self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2) self.cTrav = CollisionTraverser() # Use a CollisionHandlerPusher to handle collisions between Ralph and # the environment. Ralph is added as a "from" object which will be # "pushed" out of the environment if he walks into obstacles. # # Ralph is composed of two spheres, one around the torso and one # around the head. They are slightly oversized since we want Ralph to # keep some distance from obstacles. self.ralphCol = CollisionNode('ralph') self.ralphCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5)) self.ralphCol.addSolid( CollisionSphere(center=(0, -0.25, 4), radius=1.5)) self.ralphCol.setFromCollideMask(CollideMask.bit(0)) self.ralphCol.setIntoCollideMask(CollideMask.allOff()) self.ralphColNp = self.ralph.attachNewNode(self.ralphCol) self.ralphPusher = CollisionHandlerPusher() self.ralphPusher.horizontal = True # Note that we need to add ralph both to the pusher and to the # traverser; the pusher needs to know which node to push back when a # collision occurs! self.ralphPusher.addCollider(self.ralphColNp, self.ralph) self.cTrav.addCollider(self.ralphColNp, self.ralphPusher) # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above ralph's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 9) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0)) self.ralphGroundCol.setIntoCollideMask(CollideMask.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays #self.ralphColNp.show() #self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight))