Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
class Boule_feu(Arme):
    def __init__(self, parent):
        Arme.__init__(self, parent)
        # init du rayon de la mort
        self.ray = CollisionRay(0, 0, 0, 0, 1, 0)
        rayNode = CollisionNode("boule_feu")
        rayNode.addSolid(self.ray)
        mask = BitMask32()
        mask.setBit(2)
        rayNode.setFromCollideMask(mask)
        maskI = BitMask32()
        maskI.setBit(0)
        rayNode.setIntoCollideMask(maskI)
        self.rayNodePath = render.attachNewNode(rayNode)
        self.rayQueue = CollisionHandlerQueue()
        self.parent.base.cTrav.addCollider(self.rayNodePath, self.rayQueue)
        self.ray.setOrigin(12, 9, 7)
        self.ray.setDirection(self.parent.heros.actor.getPos() -
                              self.parent.sorcier.obj.getPos())
        self.rayNodePath.show()

    def update(self, keys, dt):
        self.ray.setDirection(self.parent.heros.actor.getPos() -
                              self.parent.sorcier.obj.getPos())
        if self.rayQueue.getNumEntries() > 0:
            self.rayQueue.sortEntries()
            rayHit = self.rayQueue.getEntry(0)
            hitPos = rayHit.getSurfacePoint(render)
            hitNodePath = rayHit.getIntoNodePath()
            print(hitNodePath)
Exemplo n.º 3
0
    def initHero(self):
        self.hero = loader.loadModel("charaRoot")
        self.hero.reparentTo(self.stage)
        model = base.gameData.heroModel
        self.heroArmature = Actor(
            "{}".format(model), {
                "idle": "{}-idle".format(model),
                "walk": "{}-run".format(model)
            })
        self.heroArmature.reparentTo(self.hero)
        self.hero.setPos(self.startPos)
        cNode = CollisionNode('hero')
        cNode.addSolid(CollisionSphere(0, 0, 1.5, 1))
        heroCollision = self.hero.attachNewNode(cNode)
        #########################################################
        # heroCollision.show()

        self.pusher.addCollider(
            heroCollision, self.hero, base.drive.node())
        base.cTrav.addCollider(heroCollision, self.pusher)

        heroGroundRay = CollisionRay()
        heroGroundRay.setOrigin(0, 0, 9)
        heroGroundRay.setDirection(0, 0, -1)
        heroGroundCol = CollisionNode('heroRay')
        heroGroundCol.addSolid(heroGroundRay)
        heroGroundCol.setFromCollideMask(CollideMask.bit(0))
        heroGroundCol.setIntoCollideMask(CollideMask.allOff())
        heroGroundColNp = self.hero.attachNewNode(heroGroundCol)
        #########################################################
        # heroGroundColNp.show()

        base.cTrav.addCollider(heroGroundColNp, self.heroGroundHandler)
        self.controlCamera()
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
def colRay(parent, origin=(0,0,0.1), direction=(0,0,-1)):
    ray = CollisionRay()
    ray.setOrigin(origin)
    ray.setDirection(direction)
    col = CollisionNode(parent.getName()+"-ray")
    col.addSolid(ray)
    col.setIntoCollideMask(CollideMask.allOff())
    colNode = parent.attachNewNode(col)
    handler = CollisionHandlerQueue()
    base.cTrav.addCollider(colNode, handler)
    #colNode.show()
    return handler
Exemplo n.º 6
0
 def createMouseCollisions(self):
     # Fire the portals
     firingNode = CollisionNode('mouseRay')
     firingNP = self.base.camera.attachNewNode(firingNode)
     firingNode.setFromCollideMask(COLLISIONMASKS['geometry'])
     firingNode.setIntoCollideMask(BitMask32.allOff())
     firingRay = CollisionRay()
     firingRay.setOrigin(0,0,0)
     firingRay.setDirection(0,1,0)
     firingNode.addSolid(firingRay)
     self.firingHandler = CollisionHandlerQueue()
     self.base.cTrav.addCollider(firingNP, self.firingHandler)
Exemplo n.º 7
0
class MouseCollision:
    def __init__(self, game):

        self.game = game

        self.c_trav = CollisionTraverser()

        self.mouse_groundHandler = CollisionHandlerQueue()
        self.mouse_ground_ray = CollisionRay()
        self.mouse_ground_col = CollisionNode('mouseRay')

        self.mouse_ground_ray.setOrigin(0, 0, 0)
        self.mouse_ground_ray.setDirection(0, -1, 0)

        self.mouse_ground_col.addSolid(self.mouse_ground_ray)
        self.mouse_ground_col.setFromCollideMask(CollideMask.bit(0))
        self.mouse_ground_col.setIntoCollideMask(CollideMask.allOff())

        self.mouse_ground_col_np = self.game.camera.attachNewNode(
            self.mouse_ground_col)

        self.c_trav.addCollider(self.mouse_ground_col_np,
                                self.mouse_groundHandler)

        self.game.taskMgr.add(self.update, 'updateMouse')

    def update(self, task):

        if self.game.mouseWatcherNode.hasMouse():
            if self.game.ship.model:

                mouse_pos = self.game.mouseWatcherNode.getMouse()

                self.mouse_ground_ray.setFromLens(self.game.camNode,
                                                  mouse_pos.getX(),
                                                  mouse_pos.getY())

                near_point = render.getRelativePoint(
                    self.game.camera, self.mouse_ground_ray.getOrigin())
                near_vec = render.getRelativeVector(
                    self.game.camera, self.mouse_ground_ray.getDirection())

                self.game.ship.shipPoint.setPos(
                    self.PointAtY(self.game.ship.model.getY(), near_point,
                                  near_vec))

        return task.cont

    def PointAtY(self, y, point, vec):
        return point + vec * ((y - point.getY()) / vec.getY())
Exemplo n.º 8
0
class PlayerObject():
	def __init__(self, render, player):
		self.username = player.getUsername()
		self.isMoving = False
		self.render = render

		self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}

		self.actor = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"})
		self.actor.reparentTo(render)
		self.actor.setScale(0.2)
		self.actor.setPos(player.getX(), player.getY(), player.getZ())
		self.actor.setH(player.getH())

		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 getUsername(self):
# 		return self.username
	
	def getActor(self):
		return self.actor
	
	def setPos(self, x, y, z):
		self.actor.setPos(x, y, z)
		
	def setH(self, h):
		self.actor.setH(h)

	def move(self, isActorMove):
		if isActorMove == "True":
			if self.isMoving is False:
				self.actor.loop("run")
				self.isMoving = True
		else:
			if self.isMoving:
				self.actor.stop()
				self.actor.pose("walk",5)
				self.isMoving = False
Exemplo n.º 9
0
    def setupCollisionRay(self,
                          node,
                          origin=(0, 0, 0),
                          direction=(0, 0, 0),
                          name=None):
        ray = CollisionRay()
        ray.setOrigin(origin)
        ray.setDirection(direction)

        col = CollisionNode(name)
        col.addSolid(ray)
        col.setFromCollideMask(CollideMask.bit(0))
        col.setIntoCollideMask(CollideMask.allOff())
        colNode = node.attachNewNode(col)
        queue = CollisionHandlerQueue()
        self.cTrav.addCollider(colNode, queue)

        return queue
Exemplo n.º 10
0
class MouseCollision:
    def __init__(self, game):

        self.game = game

        self.c_trav = CollisionTraverser()

        self.mouse_groundHandler = CollisionHandlerQueue()
        self.mouse_ground_ray = CollisionRay()
        self.mouse_ground_col = CollisionNode('mouseRay')

        self.mouse_ground_ray.setOrigin(0, 0, 0)
        self.mouse_ground_ray.setDirection(0, -1, 0)

        self.mouse_ground_col.addSolid(self.mouse_ground_ray)
        self.mouse_ground_col.setFromCollideMask(CollideMask.bit(0))
        self.mouse_ground_col.setIntoCollideMask(CollideMask.allOff())

        self.mouse_ground_col_np = self.game.camera.attachNewNode(self.mouse_ground_col)

        self.c_trav.addCollider(self.mouse_ground_col_np, self.mouse_groundHandler)

        self.game.taskMgr.add(self.update, 'updateMouse')

    def update(self, task):

        if self.game.mouseWatcherNode.hasMouse():
            if self.game.ship.model:

                mouse_pos = self.game.mouseWatcherNode.getMouse()

                self.mouse_ground_ray.setFromLens(self.game.camNode, mouse_pos.getX(), mouse_pos.getY())

                near_point = render.getRelativePoint(self.game.camera, self.mouse_ground_ray.getOrigin())
                near_vec = render.getRelativeVector(self.game.camera, self.mouse_ground_ray.getDirection())

                self.game.ship.shipPoint.setPos(self.PointAtY(self.game.ship.model.getY(), near_point, near_vec))

        return task.cont

    def PointAtY(self, y, point, vec):
        return point + vec * ((y - point.getY()) / vec.getY())
Exemplo n.º 11
0
class PlayerInput(DirectObject):
	
	"""
	PlayerInput Class:
	Handels all inputs.
	"""
	
	def __init__(self):
		
		# Should make a method to get active players.
		self.activePlayer = ACTIVE_ACTORS['Player'].playerActor
		self.activePlayerSpeed = ACTIVE_ACTORS['Player'].playerSpeed
		
		# Set the control maps.
		self.controlMap = {"left": 0, "right": 0, "forward": 0, "backward": 0, "jump": 0, "wheel-in": 0, "wheel-out": 0}  
		self.mousebtn = [0, 0, 0]
		
		# 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)
		
		### SETUP KEYBOARD ###
		# Setup the control [KEYS] for movement w,a,s,d.
		self.accept("escape", sys.exit)
		self.accept("w", self.setControl, ["forward", 1])
		self.accept("a", self.setControl, ["left", 1])
		self.accept("s", self.setControl, ["backward", 1])
		self.accept("d", self.setControl, ["right", 1])
		self.accept("space", self.setControl, ["jump", 1])
		
		self.accept("w-up", self.setControl, ["forward", 0])
		self.accept("a-up", self.setControl, ["left", 0])
		self.accept("s-up", self.setControl, ["backward", 0])
		self.accept("d-up", self.setControl, ["right", 0])
		self.accept("space-up", self.setControl, ["jump", 0])
		
		# Setup mouse [ZOOM].
		self.accept("wheel_up", self.setControl, ["wheel-in", 1])
		self.accept("wheel_down", self.setControl, ["wheel-out", 1])
		
		# Add the "moveTask"
		taskMgr.add(self.move, "moveTask")
		
		# Game State Variable.
		self.isMoving = False
		###>
		
		###  SETUP CAMERA  ###
		# Reparent the -main- Camera to playerActor.
		base.camera.reparentTo(self.activePlayer)
		self.cameraTargetHeight = 6.0
		self.cameraDistance = 30
		self.cameraPitch = 10 
		base.disableMouse()
		# This should be used together with a right click function, for the camera rotate. Like in wow.
		WinProps = WindowProperties()
		# Hide the cursor. | This will change with the rightClick function. 
		# Giving us the cursor when not rotating. If the player wants to rotate basic [KEYS] left/right can turn while cursor is active.
		WinProps.setCursorHidden(True) 
		base.win.requestProperties(WinProps)
		#base.camera.setPos(self.activePlayer.getX(),self.activePlayer.getY()+10,2)
		
		# FROM THE ROAMING RALPH TUT>
		# 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.actorGroundRay = CollisionRay()
		self.actorGroundRay.setOrigin(0,0,1000)
		self.actorGroundRay.setDirection(0,0,-1)
		self.actorGroundCol = CollisionNode('actorRay')
		self.actorGroundCol.addSolid(self.actorGroundRay)
		self.actorGroundCol.setFromCollideMask(BitMask32.bit(0))
		self.actorGroundCol.setIntoCollideMask(BitMask32.allOff())
		self.actorGroundColNp = self.activePlayer.attachNewNode(self.actorGroundCol)
		self.actorGroundHandler = CollisionHandlerQueue()
		cTrav.addCollider(self.actorGroundColNp, self.actorGroundHandler)

		# 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.activePlayer.attachNewNode(self.cameraCol) 
		self.cameraColHandler = CollisionHandlerQueue() 
		cTrav.addCollider(self.cameraColNp, self.cameraColHandler) 

		# Uncomment this line to see the collision rays
		self.actorGroundColNp.show()
		self.cameraColNp.show()
	   
		# Uncomment this line to show a visual representation of the 
		# collisions occuring
		cTrav.showCollisions(render)
		
		###>
		
	# Check the state of the KB.
	def setControl(self, key, value):
		self.controlMap[key] = value
		
	def move(self, task):
		
		self.actorPos = self.activePlayer.getPos()
		# Check if a-move key is pressed, if so move.
		# Forward.
		if (self.controlMap["forward"] != 0):
			self.activePlayer.setY(self.activePlayer, -self.activePlayerSpeed * globalClock.getDt())
		# Backward.
		if (self.controlMap["backward"] != 0):
			self.activePlayer.setY(self.activePlayer, self.activePlayerSpeed * globalClock.getDt())
		# Left.
		if (self.controlMap["left"] != 0):
			self.activePlayer.setX(self.activePlayer, self.activePlayerSpeed * globalClock.getDt())
		# Right.
		if (self.controlMap["right"] != 0):
			self.activePlayer.setX(self.activePlayer, -self.activePlayerSpeed * globalClock.getDt())
			
		if (self.controlMap["jump"] != 0):
			print "Jump now...!?"
		
		# Check for zooming and Do.
		if (self.controlMap["wheel-in"] != 0):
			self.cameraDistance -= 0.1 * self.cameraDistance
			if  (self.cameraDistance < 5):
				self.cameraDistance = 5
			self.controlMap["wheel-in"] = 0
		
		elif (self.controlMap["wheel-out"] != 0):
			self.cameraDistance += 0.1 * self.cameraDistance
			if (self.cameraDistance > 250):
				self.cameraDistance = 250
			self.controlMap["wheel-out"] = 0
			
		# Make use of mouse, to turn.
		if base.mouseWatcherNode.hasMouse():
			
			# get changes in mouse position
			md = base.win.getPointer(0)
			x = md.getX()
			y = md.getY()
			
			deltaX = md.getX() - 200
			deltaY = md.getY() - 200
			
			# reset mouse cursor position
			base.win.movePointer(0, 200, 200)
			
			# Mouse speed setting
			mouseSpeed = 0.3
			
			# alter the actor yaw by an amount proportionate to deltaX
			self.activePlayer.setH(self.activePlayer.getH() - mouseSpeed* deltaX)

			# find the new camera pitch and clamp it to a reasonable range
			self.cameraPitch = self.cameraPitch + 0.1 * deltaY
			if (self.cameraPitch < -60): self.cameraPitch = -60
			if (self.cameraPitch >  80): self.cameraPitch =  80
			base.camera.setHpr(0,self.cameraPitch,0)
			
			# set the camera at around middle of the ship
			# We should pivot around here instead of the view target which is noticebly higher
			base.camera.setPos(0,0,self.cameraTargetHeight/2)
			# back the camera out to its proper distance
			base.camera.setY(base.camera,self.cameraDistance)
		
		# point the camera at the view target 
		viewTarget = Point3(0,0,self.cameraTargetHeight) 
		base.camera.lookAt(viewTarget) 
		# reposition the end of the  camera's obstruction ray trace 
		self.cameraRay.setPointB(base.camera.getPos())
		
		# If ralph is moving, loop the run animation.
		# If he is standing still, stop the animation.

		if (self.controlMap["forward"]!=0) or (self.controlMap["left"]!=0) or (self.controlMap["right"]!=0):
			if self.isMoving is False:
				self.activePlayer.loop("run")
				self.isMoving = True
		else:
			if self.isMoving:
				self.activePlayer.stop()
				self.activePlayer.pose("walk",5)
				self.isMoving = False
		
		# Now check for collisions.

		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.actorGroundHandler.getNumEntries()):
			entry = self.actorGroundHandler.getEntry(i)
			entries.append(entry)
		entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
									 x.getSurfacePoint(render).getZ()))
		if (len(entries)>0) and (entries[0].getIntoNode().getName() == "ground"):
			self.activePlayer.setZ(entries[0].getSurfacePoint(render).getZ())
		else:
			self.activePlayer.setPos(self.actorPos)
		
		# Go through the BALL_DICT which is not a list and needs a new name :P 
		# And find the ball being colided with. and then del. it
		for ball in BALL_LIST:
			if (len(entries)>0) and (entries[0].getIntoNode().getName() == str(ball)):
				print "Collide with ", entries[0].getIntoNode().getName()
				del BALL_LIST[ball]
				BALL_LIST[ball] = None



		# Keep the camera at one foot above the terrain,
		# or two feet above ralph, whichever is greater.
		
		entries = [] 
		for i in range(self.cameraColHandler.getNumEntries()): 
			entry = self.cameraColHandler.getEntry(i) 
			entries.append(entry) 
		entries.sort(lambda x,y: cmp(-y.getSurfacePoint(self.activePlayer).getY(), 
									 -x.getSurfacePoint(self.activePlayer).getY())) 
		if (len(entries)>0): 
			collisionPoint =  entries[0].getSurfacePoint(self.activePlayer) 
			collisionVec = ( viewTarget - collisionPoint) 
			if ( collisionVec.lengthSquared() < self.cameraDistance * self.cameraDistance ): 
				base.camera.setPos(collisionPoint) 
				if (entries[0].getIntoNode().getName() == "ground"): 
					base.camera.setZ(base.camera, 0.2) 
				base.camera.setY(base.camera, 0.3) 
				
		return task.cont   
Exemplo n.º 12
0
class MousePicker(object):
    def __init__(self,
                 pickTag='MyPickingTag',
                 nodeName='pickRay',
                 showCollisions=False):
        self.pickTag = pickTag
        self.nodeName = nodeName
        self.showCollisions = showCollisions

    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 mousePick(self, traverse=None, tag=None):
        #do we have a mouse
        if (base.mouseWatcherNode.hasMouse() == False):
            return None, None

        traverse = traverse or base.render
        tag = tag or self.pickTag

        mpos = base.mouseWatcherNode.getMouse()

        #Set the position of the ray based on the mouse position
        self.mPickRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
        self.mPickerTraverser.traverse(traverse)

        if (self.mCollisionQue.getNumEntries() > 0):
            self.mCollisionQue.sortEntries()

            for entry in self.mCollisionQue.getEntries():
                pickedObj = entry.getIntoNodePath()
                pickedObj = pickedObj.findNetTag(tag)

                if not pickedObj.isEmpty():
                    pos = entry.getSurfacePoint(base.render)
                    return pickedObj, pos

        return None, None

    def mousePick2D(self, traverse=None, tag=None, all=False):
        #do we have a mouse
        if (base.mouseWatcherNode.hasMouse() == False):
            return None, None

        traverse = traverse or base.render
        tag = tag or self.pickTag

        mpos = base.mouseWatcherNode.getMouse()

        self.mPickRay2D.setFromLens(base.cam2d.node(), mpos.getX(),
                                    mpos.getY())

        self.mPickerTraverser2D.traverse(base.aspect2d)

        if self.mCollisionQue2D.getNumEntries() > 0:
            self.mCollisionQue2D.sortEntries()

            if all:
                return [(entry.getIntoNodePath().findNetTag(tag),
                         entry.getSurfacePoint(base.aspect2d))
                        for entry in self.mCollisionQue2D.getEntries()], None
            else:
                entry = self.mCollisionQue2D.getEntry(0)
                pickedObj = entry.getIntoNodePath()

                pickedObj = pickedObj.findNetTag(tag)
                if not pickedObj.isEmpty():
                    pos = entry.getSurfacePoint(base.aspect2d)
                    return pickedObj, pos

        return None, None
Exemplo n.º 13
0
class Usuario(object):
    '''
    Usuario
    '''
    def __init__(self):
        self.habilitado = False

        self.estaMovendo = False
        self.estaRodando = False
        self.timeIniMover = 0
        self.timeIniRodar = 0
        self.keyMap = {
            TECLA_esquerda: EVENT_up,
            TECLA_direita: EVENT_up,
            TECLA_frente: EVENT_up,
            TECLA_traz: EVENT_up
        }

        self.login = None
        self.senha = None
        self.nick = None

        self.vida_real = None
        self.vida_total = None
        self.mana_real = None
        self.mana_total = None
        self.forca = None
        self.velocidade = None
        self.velocidade_atack = None

        self.key = None
        self.addr = None
        self.login = None

        pandaFileModelo = get_path_modelo("ralph")

        self.__modelo = Actor(pandaFileModelo)
        self.__modelo.reparentTo(render)
        self.__modelo.setScale(SCALE_MODELOS)

        modeloStartPos = vinerWorld.mapa.modelo.find("**/start_point").getPos()
        self.set_pos(modeloStartPos)

        self.__setup_collision()

    def get_x(self):
        return self.__modelo.getX()

    def get_y(self):
        return self.__modelo.getY()

    def get_z(self):
        return self.__modelo.getZ()

    def get_h(self):
        return self.__modelo.getH()

    def get_pos(self):
        return self.__modelo.getPos()

    def set_x(self, x):
        self.__modelo.setX(x)

    def set_y(self, y):
        self.__modelo.setY(y)

    def set_z(self, z):
        self.__modelo.setZ(z)

    def set_h(self, h):
        self.__modelo.setH(h)

    def set_pos(self, pos):
        self.__modelo.setPos(pos)

    def get_dados(self):

        return [
            self.key,
            self.nick,
            self.vida_real,
            self.vida_total,
            self.mana_real,
            self.mana_total,
            self.forca,
            self.velocidade,
            self.velocidade_atack,
            self.get_x(),
            self.get_y(),
            self.get_z(),
            self.get_h(),
        ]

    def stop_task_movimentacao(self):
        taskMgr.remove(self.key)

    def inicia_task_movimentacao(self):
        if self.key != "":
            taskMgr.add(self.__task_movimentacao, self.key, sort=1)

    def __setup_collision(self):
        #Colisao
        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 5)
        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.__modelo.attachNewNode(
            self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()

        base.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)
        #Colisao

    def __task_movimentacao(self, task):
        dt = globalClock.getDt()
        startpos = self.__modelo.getPos()

        #rodar usuario
        if self.keyMap[TECLA_esquerda] == EVENT_down and self.keyMap[
                TECLA_direita] == EVENT_up:

            if time.time() < self.timeIniRodar + 4:
                self.estaRodando = True

                self.__modelo.setH(self.__modelo, ((self.velocidade * 5) * dt))
            else:
                h = self.get_h()
                vinerOnline.envia_pacote_todos(
                    1, ACAO_CLIENT_rodar,
                    [self.key, TECLA_esquerda, EVENT_up, h])

                self.estaRodando = False
                self.keyMap[TECLA_esquerda] = EVENT_up

        elif self.keyMap[TECLA_direita] == EVENT_down and self.keyMap[
                TECLA_esquerda] == EVENT_up:

            if time.time() < self.timeIniRodar + 4:
                self.estaRodando = True

                self.__modelo.setH(self.__modelo,
                                   ((self.velocidade * 5) * dt) * -1)
            else:
                h = self.get_h()
                vinerOnline.envia_pacote_todos(
                    1, ACAO_CLIENT_rodar,
                    [self.key, TECLA_direita, EVENT_up, h])

                self.estaRodando = False
                self.keyMap[TECLA_direita] = EVENT_up
        elif self.estaRodando:
            self.estaRodando = False
        #rodar usuario

        #mover usuario
        if self.keyMap[TECLA_frente] == EVENT_down and self.keyMap[
                TECLA_traz] == EVENT_up:

            if time.time() < self.timeIniMover + 4:
                self.estaMovendo = True

                self.__modelo.setY(self.__modelo,
                                   ((self.velocidade * 2) * dt) * -1)
            else:
                x = self.get_x()
                y = self.get_y()
                z = self.get_z()
                vinerOnline.envia_pacote_todos(
                    1, ACAO_CLIENT_mover,
                    [self.key, TECLA_frente, EVENT_up, x, y, z])

                self.estaMovendo = False
                self.keyMap[TECLA_frente] = EVENT_up

        elif self.keyMap[TECLA_traz] == EVENT_down and self.keyMap[
                TECLA_frente] == EVENT_up:

            if time.time() < self.timeIniMover + 4:
                self.estaMovendo = True

                self.__modelo.setY(self.__modelo, (self.velocidade * dt))
            else:
                x = self.get_x()
                y = self.get_y()
                z = self.get_z()
                vinerOnline.envia_pacote_todos(
                    1, ACAO_CLIENT_mover,
                    [self.key, TECLA_traz, EVENT_up, x, y, z])

                self.estaMovendo = False
                self.keyMap[TECLA_traz] = EVENT_up

        elif self.estaMovendo:
            self.estaMovendo = False
        #mover usuario

        #se esta moventdo trata colisao
        if self.estaMovendo:

            base.cTrav.traverse(render)

            if self.ralphGroundHandler.getNumEntries() == 1:
                entry = self.ralphGroundHandler.getEntry(0)
                if entry.getIntoNode().getName() == "terrain":
                    self.__modelo.setZ(entry.getSurfacePoint(render).getZ())
            else:
                self.__modelo.setPos(startpos)
        #se esta moventdo trata colisao

        return task.cont
Exemplo n.º 14
0
class World(DirectObject):

    def __init__(self):
        #create Queue to hold the incoming chat
        #request the heartbeat so that the caht interface is being refreshed in order to get the message from other player
        
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "charge":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        self.cManager = ConnectionManager()
        self.cManager.startConnection()
        #------------------------------
        #Chat
        Chat(self.cManager)
        
        
        #send dummy login info of the particular client
        #send first chat info 
        #---------------------------------------
        self.userName = username
        dummy_login ={'user_id' : self.userName, 'factionId': faction, 'password': '******'}
        self.cManager.sendRequest(Constants.RAND_STRING, dummy_login)
        
        
        chat = { 'userName' : self.userName,     #username
                 'message'    : '-------Login------' }
        self.cManager.sendRequest(Constants.CMSG_CHAT, chat)

        #--------------------------------------
        #self.minimap = OnscreenImage(image="images/minimap.png", scale=(0.2,1,0.2), pos=(-1.1,0,0.8))

        #frame = DirectFrame(text="Resource Bar", scale=0.001)

        resource_bar = DirectWaitBar(text="",
            value=35, range=100, pos=(0,0,0.9), barColor=(255,255,0,1),
            frameSize=(-0.3,0.3,0,0.03))
        cp_bar = DirectWaitBar(text="",
            value=70, range=100, pos=(1.0,0,0.9), barColor=(0,0,255,1),
            frameSize=(-0.3,0.3,0,0.03), frameColor=(255,0,0,1))

        # 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)
        self.environ.setPos(0,0,0)
        
        # 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)

        nameplate = TextNode('textNode username_' + str(self.userName))
        nameplate.setText(self.userName)
        npNodePath = self.ralph.attachNewNode(nameplate)
        npNodePath.setScale(0.8)
        npNodePath.setBillboardPointEye()
        #npNodePath.setPos(1.0,0,6.0)
        npNodePath.setZ(6.5)

        bar = DirectWaitBar(value=100, scale=1.0)
        bar.setColor(255,0,0)
        #bar.setBarRelief()
        bar.setZ(6.0)
        bar.setBillboardPointEye()
        bar.reparentTo(self.ralph)

        # 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("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])
        self.accept("c", self.setKey, ["charge",1])
        self.accept("c-up", self.setKey, ["charge",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        
        # 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
    

    # 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())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -25 * globalClock.getDt())
        if (self.keyMap["charge"]!=0):
            self.ralph.setY(self.ralph, -250 * globalClock.getDt())
            #ribbon = Ribbon(self.ralph, Vec4(1,1,1,1), 3, 10, 0.3)
            #ribbon.getRoot().setZ(2.0)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"]!=0) or (self.keyMap["charge"]!=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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        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
Exemplo n.º 15
0
class Usuario(object):
    """
    Usuario
    """

    def __init__(self, dadosUsuario, principal=False):
        self.key = dadosUsuario["key"]
        self.nick = dadosUsuario["nick"]
        self.vida_real = float(dadosUsuario["vida_real"])
        self.vida_total = float(dadosUsuario["vida_total"])
        self.mana_real = float(dadosUsuario["mana_real"])
        self.mana_total = float(dadosUsuario["mana_total"])
        self.forca = float(dadosUsuario["forca"])
        self.velocidade = float(dadosUsuario["velocidade"])
        self.velocidade_atack = float(dadosUsuario["velocidade_atack"])

        self.estaMovendo = False
        self.estaRodando = False

        self.__task_name = "Task Usuario - " + self.key

        self.keyMap = {TECLA_esquerda: EVENT_up, TECLA_direita: EVENT_up, TECLA_frente: EVENT_up, TECLA_traz: EVENT_up}

        pandaFileModelo = get_path_modelo("ralph")
        pandaFileAnimacaoRun = get_path_animacao("ralph-run")
        pandaFileAnimacaoWalk = get_path_animacao("ralph-walk")

        self.modelo = Actor(pandaFileModelo, {"run": pandaFileAnimacaoRun, "walk": pandaFileAnimacaoWalk})
        self.modelo.reparentTo(render)
        self.modelo.setScale(SCALE_MODELOS)

        self.set_pos((float(dadosUsuario["x"]), float(dadosUsuario["y"]), float(dadosUsuario["z"])))
        self.set_h(float(dadosUsuario["h"]))

        if not principal:
            self.text = Text(
                parent=self.modelo, pos=(0, 0, 5.5), scale=0.5, align="center", cor=COR_VERDE, text=self.nick
            )

            self.text.billboardEffect()

        self.__setup_collision()

        taskMgr.add(self.__task_movimentacao, self.__task_name, sort=1)

    def get_x(self):
        return self.modelo.getX()

    def get_y(self):
        return self.modelo.getY()

    def get_z(self):
        return self.modelo.getZ()

    def get_h(self):
        return self.modelo.getH()

    def get_pos(self):
        return self.modelo.getPos()

    def set_x(self, x):
        self.modelo.setX(x)

    def set_y(self, y):
        self.modelo.setY(y)

    def set_z(self, z):
        self.modelo.setZ(z)

    def set_h(self, h):
        self.modelo.setH(h)

    def set_pos(self, pos):
        self.modelo.setPos(pos)

    def delete(self):
        taskMgr.remove(self.__task_name)

        self.modelo.delete()

    def __setup_collision(self):
        # Colisao
        self.cTrav = CollisionTraverser("usuarioTraverser")

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 5)
        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.modelo.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()

        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        # self.ralphGroundColNp.show()
        # self.cTrav.showCollisions(render)
        # Colisao

    def __task_movimentacao(self, task):
        dt = globalClock.getDt()
        startpos = self.modelo.getPos()

        # movimentos usuario modelo
        if self.keyMap[TECLA_esquerda] == EVENT_down and self.keyMap[TECLA_direita] == EVENT_up:
            self.modelo.setH(self.modelo, ((self.velocidade * 5) * dt))

            if not self.estaRodando:
                self.estaRodando = True

        elif self.keyMap[TECLA_direita] == EVENT_down and self.keyMap[TECLA_esquerda] == EVENT_up:
            self.modelo.setH(self.modelo, ((self.velocidade * 5) * dt) * -1)

            if not self.estaRodando:
                self.estaRodando = True

        elif self.estaRodando:
            self.estaRodando = False

        if self.keyMap[TECLA_frente] == EVENT_down and self.keyMap[TECLA_traz] == EVENT_up:
            self.modelo.setY(self.modelo, ((self.velocidade * 2) * dt) * -1)

            if self.estaMovendo is False:
                self.modelo.loop("run")
                self.estaMovendo = True

        elif self.keyMap[TECLA_traz] == EVENT_down and self.keyMap[TECLA_frente] == EVENT_up:
            self.modelo.setY(self.modelo, (self.velocidade * dt))

            if self.estaMovendo is False:
                self.modelo.loop("walk")
                self.estaMovendo = True

        elif self.estaMovendo:
            self.modelo.stop()
            self.modelo.pose("walk", 5)
            self.estaMovendo = False
        # movimentos usuario modelo

        if self.estaMovendo:

            self.cTrav.traverse(render)

            if self.ralphGroundHandler.getNumEntries() == 1:
                entry = self.ralphGroundHandler.getEntry(0)
                if entry.getIntoNode().getName() == "terrain":
                    self.modelo.setZ(entry.getSurfacePoint(render).getZ())
            else:
                self.modelo.setPos(startpos)

        return task.cont
class World(DirectObject):

    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # Post the instructions

        self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[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)
        self.environ.setPos(0,0,0)
        
        # Create the main character, Ralph
        ralphStartPos = self.environ.find("**/start_point").getPos()
        
        #self.addRalph(ralphStartPos)
       

        # 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("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        
        
        # 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.

       

        # 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))
        
        # Add some text
        '''
        bk_text = "This is a test"
        textObject = OnscreenText(text = bk_text, pos = (0.95,-0.35), 
        scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1)
        '''
    
    #MS: Adds a Roaming Ralph
    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)
        
    
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    

    # 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())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -25 * 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["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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        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
Exemplo n.º 17
0
class World(DirectObject):

    def skyBoxLoad(self):
        self.spaceSkyBox = load_model('skybox1.egg')
        self.spaceSkyBox.setScale(150)
        self.spaceSkyBox.setLightOff()
        self.spaceSkyBox.reparentTo(render)
        self.spaceSkyBox.setPos(0,0,-200)
        self.spaceSkyBox.setHpr(0,0,0)        

    def loadEnviron(self):
        self.environ = load_model("secondWorld.egg")
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)

    def loadPokemon(self):
        self.pikachu = load_model("pikachu.egg")
        self.pikachu.reparentTo(render)
        self.pikachu.setScale(1)
        # self.pikachu.setPos(0,0,1)
        # self.pikachu.place()
        self.Groudon = load_model("Groudon.egg")
        self.Groudon.reparentTo(render)
        self.Groudon.setPos(-50,0,0)        
        # self.Groudon.place()
    def loadRalph(self):
        # Create the main character, Ralph
        basePath = r"../google_drive/ball/data/models/"
        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor(basePath+"ralph",{"run":basePath+"ralph-run",
                                  "walk":basePath+"ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(ralphStartPos)
        self.ralph.hide()
        
    def loadMusic(self, name="palette.mp3"):
        bgmusic = load_bgmusic(name)
        bgmusic.play()                    

    def keyControl(self):
        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("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("w",self.setKey,["upward",1])
        self.accept("w-up",self.setKey,["upward",0])
        self.accept("s",self.setKey,["downward",1])
        self.accept("s-up",self.setKey,["downward",0])        

    def displayInformation(self):
        self.title = addTitle("My Pokemon - Roam Mode")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Arrow Keys]: Move")
        self.inst4 = addInstructions(0.85, "[w]: look up")
        self.inst4 = addInstructions(0.80, "[s]: look down")        
        
    def __init__(self):
        self.keyMap = {"left":0, "right":0, "forward":0,"backward":0,
                       "upward":0, "downward":0, "leftward":0,"rightward":0,
                       "cam-left":0, "cam-right":0}
        # base.win.setClearColor(Vec4(0,0,0,1))
        self.above = 3.0
        # load sky box
        self.skyBoxLoad()
        # load environment
        self.loadEnviron()
        # load pokemon
        self.loadPokemon()
        # load ralph
        self.loadRalph()
        # load music
        self.loadMusic()
        self.displayInformation()
        self.keyControl()
        # 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)
        taskMgr.add(self.move,"moveTask")
        taskMgr.add(self.setAbove,"setAbove")
        # Game state variables
        self.isMoving = False
        # Set up the camera
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY(),2)
        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))

    def setAbove(self,task):
        if self.keyMap["upward"] == 1:
            self.above += 0.1
        if self.keyMap["downward"] == 1:
            self.above -= 0.1
        return task.cont
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # 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() + 113 * globalClock.getDt())
            base.camera.setX(base.camera, +20 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 113 * globalClock.getDt())
            base.camera.setX(base.camera, -20 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -75 * globalClock.getDt())
        if (self.keyMap["backward"] != 0):
            pass
            #self.ralph.setY(self.ralph, 75 * 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["left"]!=0) or (self.keyMap["right"]!=0):# or (self.keyMap["backward"]!=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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        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() + self.above)#self.above)
        
        base.camera.lookAt(self.floater)
        return task.cont
Exemplo n.º 18
0
class PandaPath(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # Set the background color to black
        self.win.setClearColor((0, 0, 0, 1))

        # This is used to store which keys are currently pressed.
        self.key_map = {"left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0}

        # Post the Instruction
        self.title = add_title("Panda 3D Demo")

        # Instructions
        self.inst1 = add_instructions(0.06, "[ESC]: Quit")
        self.inst2 = add_instructions(0.12, "[Left Arrow]: Rotate Left")
        self.inst3 = add_instructions(0.18, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = add_instructions(0.24, "[Up Arrow]: Run Ralph Forward")
        # self.inst6 = add_instructions(0.30, "[A]: Rotate Camera Left")
        # self.inst7 = add_instructions(0.36, "[S]: Rotate Camera Right")

        # Load the Environment Model
        self.environ = self.loader.loadModel(ENVIRONMENT)
        # Reparent the model to the render controller
        self.environ.reparentTo(render)

        # Apply scale and position transform on the model
        # self.environ.setScale(0.25, 0.25, 0.25)
        # self.environ.setPos(-8, 42, 0)

        # Create the Main Character
        # Load and transform the panda actor
        ralph_start_pos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor(RALPH_ACTOR, RALPH_ACTIONS)

        # self.ralph.setScale(0.005, 0.005, 0.005)
        self.ralph.reparentTo(render)
        # Loop it's animation
        self.ralph.setScale(0.2)
        self.ralph.setPos(ralph_start_pos + (0, 0, 0.5))
        # self.ralph.loop("walk")

        # Create a floater object, which floats 2 units above rlaph. We use this as a target for the camera to look at
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.ralph)
        # 2 Units above Ralph
        self.floater.setZ(2.0)

        # Configure the Camera
        # Add the spin camera taks procedure to the taks manager
        # self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")

        # Accept certain control keys
        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.set_key, ["left", True])
        self.accept("arrow_right", self.set_key, ["right", True])
        self.accept("arrow_up", self.set_key, ["forward", True])
        self.accept("a", self.set_key, ["cam-left", True])
        self.accept("s", self.set_key, ["cam-right", True])
        self.accept("arrow_left-up", self.set_key, ["left", False])
        self.accept("arrow_right-up", self.set_key, ["right", False])
        self.accept("arrow_up-up", self.set_key, ["forward", False])
        self.accept("a-up", self.set_key, ["cam-left", False])
        self.accept("s-up", self.set_key, ["cam-right", False])

        # Game States
        taskMgr.add(self.move, "moveTask")
        self.is_moving = False

        self.disableMouse()
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)
        self.camera.lookAt(self.floater)

        """
        Detect the height of hte terrain by creating a collision ray and casting it down towards 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 ca ndetect the height.

        If it hits anything else, we rule that the move is illegal.
        """
        self.cTrav = CollisionTraverser()

        # Create a vector, it's location is at the top of ralph's head
        self.ralph_ground_ray = CollisionRay()
        self.ralph_ground_ray.setOrigin(0, 0, 9)  # Top of ralph's head
        self.ralph_ground_ray.setDirection(0, 0, -1)  # Points -Z axis

        # Create a Collision node
        self.ralph_ground_col = CollisionNode("ralph_ray")  # Give the node a name
        self.ralph_ground_col.addSolid(self.ralph_ground_ray)  # the vector from ralph's head to the ground is solid
        self.ralph_ground_col.setFromCollideMask(CollideMask.bit(0))  # ??
        self.ralph_ground_col.setIntoCollideMask(
            CollideMask.allOff()
        )  # ?? This seems like it defines the behavior of ray
        self.ralph_ground_col_np = self.ralph.attachNewNode(self.ralph_ground_col)  # Attach the ray to ralph
        self.ralph_ground_handler = (
            CollisionHandlerQueue()
        )  # I think that when a collision occurs it sends through this
        self.cTrav.addCollider(self.ralph_ground_col_np, self.ralph_ground_handler)  # Attach the collision

        """
        Attach the a camera ray to the camera
        """
        self.cam_ground_ray = CollisionRay()
        self.cam_ground_ray.setOrigin(0, 0, 9)
        self.cam_ground_ray.setDirection(0, 0, -1)
        self.cam_ground_col = CollisionNode("camera_ray")
        self.cam_ground_col.addSolid(self.cam_ground_ray)
        self.cam_ground_col.setFromCollideMask(CollideMask.bit(0))
        self.cam_ground_col.setIntoCollideMask(CollideMask.allOff())
        self.cam_ground_col_np = self.camera.attachNewNode(self.cam_ground_col)
        self.cam_ground_handler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.cam_ground_col_np, self.cam_ground_handler)

        # Uncomment the following lines to view the rays
        self.ralph_ground_col_np.show()
        self.cam_ground_col_np.show()

        # Uncomment this line to show a visual representation of the Collision occuring
        self.cTrav.showCollisions(render)

        # Create some lighting
        ambient_light = AmbientLight("ambient_light")
        ambient_light.setColor((0.3, 0.3, 0.3, 1))
        directional_light = DirectionalLight("directional_light")
        directional_light.setDirection((-5, -5, -5))
        directional_light.setColor((1, 1, 1, 1))
        directional_light.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambient_light))
        render.setLight(render.attachNewNode(directional_light))

        # Add Cube
        X_OFFSET = 0
        Y_OFFSET = -3
        Z_OFFSET = 1

        CUBE_SIZE = 2

        x, y, z = ralph_start_pos
        x += X_OFFSET
        y += Y_OFFSET
        z += Z_OFFSET

        # make_cube(x, y, z, CUBE_SIZE)

    def set_key(self, key, value):
        self.key_map[key] = value

    def move(self, task):
        dt = globalClock.getDt()
        # print "DT: %f" % dt

        # ****: Movement
        # Get Ralph's position before we do anything to it
        start_pos = self.ralph.getPos()

        # User wants to turn
        if self.key_map["left"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.key_map["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)

        # Perform a move forward
        if self.key_map["forward"]:
            self.ralph.setY(self.ralph, -25 * dt)

        # ****: Animation
        if self.key_map["forward"] or self.key_map["left"] or self.key_map["right"]:
            if not self.is_moving:
                self.ralph.loop("run")
                self.is_moving = True

        else:
            if self.is_moving:
                self.ralph.stop()
                self.ralph.pose("walk", 5)
                self.is_moving = False

        # ****: Camera Movement
        if self.key_map["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        elif self.key_map["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

        # 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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist - 5.0

        # ****: Collision
        """
        Normally, we would have to call traverse() to check for collisions.

        However, the class ShowBase that we inherit from has a task to do this for us

        If we assign a CollisionTraverser to self.cTrav

        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 = list(self.ralph_ground_handler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        # print "Entry count: %d" % len(entries)

        if len(entries) > 0 and entries[0].getIntoNode().getName() == "terrain":
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.ralph.setPos(start_pos)

        # Keep the camera at one foot above the terrain or two feet above ralph, whichever is greater
        entries = list(self.cam_ground_handler.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.ralph.getZ() + 2.0:
            self.camera.setZ(self.ralph.getZ() + 2.0)

        """
        The camera should look in rlaphs direction, but it should also try to stay horizontal so look at a
        floater which hovers above ralph's head
        """
        self.camera.lookAt(self.floater)
        return task.cont
Exemplo n.º 19
0
class World(ShowBase):

	def __init__(self):
		ShowBase.__init__(self)

		#PStatClient.connect()

		#self.lookPoint = NodePath(PandaNode("floater"))
		self.lookPoint = self.loader.loadModel("models/cone")
		self.lookPoint.reparentTo(render)

		self.menu = StartMenu(self)
		#self.bar = Bar()

		#self.messenger.toggleVerbose()


		#sys.exit()
		#pdb.set_trace()

		# Window change event handler
		#self.windowEventSetup()



	def setup(self):

		print("Init Levels...")
		self.initLevels()

		print("Init World...")
		self.initWorld("yard")

		print("Init Items...")
		self.initItems()

		print("Init Actors...")
		self.initActors()

		print("Init GUI ...")
		self.initGui()

		print("Init Lights...")
		self.initLights()

		print("Init Collisions...")
		self.initCollision()

		print("Init Tasks...")
		self.initTasks()

		print("Launching World")

		# Accept the control keys
		#self.accept("h", self.crono.start)

	def initItems(self):

		with open('items/items.json') as items_file:
			self.items = json.load(items_file)

	def initActors(self):

		self.player = Player(self, 20, 10, 10, 10, 10, 10) #app, hp, mana, strength, dexterity, vigor, magic):

		self.enemies = []
		self.npcs = []

		#Creating AI World

		self.AIworld = AIWorld(render)

		"""self.foe1 = Enemy(self, 100, 50, 5, 2, "bug") #(self, app, hp, mana, speed, attackSpeed, name):
		self.nasgul = Enemy(self, 100, 50, 5, 2, "nasgul")

		self.npc1 = Npc(self, 100, 50, 5, 2, "guy2")
		self.npc2 = Npc(self, 100, 50, 5, 2, "ralph")

		self.enemies.append(self.foe1)
		self.enemies.append(self.nasgul)

		self.npcs.append(self.npc1)
		self.npcs.append(self.npc2)"""


	def initGui(self):

		# Load the models.

		self.inventory = Inventory(self)
		self.status = Status(self)
		self.skills = Skills(self)

		#self.statusBar = self.loader.loadModel("models/statusbar")


		##self.statusBar.setDepthTest(True)
		#self.statusBar.setDepthWrite(True)


		# Reparent the model to render2d.
		#self.statusBar.reparentTo(self.render2d)


		#self.statusBar.setScale(0.15, 0.15, 0.15)
		#self.statusBar.setPos(-0.95, 0, 0.65)


		#self.crono = Crono(self)
		##self.cursorpos = CursorPos(self)
		#self.playerpos = PlayerPos(self)

		#self.crono.draw(0.7, -0.85)
		#self.cursorpos.draw(0.0, -0.85)
		#self.playerpos.draw(-0.7, -0.85)


		self.accept("i", self.inventory.toggle)
		self.accept("c", self.status.toggle)
		self.accept("k", self.skills.toggle)

	def initTasks(self):

		#self.taskMgr.add(self.crono.task, "cronoTask")
		#self.taskMgr.add(self.cursorpos.task, "cursorposTask")

		###self.taskMgr.add(self.playerpos.task, "playerposTask")

		self.taskMgr.add(self.checkCollision, "collisionTask")

		#self.taskMgr.add(self.player.update, "updateTask")
		self.taskMgr.add(self.player.move, "moveTask")
		self.taskMgr.add(self.player.updateCamera, "playerCameraTask",priority=1)
		"""
		#self.taskMgr.add(self.foe1.update, "bugTask",priority=1)
		#self.taskMgr.add(self.nasgul.update, "nasgulTask",priority=1)

		#self.taskMgr.add(self.npc1.update, "npc1Task",priority=1)
		#self.taskMgr.add(self.npc2.update, "npc2Task",priority=1)
		"""
		self.taskMgr.add(self.update, 'update')

	def initLights(self):
		# Create some lighting

		#self.environ.ls()

		#print(self.environ.findAllMatches("**/Spot"))

		ambientLight = AmbientLight("ambientLight")
		ambientLight.setColor(Vec4(0.8, 0.8, 0.8, 0.65))

		"""
		directionalLight = DirectionalLight("directionalLight")
		directionalLight.setDirection(Vec3(-10, -10, 5))
		directionalLight.showFrustum()
		directionalLight.setColor(Vec4(1, 1, 1, 1))
		directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
		dirnp = render.attachNewNode(directionalLight)
		dirnp.setPos(10, 0, 6)
		"""

		plight1 = PointLight('plight1')
		plight1.setColor(VBase4(1, 1, 1, 1))
		plight1.showFrustum()
		#plight1.setShadowCaster(True)
		plnp1 = render.attachNewNode(plight1)
		plnp1.setPos(26.71, -33.2, 26)

		plight2 = PointLight('plight2')
		plight2.setColor(VBase4(1, 1, 1, 1))
		plight2.showFrustum()
		plnp2 = render.attachNewNode(plight2)
		plnp2.setPos(-25, 25, 25)

		slight = Spotlight('slight')
		slight.setColor(VBase4(1, 1, 1, 1))
		lens = PerspectiveLens()
		lens.setFilmSize(1, 1)  # Or whatever is appropriate for your scene
		slight.setLens(lens)
		slight.setShadowCaster(True, 512, 512)
		slight.showFrustum()
		slnp = render.attachNewNode(slight)
		slnp.setPos(0, 0, 100)

		slnp.lookAt(Vec3(0,0,0))

		render.setLight(slnp)
		render.setLight(plnp1)
		render.setLight(plnp2)
		#render.setLight(render.attachNewNode(ambientLight))

		#render.setLight(dirnp)

		render.setShaderAuto()

		#render.setLight(render.attachNewNode(directionalLight))

		"""
		self.light = render.attachNewNode(Spotlight("Spot"))
		self.light.node().setScene(render)
		self.light.node().setShadowCaster(True)
		self.light.node().showFrustum()
		self.light.node().getLens().setFov(40)
		self.light.node().getLens().setNearFar(10,100)
		render.setLight(self.light)
		"""

	def initLevels(self):
		with open('levels/levels.json') as levels_file:
			self.levels = json.load(levels_file)

	def initWorld(self, level):

		self.environ = self.loader.loadModel(self.levels["levels"][level]["model"])
		#self.environ.setScale(20, 20, 20)
		#self.environ.setHpr(0, 0, 0)
		self.environ.setPos(0, 0, 0)

		self.playerStartPos = self.environ.find("**/startPos").getPos()

		# Reparent the model to render

		self.environ.reparentTo(render)
		#self.environ.ls()
		self.accept("q", self.changeMap)

	def destroyWorld(self):

		self.environ.detachNode()
		self.environ.removeNode()

	def changeMap(self):#, levelName):
		self.destroyWorld()
		self.initWorld("yard")

	def update(self, task):
		dt = globalClock.getDt()

		self.AIworld.update()
		return task.cont

	def setKey(self, key, value):
		self.keyMap[key] = value

	def windowEventSetup( self ):
		# accept the window event's
		self.accept( 'window-event', self.windowEventHandler)
		# create a window event yourself
		#messenger.send( 'window-event', [self.win] )

	def windowEventHandler( self, window=None ):
		wp = window.getProperties()

		print("Window changed")
		print("X = %s" % wp.getXSize())
		print("Y = %s" % wp.getYSize())
		self.setResolution( wp.getXSize(), wp.getYSize() )

	def setResolution( self, w, h ):
		wp = WindowProperties()
		wp.setSize( w, h )

		if os.name == 'posix':
			self.openMainWindow()
			self.graphicsEngine.openWindows()
		self.win.requestProperties( wp )

	# Define a procedure to move the camera.
	def spinCameraTask(self, task):
		angleDegrees = task.time * 6.0
		angleRadians = angleDegrees * (pi / 180.0)
		self.camera.setPos(40 * sin(angleRadians), -10.0 * cos(angleRadians), 3)
		self.camera.setHpr(angleDegrees, 0, 0)
		return Task.cont

	def initCollision(self):


		self.enemyGroundRay = []
		self.enemyGroundCol = []
		self.enemyGroundColNp = []
		self.enemyGroundHandler = []

		self.npcGroundRay = []
		self.npcGroundCol = []
		self.npcGroundColNp = []
		self.npcGroundHandler = []

		self.cTrav = CollisionTraverser()


		self.playerGroundRay = CollisionRay()
		self.playerGroundRay.setOrigin(0, 0, 9)
		self.playerGroundRay.setDirection(0, 0, -1)
		self.playerGroundCol = CollisionNode('playerRay')
		self.playerGroundCol.addSolid(self.playerGroundRay)
		self.playerGroundCol.setFromCollideMask(CollideMask.bit(0))
		self.playerGroundCol.setIntoCollideMask(CollideMask.allOff())
		self.playerGroundColNp = self.player.moveFloater.attachNewNode(self.playerGroundCol)
		self.playerGroundHandler = CollisionHandlerQueue()
		self.cTrav.addCollider(self.playerGroundColNp, self.playerGroundHandler)

		self.mouseGroundRay = CollisionRay()
		self.mouseGroundRay.setOrigin(0, 0, 9)
		self.mouseGroundRay.setDirection(0, 0, -1)
		self.mouseGroundCol = CollisionNode('mouseRay')
		self.mouseGroundCol.addSolid(self.mouseGroundRay)
		self.mouseGroundCol.setFromCollideMask(CollideMask.bit(0))
		self.mouseGroundCol.setIntoCollideMask(CollideMask.allOff())
		self.mouseGroundColNp = self.camera.attachNewNode(self.mouseGroundCol)
		self.mouseGroundHandler = CollisionHandlerQueue()
		self.cTrav.addCollider(self.mouseGroundColNp, self.mouseGroundHandler)

		# Uncomment this line to see the collision rays
		#self.playerGroundColNp.show()
		#self.mouseGroundColNp.show()

		# Uncomment this line to show a visual representation of the
		# collisions occuring
		#self.cTrav.showCollisions(render)


		i = 0
		for enemy in self.enemies:

			self.enemyGroundRay.append(CollisionRay())
			self.enemyGroundRay[i].setOrigin(0, 0, 9)
			self.enemyGroundRay[i].setDirection(0, 0, -1)

			self.enemyGroundCol.append(CollisionNode('%sRay' % enemy.name))
			self.enemyGroundCol[i].addSolid(self.enemyGroundRay[i])
			self.enemyGroundCol[i].setFromCollideMask(CollideMask.bit(0))
			self.enemyGroundCol[i].setIntoCollideMask(CollideMask.allOff())

			self.enemyGroundColNp.append(enemy.enemyActor.attachNewNode(self.enemyGroundCol[i]))
			self.enemyGroundHandler.append(CollisionHandlerQueue())
			self.cTrav.addCollider(self.enemyGroundColNp[i], self.enemyGroundHandler[i])

			#self.enemyGroundColNp.show()
			i += 1

		i = 0
		for npc in self.npcs:

			self.npcGroundRay.append(CollisionRay())
			self.npcGroundRay[i].setOrigin(0, 0, 9)
			self.npcGroundRay[i].setDirection(0, 0, -1)

			self.npcGroundCol.append(CollisionNode('%sRay' % npc.name))
			self.npcGroundCol[i].addSolid(self.npcGroundRay[i])
			self.npcGroundCol[i].setFromCollideMask(CollideMask.bit(0))
			self.npcGroundCol[i].setIntoCollideMask(CollideMask.allOff())

			self.npcGroundColNp.append(npc.npcActor.attachNewNode(self.npcGroundCol[i]))
			self.npcGroundHandler.append(CollisionHandlerQueue())
			self.cTrav.addCollider(self.npcGroundColNp[i], self.npcGroundHandler[i])

			#self.npcGroundColNp.show()
			i += 1

	def checkCollision(self, task):

		startpos = self.player.moveFloater.getPos()

		entries = list(self.playerGroundHandler.getEntries())
		entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

		for entry in entries:
			if entry > 0 and entries[0].getIntoNode().getName() == "Ground":
				self.player.moveFloater.setZ(entry.getSurfacePoint(render).getZ())
			else:
				self.player.moveFloater.setPos(startpos)

		if self.mouseWatcherNode.hasMouse():

			mpos = self.mouseWatcherNode.getMouse()

			self.mouseGroundRay.setFromLens(self.camNode, mpos.getX(), mpos.getY())


			nearPoint = render.getRelativePoint(self.camera, self.mouseGroundRay.getOrigin())
			nearVec = render.getRelativeVector(self.camera, self.mouseGroundRay.getDirection())
			try:
				self.lookPoint.setPos(PointAtZ(self.player.moveFloater.getZ(), nearPoint, nearVec))
			except:
				pass

		i = 0

		for enemy in self.enemies:
			startpos = enemy.enemyActor.getPos()

			entries = list(self.enemyGroundHandler[i].getEntries())
			entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

			for entry in entries:
				if entry > 0: # and entries[0].getIntoNode().getName() == "Ground":
					enemy.enemyActor.setZ(entry.getSurfacePoint(render).getZ())
				else:
					enemy.enemyActor.setPos(startpos)
			i += 1


		i = 0
		for npc in self.npcs:
			startpos = npc.npcActor.getPos()

			entries = list(self.npcGroundHandler[i].getEntries())
			entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

			for entry in entries:
				if entry > 0: # and entries[0].getIntoNode().getName() == "Ground":
					npc.npcActor.setZ(entry.getSurfacePoint(render).getZ())
				else:
					npc.npcActor.setPos(startpos)
			i += 1

		return task.cont
Exemplo n.º 20
0
class Collision():
  def __init__(self,ui):
	
    self.ui = ui;
   
    
    # Find the collision node named wall_collide
    self.walls = self.ui.maze.find("**/wall_collide")

    
    self.walls.node().setIntoCollideMask(BitMask32.bit(0))
    # CollisionNodes are usually invisible but can be shown. 
    # 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.ui.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.ui.maze.find("**/ground_collide")
    self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1))
    
    
    # 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.ui.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.ui.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)
Exemplo n.º 21
0
class World(ShowBase):
    def __init__(self):

        # Load the default configuration.prc. This is recommended, as it
        # contains some important panda options
        loadPrcFile("../../Config/configuration.prc")

        ShowBase.__init__(self)

        # Create a new pipeline instance
        self.renderPipeline = RenderingPipeline(self)

        # Set the base path for the pipeline. This is required as we are in
        # a subdirectory
        self.renderPipeline.getMountManager().setBasePath("../../")

        # Also set the write path
        self.renderPipeline.getMountManager().setWritePath("../../Temp/")

        # Load the default settings
        self.renderPipeline.loadSettings("../../Config/pipeline.ini")

        # Now create the pipeline
        self.renderPipeline.create()

        # Add a directional light
        dPos = Vec3(40, 40, 15)
        dirLight = DirectionalLight()
        dirLight.setPos(dPos * 1000000.0)
        dirLight.setShadowMapResolution(1024)
        dirLight.setCastsShadows(True)
        dirLight.setColor(Vec3(8))
        self.renderPipeline.addLight(dirLight)
        self.renderPipeline.setScatteringSource(dirLight)
        self.dirLight = dirLight

        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "cam-left": 0,
            "cam-right": 0
        }
        base.win.setClearColor(Vec4(0, 0, 0, 1))

        # Post the instructions

        self.title = addTitle(
            "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[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)
        self.environ.setPos(0, 0, 0)

        self.environ.find("**/wall").removeNode()

        # 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)

        self.renderPipeline.setEffect(self.ralph,
                                      "Effects/Default/Default.effect",
                                      {"dynamic": True})

        # 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("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("a", self.setKey, ["cam-left", 1])
        self.accept("s", self.setKey, ["cam-right", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("a-up", self.setKey, ["cam-left", 0])
        self.accept("s-up", self.setKey, ["cam-right", 0])

        # NOTICE: It is important that your update tasks have a lower priority
        # than -10000
        taskMgr.add(self.move, "moveTask", priority=-20000)

        self.accept("r", self.reloadShader)

        # Game state variables
        self.isMoving = False

        # Set up the camera

        base.disableMouse()
        base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 1.2)

        # 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 ocean
        self.water = ProjectedWaterGrid(self.renderPipeline)
        self.water.setWaterLevel(-3.0)

        # Create the skybox
        self.skybox = self.renderPipeline.getDefaultSkybox()
        self.skybox.reparentTo(render)

        self.prepareSRGB(render)
        self.reloadShader()
        self.renderPipeline.onSceneInitialized()

        # Add demo slider to move the sun position
        if self.renderPipeline.settings.displayOnscreenDebugger:
            self.renderPipeline.guiManager.demoSlider.node[
                "command"] = self.setSunPos
            self.renderPipeline.guiManager.demoSlider.node["value"] = 50

    def setSunPos(self):
        rawValue = self.renderPipeline.guiManager.demoSlider.node["value"]
        dPos = Vec3(100, 100, rawValue - 20)
        self.dirLight.setPos(dPos * 100000000.0)

    def reloadShader(self):
        self.renderPipeline.reloadShaders()

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    def prepareSRGB(self, np):
        """ Sets the correct texture format for all textures found in <np> """
        for tex in np.findAllTextures():

            baseFormat = tex.getFormat()

            if baseFormat == Texture.FRgb:
                tex.setFormat(Texture.FSrgb)
            elif baseFormat == Texture.FRgba:
                tex.setFormat(Texture.FSrgbAlpha)
            else:
                print "Unkown texture format:", baseFormat
                print "\tTexture:", tex

            # tex.setMinfilter(Texture.FTLinearMipmapLinear)
            # tex.setMagfilter(Texture.FTLinear)
            tex.setAnisotropicDegree(16)

    # 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())
        if (self.keyMap["right"] != 0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"] != 0):
            self.ralph.setY(self.ralph, -25 * 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["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 > 7.0):
            base.camera.setPos(base.camera.getPos() + camvec * (camdist - 7))
            camdist = 7.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)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        if (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                   == "terrain"):
            self.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)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        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.5):
            base.camera.setZ(self.ralph.getZ() + 2.5)

        # 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
Exemplo n.º 22
0
class Game(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # Set the background color to black
        self.win.setClearColor(BACKGROUND_COLOR)

        # 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)

        # Create the main character

        playerStartPos = self.environ.find("**/start_point").getPos()
        self.player = Actor("models/player",
                           {"run": "models/player-run",
                            "walk": "models/player-walk"})
        self.player.reparentTo(render)
        self.player.setScale(.2)
        self.player.setPos(playerStartPos + (0, 0, 0.5))

        # Create a floater object, which floats 2 units above player.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.player)
        self.floater.setZ(CAMERA_TARGET_HEIGHT_DELTA)

        self.first_person = False

        def key_dn(name):
            return lambda: self.setKey(name, True)
        def key_up(name):
            return lambda: self.setKey(name, False)
        def quit():
            self.destroy()
        def toggle_first():
            self.first_person = not self.first_person
        # Accept the control keys for movement and rotation
        key_map = [
            # key              command        action                   help
            # ---              -------        ------                   ----
            ("escape",         "esc",         lambda: quit(),          '[ESC]: Quit'),
            ("arrow_left",     'left',        key_dn("left"),          "[Left Arrow]: Rotate Left"),
            ("arrow_left-up",  'left',        key_up("left"),          None),
            ("arrow_right",    'right',       key_dn("right"),         "[Right Arrow]: Rotate Right"),
            ("arrow_right-up", 'right',       key_up("right"),         None),
            ("arrow_up",       'forward',     key_dn("forward"),       "[Up Arrow]: Run Forward"),
            ("arrow_up-up",    'forward',     key_up("forward"),       None),
            ("arrow_down",     'backward',    key_dn("backward"),      "[Down Arrow]: Run Backward"),
            ("arrow_down-up",  'backward',    key_up("backward"),      None),
            ("a",              'cam-left',    key_dn("cam-left"),      "[A]: Rotate Camera Left"),
            ("a-up",           'cam-left',    key_up("cam-left"),      None),
            ("s",              'cam-right',   key_dn("cam-right"),     "[S]: Rotate Camera Right"),
            ("s-up",           'cam-right',   key_up("cam-right"),     None),
            ('f',              'first-pers',  lambda: toggle_first(),  '[F]: Toggle first-person'),
            ]
        self.keyMap = {}
        inst = Instructions()
        for key, command, action, description in key_map:
            if command:
                self.setKey(command, False)
            self.accept(key, action)
            if description:
                inst.add(description)

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.player.getX(), self.player.getY() + 10, 2)

        # 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 player'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.playerGroundRay = CollisionRay()
        self.playerGroundRay.setOrigin(0, 0, 9)
        self.playerGroundRay.setDirection(0, 0, -1)
        self.playerGroundCol = CollisionNode('playerRay')
        self.playerGroundCol.addSolid(self.playerGroundRay)
        self.playerGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.playerGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.playerGroundColNp = self.player.attachNewNode(self.playerGroundCol)
        self.playerGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.playerGroundColNp, self.playerGroundHandler)

        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.playerGroundColNp.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))

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

        # save player's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startpos = self.player.getPos()

        # If a move-key is pressed, move player in the specified direction.

        if self.keyMap["left"]:
            self.player.setH(self.player.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.player.setH(self.player.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.player.setY(self.player, -25 * dt)
        if self.keyMap["backward"]:
            self.player.setY(self.player, 25 * dt)

        # If player is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if self.keyMap["forward"] or self.keyMap["backward"] or self.keyMap["left"] or self.keyMap["right"]:
            if self.isMoving is False:
                self.player.loop("run")
                self.isMoving = True
        else:
            if self.isMoving:
                self.player.stop()
                self.player.pose("walk", 5)
                self.isMoving = False

        # If the camera is too far from player, move it closer.
        # If the camera is too close to player, move it farther.

        if self.first_person:
            self.camera.setPos(self.player.getPos())
        else:
            camvec = self.player.getPos() - self.camera.getPos()
            camvec.setZ(0)
            camdist = camvec.length()
            camvec.normalize()
            if camdist > CAMERA_DISTANCE_MAX:
                self.camera.setPos(self.camera.getPos() + camvec * (camdist - int(CAMERA_DISTANCE_MAX)))
                camdist = CAMERA_DISTANCE_MAX
                if camdist < CAMERA_DISTANCE_MIN:
                    self.camera.setPos(self.camera.getPos() - camvec * (int(CAMERA_DISTANCE_MIN) - camdist))
                    camdist = CAMERA_DISTANCE_MIN

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        self.cTrav.traverse(render)

        # Adjust player's Z coordinate.  If player'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 = list(self.playerGroundHandler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        if len(entries) > 0 and entries[0].getIntoNode().getName() == "terrain":
            self.player.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.player.setPos(startpos)

        # Keep the camera at one foot above the terrain,
        # or two feet above player, whichever is greater.

        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() + CAMERA_POSITION_HEIGHT_DELTA_MIN)
        if self.camera.getZ() < self.player.getZ() + CAMERA_POSITION_HEIGHT_DELTA_MAX:
            self.camera.setZ(self.player.getZ() + CAMERA_POSITION_HEIGHT_DELTA_MAX)

        # The camera should look in player's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above player's head.
        self.camera.lookAt(self.floater)

        return task.cont
Exemplo n.º 23
0
class World(DirectObject):

    def __init__(self):
        self.keyMap = {"left":0, "right":0, "forward":0, "back":0, "cam-left":0, "cam-right":0}
        self.flag1=0
        self.flag2=0
        self.flag3=0 
        self.flag4=0
        self.count=0
        self.health = 100
        self.points = -5
        self.flagd=1
        self.player_points = 0
        base.win.setClearColor(Vec4(0,0,0,1))
        
        self.mySound=base.loader.loadSfx("sounds/trial.mp3")
        self.mySound.play()
        
        self.title = addTitle("Bumping Cars")
       
		#Full Screen
        props = WindowProperties.getDefault()
        w=base.pipe.getDisplayWidth()
        h=base.pipe.getDisplayHeight()
        props.setSize(w,h)
        props.setFullscreen(True)
        props.setCursorHidden(True)
        base.win.requestProperties(props) 

		# Load World
        self.environ = loader.loadModel("models/world.egg")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        
        #Load Sky
        self.sky = loader.loadModel("models/clouds.egg")
        self.sky.reparentTo(render)
        self.sky.setPos(60,0,-450)
        
        
        # Create Player Car
        carStartPos = self.environ.find("**/start_point").getPos()
        self.car = Actor("models/carnsx")
        self.car.reparentTo(render)
        self.car.setScale(0.25)
        #self.car.place()
        self.car.setPos(carStartPos)
        
        # Create Enemy Car 1
        enemyCarStartPos1 = (-108,-1,-.5)
        self.car1 = Actor("models/enemy_cars/monstercar/carmonster")
        self.car1.reparentTo(render)
        self.car1.setScale(0.25)
        #self.car1.place()
        self.car1.setPos(enemyCarStartPos1)
        
        # Create Enemy Car 2
        enemyCarStartPos2 = (-104,-26,-.02)
        self.car2 = Actor("models/enemy_cars/yugo/yugo")
        self.car2.reparentTo(render)
        self.car2.setScale(0.15)
        #self.car2.place()
        self.car2.setPos(enemyCarStartPos2)
        
        # Create Enemy Car 3
        enemyCarStartPos3 = (-111,-26,0)
        self.car3 = Actor("models/enemy_cars/truck/cartruck")
        self.car3.reparentTo(render)
        self.car3.setScale(0.25)
        #self.car3.place()
        self.car3.setPos(enemyCarStartPos3)
        
        # Create Enemy Car 4
        enemyCarStartPos4 = (-111,-2,-.5)
        self.car4 = Actor("models/enemy_cars/truck/cartruck-purple")
        self.car4.reparentTo(render)
        self.car4.setScale(0.25)
        #self.car4.place()
        self.car4.setPos(enemyCarStartPos4)
        

        # 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, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_up",self.setKey, ["forward",1])
        self.accept("arrow_left",self.setKey, ["left",1])
        self.accept("arrow_down",self.setKey, ["back",1])
        self.accept("arrow_right",self.setKey, ["right",1])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])
        self.accept("arrow_up-up",self.setKey, ["forward",0])
        self.accept("arrow_left-up",self.setKey, ["left",0])
        self.accept("arrow_right-up",self.setKey, ["right",0])
        self.accept("arrow_down-up",self.setKey, ["back",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.car.getX(),self.car.getY()+10,2)
        
        # 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))
        
        # AI
        self.AIworld = AIWorld(render)
 
        # AI Car 1
        self.AIchar1 = AICharacter("car1",self.car1, 70, 0.1, 3)
        self.AIworld.addAiChar(self.AIchar1)
        self.AIbehaviors1 = self.AIchar1.getAiBehaviors()
        self.AIbehaviors1.pursue(self.car)
        
        # AI Car 2
        self.AIchar2 = AICharacter("car2",self.car2, 180, 0.1, 1)
        self.AIworld.addAiChar(self.AIchar2)
        self.AIbehaviors2 = self.AIchar2.getAiBehaviors()
        self.AIbehaviors2.pursue(self.car4)
        
        # AI Car 3
        self.AIchar3 = AICharacter("car3",self.car3, 70, 0.1, 3)
        self.AIworld.addAiChar(self.AIchar3)
        self.AIbehaviors3 = self.AIchar3.getAiBehaviors()
        self.AIbehaviors3.pursue(self.car)
        
        # AI Car 4
        self.AIchar4 = AICharacter("car4",self.car4, 200, 0.5, 2)
        self.AIworld.addAiChar(self.AIchar4)
        self.AIbehaviors4 = self.AIchar4.getAiBehaviors()
        self.AIbehaviors4.pursue(self.car3)
        
        # Obstacle avoidance
        self.AIbehaviors1.obstacleAvoidance(1.0)
        self.AIworld.addObstacle(self.car2)
        self.AIworld.addObstacle(self.car3)
        self.AIworld.addObstacle(self.car4)
        
        self.AIbehaviors2.obstacleAvoidance(1.0)
        self.AIbehaviors3.obstacleAvoidance(1.0)
        self.AIbehaviors4.obstacleAvoidance(1.0)
          
        #AI World update        
        taskMgr.add(self.AIUpdate,"AIUpdate")
        
    
        self.cTrav = CollisionTraverser()
        #self.cTrav.showCollisions(render)
       
        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.carGroundColNp = self.car.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.carGroundColNp, self.ralphGroundHandler)
        
        #car1
        self.car1Ray = CollisionSphere(0,0,0,4)
        self.car1GroundCol = CollisionNode('car1Ray')
        self.car1GroundCol.addSolid(self.car1Ray)
        self.car1GroundCol.setFromCollideMask(BitMask32.bit(0))
        self.car1GroundCol.setIntoCollideMask(BitMask32.allOff())
        self.car1GroundColNp = self.car.attachNewNode(self.car1GroundCol)
        self.car1GroundHandler = CollisionHandlerQueue()
        #self.car1GroundColNp.show()
        self.cTrav.addCollider(self.car1GroundColNp, self.car1GroundHandler)
        cnodePath = self.car1.attachNewNode(CollisionNode('cnode1'))
        cnodePath.node().addSolid(self.car1Ray)
        #cnodePath.show()
        
        #car2
        self.car2Ray = CollisionSphere(0,0,0,4)
        self.car2GroundCol = CollisionNode('car2Ray')
        self.car2GroundCol.addSolid(self.car2Ray)
        self.car2GroundCol.setFromCollideMask(BitMask32.bit(0))
        self.car2GroundCol.setIntoCollideMask(BitMask32.allOff())
        self.car2GroundColNp = self.car.attachNewNode(self.car2GroundCol)
        self.car2GroundHandler = CollisionHandlerQueue()
        #self.car2GroundColNp.show()
        self.cTrav.addCollider(self.car2GroundColNp, self.car2GroundHandler)
        cnodePath = self.car2.attachNewNode(CollisionNode('cnode2'))
        cnodePath.node().addSolid(self.car2Ray)
        #cnodePath.show()
           
        #car3
        self.car3Ray = CollisionSphere(0,0,0,4)
        self.car3GroundCol = CollisionNode('car3Ray')
        self.car3GroundCol.addSolid(self.car3Ray)
        self.car3GroundCol.setFromCollideMask(BitMask32.bit(0))
        self.car3GroundCol.setIntoCollideMask(BitMask32.allOff())
        self.car3GroundColNp = self.car.attachNewNode(self.car3GroundCol)
        self.car3GroundHandler = CollisionHandlerQueue()
        #self.car3GroundColNp.show()
        self.cTrav.addCollider(self.car3GroundColNp, self.car3GroundHandler)
        cnodePath = self.car3.attachNewNode(CollisionNode('cnode3'))
        cnodePath.node().addSolid(self.car3Ray)
        #cnodePath.show()
         
        #car4
        self.car4Ray = CollisionSphere(0,0,0,4)
        self.car4GroundCol = CollisionNode('car4Ray')
        self.car4GroundCol.addSolid(self.car4Ray)
        self.car4GroundCol.setFromCollideMask(BitMask32.bit(0))
        self.car4GroundCol.setIntoCollideMask(BitMask32.allOff())
        self.car4GroundColNp = self.car.attachNewNode(self.car4GroundCol)
        self.car4GroundHandler = CollisionHandlerQueue()
        #self.car4GroundColNp.show()
        self.cTrav.addCollider(self.car4GroundColNp, self.car4GroundHandler)
        cnodePath = self.car4.attachNewNode(CollisionNode('cnode4'))
        cnodePath.node().addSolid(self.car4Ray)
        #cnodePath.show()
       
        
        #camera
        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 onCollision(self, entry):
		print("123")
		    
    def displayHealth(self):
		healthBar['scale'] = (self.health*0.01*BAR_WIDTH,0.2,0.2)
		
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    

    def makezero4(self,task):
		self.flag4=0
		
    def makezero3(self,task):
		self.flag3=0
		
    #to update the AIWorld
    def AIUpdate(self,task):
        self.AIworld.update()            
        return task.cont
        
    def makezero1(self,task):
		self.flag1=0
		
    def makezero2(self,task):
		self.flag2=0
	
    def move(self, task):
        if (self.flagd==1):
            self.points = self.points + globalClock.getDt()
        self.player_points = int(self.points)
        printPointObj(self.player_points)
        #print int(self.points)

        base.camera.lookAt(self.car)
        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 car's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startposcar = self.car.getPos()

        # If a move-key is pressed, move the car in the specified direction.

        if (self.keyMap["left"]!=0):
            self.car.setH(self.car.getH() + 100 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.car.setH(self.car.getH() - 100 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.car.setY(self.car, -40 * globalClock.getDt())
        if (self.keyMap["back"]!=0):
            self.car.setY(self.car, 40 * globalClock.getDt())
            

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0) or (self.keyMap["back"]!=0):
            if self.isMoving is False:
                self.isMoving = True
        else:
            if self.isMoving:
                self.car.stop()
                self.isMoving = False

        # If the camera is too far from the car, move it closer.
        # If the camera is too close to the car, move it farther.

        camvec = self.car.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)

        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.car.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.car.setPos(startposcar)

        entries=[] 
        for i in range(self.car1GroundHandler.getNumEntries()):
            entry = self.car1GroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))    
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "cnode1") and (self.flag1==0):
			#print "car1"
			self.flag1=1
			self.health=self.health - 10
			printHealthObj(self.health)
			print "car1"
			taskMgr.doMethodLater(5,self.makezero1,"flag1")
			
        entries=[]
        for i in range(self.car2GroundHandler.getNumEntries()):
            entry = self.car2GroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))    
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "cnode2") and (self.flag2==0):
			#print "car2"
			self.flag2=1
			self.health=self.health - 10
			printHealthObj(self.health)
			print "car2"
			taskMgr.doMethodLater(5,self.makezero2,"flag2")
			
        
        entries=[]
        for i in range(self.car3GroundHandler.getNumEntries()):
            entry = self.car3GroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))    
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "cnode3") and (self.flag3==0):
			#print "car3"
			self.flag3=1
			self.health=self.health - 10
			printHealthObj(self.health)
			print "car3"
			taskMgr.doMethodLater(5,self.makezero3,"flag3")
			
			
        entries=[]
        for i in range(self.car4GroundHandler.getNumEntries()):
            entry = self.car4GroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))    
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "cnode4") and (self.flag4==0):
			#print "car4"
			self.flag4=1
			self.health=self.health - 10
			printHealthObj(self.health)
			print "car4"
			taskMgr.doMethodLater(5,self.makezero4,"flag4")
			
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.car.getZ() + 2.0):
            base.camera.setZ(self.car.getZ() + 2.0)
            
            
        if self.health <= 0:
			self.flagd=0
			frame=DirectFrame(image=r"end.jpg",frameSize=(-3, 3, -3, 3))
			textObject1 = OnscreenText(text = 'You Died!', pos = (0, 0.7), scale = 0.22)
			textObject2 = OnscreenText(text = 'Press ESC to Exit', pos = (0,0.9), scale=0.1)
			b = DirectButton(text="Exit Game",scale=0.1,command = sys.exit)
			textObject3 = OnscreenText(text = 'Your Score: ' + str(self.player_points), pos = (-0.2, -0.9), scale = 0.22)
			
        
        self.floater.setPos(self.car.getPos())
        self.floater.setZ(self.car.getZ() + 2.0)
        base.camera.lookAt(self.floater)
        self.displayHealth()

        return task.cont
Exemplo n.º 24
0
class World(ShowBase):

    def __init__(self):

        # Load the default configuration.prc. This is recommended, as it
        # contains some important panda options
        loadPrcFile("../../Config/configuration.prc")

        ShowBase.__init__(self)

        # Create a new pipeline instance
        self.renderPipeline = RenderingPipeline(self)

        # Set the base path for the pipeline. This is required as we are in
        # a subdirectory
        self.renderPipeline.getMountManager().setBasePath("../../")

        # Also set the write path
        self.renderPipeline.getMountManager().setWritePath("../../Temp/")

        # Load the default settings
        self.renderPipeline.loadSettings("../../Config/pipeline.ini")

        # Now create the pipeline
        self.renderPipeline.create()

        # Add a directional light
        dPos = Vec3(40, 40, 15)
        dirLight = DirectionalLight()
        dirLight.setPos(dPos * 1000000.0)
        dirLight.setShadowMapResolution(1024)
        dirLight.setCastsShadows(True)
        dirLight.setColor(Vec3(8))
        self.renderPipeline.addLight(dirLight)
        self.renderPipeline.setScatteringSource(dirLight)
        self.dirLight = dirLight



        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0}
        base.win.setClearColor(Vec4(0, 0, 0, 1))

        # Post the instructions

        self.title = addTitle(
            "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[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)
        self.environ.setPos(0, 0, 0)

        self.environ.find("**/wall").removeNode()

        # 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)

        self.renderPipeline.setEffect(self.ralph, "Effects/Default/Default.effect", {
                "dynamic": True
            })

        # 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("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("a", self.setKey, ["cam-left", 1])
        self.accept("s", self.setKey, ["cam-right", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("a-up", self.setKey, ["cam-left", 0])
        self.accept("s-up", self.setKey, ["cam-right", 0])

        # NOTICE: It is important that your update tasks have a lower priority
        # than -10000
        taskMgr.add(self.move, "moveTask", priority=-20000)

        self.accept("r", self.reloadShader)

        # Game state variables
        self.isMoving = False

        # Set up the camera

        base.disableMouse()
        base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 1.2)

        # 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 ocean
        self.water = ProjectedWaterGrid(self.renderPipeline)
        self.water.setWaterLevel(-4.0)

        # Create the skybox
        self.skybox = self.renderPipeline.getDefaultSkybox()
        self.skybox.reparentTo(render)

        self.prepareSRGB(render)
        self.reloadShader()
        self.renderPipeline.onSceneInitialized()

        # Add demo slider to move the sun position
        if self.renderPipeline.settings.displayOnscreenDebugger:
            self.renderPipeline.guiManager.demoSlider.node[
                "command"] = self.setSunPos
            self.renderPipeline.guiManager.demoSlider.node[
                "value"] = 50

    def setSunPos(self):
        rawValue = self.renderPipeline.guiManager.demoSlider.node["value"]
        dPos = Vec3(100, 100, rawValue - 20)
        self.dirLight.setPos(dPos * 100000000.0)

        
    def reloadShader(self):
        self.renderPipeline.reloadShaders()

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    def prepareSRGB(self, np):
        """ Sets the correct texture format for all textures found in <np> """
        for tex in np.findAllTextures():

            baseFormat = tex.getFormat()

            if baseFormat == Texture.FRgb:
                tex.setFormat(Texture.FSrgb)
            elif baseFormat == Texture.FRgba:
                tex.setFormat(Texture.FSrgbAlpha)
            else:
                print "Unkown texture format:", baseFormat
                print "\tTexture:", tex

            # tex.setMinfilter(Texture.FTLinearMipmapLinear)
            # tex.setMagfilter(Texture.FTLinear)
            tex.setAnisotropicDegree(16)

    # 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())
        if (self.keyMap["right"] != 0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"] != 0):
            self.ralph.setY(self.ralph, -25 * 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["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 > 7.0):
            base.camera.setPos(base.camera.getPos() + camvec * (camdist - 7))
            camdist = 7.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)
        entries.sort(lambda x, y: cmp(y.getSurfacePoint(render).getZ(),
                                      x.getSurfacePoint(render).getZ()))
        if (len(entries) > 0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.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)
        entries.sort(lambda x, y: cmp(y.getSurfacePoint(render).getZ(),
                                      x.getSurfacePoint(render).getZ()))
        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.5):
            base.camera.setZ(self.ralph.getZ() + 2.5)

        # 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
Exemplo n.º 25
0
class PlayerObject():
	def __init__(self, render, username, x, y, z, h):
		self.username = username
		self.isMoving = False
		self.render = render

		self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}

		self.actor = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"})
		self.actor.reparentTo(render)
		self.actor.setScale(0.2)
		self.actor.setPos(x, y, z)
		self.actor.setH(h)

		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)

	"""
	@Marvin
	Move moves the player around the map based on 
	Must be called from a task to function properly
	Currently set up to take in random test data
	Non-random will have keys supplied from client input
	"""
	def move(self, key):
		actor = self.actor

		startpos = actor.getPos()

		if (key==0):
			actor.setH(actor.getH() + 300 * globalClock.getDt())
		if (key==1):
			actor.setH(actor.getH() - 300 * globalClock.getDt())
		if (key==2):
			actor.setY(actor, -25 * globalClock.getDt())

		if (key==0) or (key==1) or (key==2):
			if self.isMoving is False:
				actor.loop("run")
				self.isMoving = True
		else:
			if self.isMoving:
				actor.stop()
				actor.pose("walk",5)
				self.isMoving = False

		self.cTrav.traverse(render)

		entries = []
		for i in range(self.GroundHandler.getNumEntries()):
			entry = self.GroundHandler.getEntry(i)
			entries.append(entry)
		entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ()))
		if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
			self.actor.setZ(entries[0].getSurfacePoint(render).getZ())
		else:
			self.actor.setPos(startpos)

		"""
Exemplo n.º 26
0
class CollisionAvatar():
    """Collision for avatar
    """
    def __init__(self, game):
        self.game = game
        self.enable = False
        self.camera = self.game.gui.camera
        self.debug = False

        self.sphere_node = CollisionNode('Sphere')
        self.sphere_nodepath = self.game.world.avatar.attachNewNode(self.sphere_node)
        self.sphere_node.setFromCollideMask(BitMask32.bit(2))
        self.sphere_node.setIntoCollideMask(BitMask32.bit(4))
        self.sphere = CollisionSphere(0, 0, 0.5, 0.5)
        self.sphere_node.addSolid(self.sphere)
        self.sphere_handler = CollisionHandlerQueue()

        self.ray_node = CollisionNode('downRay')
        self.ray_nodepath = self.game.world.avatar.attachNewNode(self.ray_node)
        self.ray_node.setFromCollideMask(BitMask32.bit(1))
        self.ray_node.setIntoCollideMask(BitMask32.bit(3))
        self.ray = CollisionRay()
        self.ray.setOrigin(0, 0, 5)
        self.ray.setDirection(0, 0, -1)
        self.ray_node.addSolid(self.ray)
        self.ray_handler = CollisionHandlerQueue()

    def set_debug(self, value):
        """docstring for debug
        """
        self.debug = value
        if self.debug:
            self.ray_nodepath.show()
            self.sphere_nodepath.show()
        else:
            self.ray_nodepath.hide()
            self.sphere_nodepath.hide()

    def set_enable(self, value, Fly = True):
        self.enable = value
        self.fly = Fly
        if self.enable:
            self.game.gui.cTrav.addCollider(self.ray_nodepath, self.ray_handler)
            self.game.gui.cTrav.addCollider(self.sphere_nodepath, self.sphere_handler)
        else:
            self.game.gui.cTrav.removeCollider(self.ray_nodepath)
            self.game.gui.cTrav.removeCollider(self.sphere_nodepath)

    def detector(self):
        if not self.enable:
            return

        self.game.gui.cTrav.traverse(self.game.world.root_node)

        if self.sphere_handler.getNumEntries() > 0:
            #self.sphere_handler.sortEntries()
            self.game.world.avatar.setPos(self.game.world.root_node, self.lastpos)

        if self.ray_handler.getNumEntries() > 0:
            self.ray_handler.sortEntries()
            pickedObj = self.ray_handler.getEntry(0).getIntoNodePath()
            pickedObj = pickedObj.findNetTag('Chunk')
            if not pickedObj.isEmpty():
                Z = self.ray_handler.getEntry(0).\
                                            getSurfacePoint(self.game.world.root_node).getZ()
                if self.fly:
                    if Z > self.game.world.avatar.getZ(self.game.world.root_node):
                        self.game.world.avatar.setZ(self.game.world.root_node, Z)
                else:
                    self.game.world.avatar.setZ(self.game.world.root_node, Z)
Exemplo n.º 27
0
class App(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)

		base.disableMouse()

		#Carrega o terreno
		self.terrain = loadCharEnvir().loadEnvir()


		#Declaracao de variaveis
		self.isMoving = False
		self.getClick = 0			#Quantos objetos foram clicados
		self.clickedObj = None
		self.terrainSize = 1024
		self.numLizards = 5
		self.numMaleLizards = 0
		self.numFemaleLizards = 0
		#self.contChamGetMed = 0		#Contador para saber se atualiza o ponto medio


		#Carrega os lagartos iniciais
		self.lizards = []
		for i in range(self.numLizards):
			randNum = random.randint(10,20)
			randNum2 = random.randint(10,20)
			lizard = loadCharEnvir().loadLizard(100 + (randNum+randNum2)*i,150 + (randNum+randNum2)*i,3)
			lizard.setTag("ID",str(i))
			self.lizards.append(lizard)
			if (lizard.getTag("femaleOrMale") == "1"):
				self.numMaleLizards = self.numMaleLizards + 1
			else:
				self.numFemaleLizards = self.numFemaleLizards + 1



		#Calcula o ponto medio dos lagartos, tanto femeas quantos machos
		self.getMedianGenderPoints()
		#taskMgr.add(self.getCloserToMedian, "Aproxima os lagartos do ponto medio dos generos")



 

		#Adiciona as tasks e as funcoes de teclado e mouse
		self.taskMgr.add(self.updateTask, "update")
		self.keyboardSetup()


		#CAMERAS:
		#Faz a camera seguir o lagarto
		#self.followcam = FollowCam(self.camera, self.lizards[0])

		#Faz a camera visualizar como um deus
		self.MoveCam = MoveCam(self.camera)


		#Ativa as colisoes
		self.setupMouseCollision()


	#Funcao que ajusta o angulo
	def clampAngle(self, angle):
		while angle < -180:
			angle = angle + 360
		while angle > 180:
			angle = angle -360

		return angle


	#Atribui um valor especifico para uma chave
	def keyboardSetup(self):
		self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
		self.accept("escape", sys.exit)
		self.accept("arrow_left", self.setKey, ["left", 1])
		self.accept("arrow_left-up", self.setKey, ["left", 0])
		self.accept("arrow_right", self.setKey, ["right", 1])
		self.accept("arrow_right-up", self.setKey, ["right", 0])
		self.accept("arrow_up", self.setKey, ["forward", 1])
		self.accept("arrow_up-up", self.setKey, ["forward", 0])
		self.accept("arrow_down", self.setKey, ["backward", 1])
		self.accept("arrow_down-up", self.setKey, ["backward", 0])
		self.accept("mouse1", self.leftMouseCommands)	#Pode ser adicionado um drag aqui
		self.accept("mouse3", self.rightMouseCommands)


	#Funcao que calcula o ponto medio da densidade de lagartos de cada genero
	def getMedianGenderPoints(self):
			self.medianMalePoint = (0,0,0)
			self.medianFemalePoint = (0,0,0)

			#Calculo do somatorio dos pontos para cada genero
			for i in range(self.numLizards):
				if (self.lizards[i].getTag("femaleOrMale") == "1"):
					self.medianMalePoint = self.lizards[i].getPos() + self.medianMalePoint
				else:
					self.medianFemalePoint = self.lizards[i].getPos() + self.medianFemalePoint

			#Calculo do ponto medio de cada genero
			if (self.numMaleLizards != 0):
				self.medianMalePoint = (self.medianMalePoint[0]/self.numMaleLizards, self.medianMalePoint[1]/self.numMaleLizards, self.medianMalePoint[2]/self.numMaleLizards)
			if (self.numFemaleLizards != 0):
				self.medianFemalePoint = (self.medianFemalePoint[0]/self.numFemaleLizards, self.medianFemalePoint[1]/self.numFemaleLizards, self.medianFemalePoint[2]/self.numFemaleLizards)



#=====================================================================================
	#NAO ESTA PRONTA // NAO FUNCIONA
	#Funcao que faz com que os lagartos, dependendo do genero, aproximem-se
#=====================================================================================

	"""
	def getCloserToMedian(self, task):

		maleMedianPoint = render.attachNewNode("male median point")
		maleMedianPoint.setPos(self.medianMalePoint)
		femaleMedianPoint = render.attachNewNode("female median point")
		femaleMedianPoint.setPos(self.medianFemalePoint)

		for i in range(self.numLizards):
			#Se for macho, procura for femeas
			if (self.lizards[i].getTag("femaleOrMale") == 1):
				lizardAuxPoint = render.attachNewNode("ponto auxiliar para obter heading")
				lizardAuxPoint.setPos(self.lizards[i].getPos())
				lizardAuxPoint.lookAt(femaleMedianPoint)
				self.lizards[i].setH(self.clampAngle(lizardAuxPoint.getH() + 180))
				self.lizards[i].setPos(self.lizards[i], self.lizards[i].getRelativeVector(femaleMedianPoint, Vec3(0.1,-0.1,0)))	
				print self.lizards[i].getRelativeVector(femaleMedianPoint, Vec3(0.1,-0.1,0))
				
				#Respeitando os limites do terreno
				if (self.lizards[i].getX() < 0):
					self.lizards[i].setX(0)
				elif (self.lizards[i].getX() > self.terrainSize):
					self.lizards[i].setX(self.terrainSize)
				if (self.lizards[i].getY() < 0):
					self.lizards[i].setY(0)
				elif (self.lizards[i].getY() > self.terrainSize):
					self.lizards[i].setY(self.terrainSize)
	
			#Se for femea, procura por machos
			else:
				self.lizards[i].lookAt(maleMedianPoint)
				self.lizards[i].setPos(self.lizards[i], self.lizards[i].getRelativeVector(maleMedianPoint, Vec3(0.1,-0.1,0)))
				
				#Respeitando os limites do terreno
				if (self.lizards[i].getX() < 0):
					self.lizards[i].setX(0)
				elif (self.lizards[i].getX() > self.terrainSize):
					self.lizards[i].setX(self.terrainSize)
				if (self.lizards[i].getY() < 0):
					self.lizards[i].setY(0)
				elif (self.lizards[i].getY() > self.terrainSize):
					self.lizards[i].setY(self.terrainSize)

			#Faz uma atualizacao pra saber se deve atualizar o ponto medio
			self.contChamGetMed = self.contChamGetMed + 1
			if (self.contChamGetMed == 1000):
				self.contChamGetMed = 0
				self.getMedianGenderPoints()

		return task.cont"""
				

#=====================================================================================
#A ATRIBUICAO DO BOTAO DIREITO SERA COMPLETAMENTE REFEITA, E ESTA SERVE APENAS PARA ILUSTRAR A IDEIA
#ESTA ATRIBUICAO ESTA ERRADA
#=====================================================================================
	def rightMouseCommands(self):
		if self.mouseWatcherNode.hasMouse():
			mpos = base.mouseWatcherNode.getMouse()
			if (self.clickedObj != None):
				self.moveCharacter(mpos.getX(), mpos.getY())


	#FUNCAO PROVISORIA:
	#FALTA AJUSTAR - COMO FAZER PARA OPERAR AS ENTRADAS SEPARADAMENTE?
	def moveCharacter(self, posX, posY):
		self.mClickRay.setFromLens(self.camNode, posX, posY)
		self.mClicker.traverse(self.render)
		if (self.mCollisionQue.getNumEntries() > 0):
			self.mCollisionQue.sortEntries()
			entry = self.mCollisionQue.getEntry(0)

			self.target = render.attachNewNode("target point")
			self.target.setPos(2*self.clickedObj.getX() - entry.getSurfacePoint(render).getX(), 2*self.clickedObj.getY() - entry.getSurfacePoint(render).getY(), entry.getSurfacePoint(render).getZ())
			self.finalPosY = self.target.getY()
			self.finalPosX = self.target.getX()

			finalHeading = render.attachNewNode("final heading")
			finalHeading.setPos(self.clickedObj.getPos())
			finalHeading.lookAt(self.target.getPos())
			self.Heading = finalHeading.getH()
			self.Heading = self.clampAngle(self.Heading)

			if (self.Heading-self.clickedObj.getH() > 150):
				turnTime = 4
			else:
				if (self.Heading-self.clickedObj.getH() > 100):
					turnTime = 3
				else:
					if (self.Heading-self.clickedObj.getH() > 50):
						turnTime = 2
					else:
						if (self.Heading-self.clickedObj.getH() < -50):
							turnTime = 2
						else:
							if (self.Heading-self.clickedObj.getH() < -100):
								turnTime = 3
							else:
								if (self.Heading-self.clickedObj.getH() < -150):
									turnTime = 4
								else:
									turnTime = 1
			self.deltaSX = self.target.getX()-self.clickedObj.getX()
			self.deltaSY = self.target.getY()-self.clickedObj.getY()
			self.deltaS = sqrt((self.target.getY()-self.clickedObj.getY())*(self.target.getY()-self.clickedObj.getY()) + (self.target.getX()-self.clickedObj.getX())*(self.target.getX()-self.clickedObj.getX()))
			t = self.deltaS/3
			changeHeading = self.clickedObj.hprInterval(turnTime, (self.Heading,0,0), (self.clickedObj.getH(),0,0))
			changePos = self.clickedObj.posInterval(t, self.target.getPos(), self.clickedObj.getPos())
			self.clickedObj.loop("walk", restart = 0)
			self.counter = 0
			moveInterv = Sequence(changeHeading, Func(self.stopAnimation))
			moveInterv.start()
			
	def stopAnimation(self):
		taskMgr.add(self.movingCharacter, "moving character")

	def movingCharacter(self,task):
		if self.counter < 130:
			self.clickedObj.setX(self.clickedObj.getX() - self.deltaSX/130)
			self.clickedObj.setY(self.clickedObj.getY() - self.deltaSY/130)
			self.counter = self.counter + 1
			return task.cont
		else:
			self.clickedObj.stop()
			taskMgr.remove("moving character")	


#=====================================================================================
#=====================================================================================
#=====================================================================================


	#Atribui valor a uma chave
	def setKey(self, key, value):
		self.keyMap[key] = value



	#Atualiza o game
	def updateTask(self, task):
		self.updateLizard()
		return Task.cont



	#Funcao do botao esquerdo do mouse
	def leftMouseCommands(self):
		if self.mouseWatcherNode.hasMouse():
			mpos = base.mouseWatcherNode.getMouse()

			self.mClickRay.setFromLens(self.camNode, mpos.getX(), mpos.getY())

			self.mClicker.traverse(self.render)

			if (self.mCollisionQue.getNumEntries() > 0):
				self.mCollisionQue.sortEntries()
				entry = self.mCollisionQue.getEntry(0)
				clickedObject = entry.getIntoNodePath()

				clickedObject = clickedObject.findNetTag("clickable")
				if not clickedObject.isEmpty():
					pos = entry.getSurfacePoint(self.render)
					self.getClick = 1
					clickedObjectId = clickedObject.findNetTag("ID")
					self.clickedObjId = clickedObjectId
					#Procura o lagarto clicado
					for i in range(self.numLizards):
						if (self.lizards[i].getTag("ID") == self.clickedObjId.getTag("ID")):
							self.clickedObj = self.lizards[i]
					return
				else:
					#Zera se nao houverem objetos clicaveis proximos
					self.getClick = 0




	#Define a colisao do mouse com objetos no terreno
	def setupMouseCollision(self):

		self.mClicker = CollisionTraverser()          
		self.mCollisionQue    = CollisionHandlerQueue()

		self.mClickRay = CollisionRay()
		self.mClickRay.setOrigin(self.camera.getPos(self.render))
		self.mClickRay.setDirection(render.getRelativeVector(camera, Vec3(0,1,0)))

		self.mClickNode = CollisionNode('clickRay')
		self.mClickNode.addSolid(self.mClickRay)

		self.mClickNP = self.camera.attachNewNode(self.mClickNode)

		self.mClickNode.setFromCollideMask(GeomNode.getDefaultCollideMask())

		self.mClicker.addCollider(self.mClickNP, self.mCollisionQue)



	#Atualiza o personagem se algum botao foi pressionado
	#POSTERIORMENTE SERA RETIRADA - ESTA AQUI APENAS PARA DEBUG/EXEMPLIFICACAO
	def updateLizard(self):
		speedFactor = 3

		if (self.getClick != 0):

			#Se o personagem esta se mexendo, rode a animacao
			#BUG - Se o jogador estiver pressionando o botao de andar enquanto muda de personagem, trava a animacao
			if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0) or (self.keyMap["backward"]!=0): 
				if self.isMoving is False: 
					self.clickedObj.loop("walk", restart = 0) 
					self.isMoving = True 
			else: 
				if self.isMoving: 
					self.clickedObj.stop() 
					self.isMoving = False 

			#if (self.clicked != None):
			if (self.keyMap["left"]!=0):
				self.clickedObj.setH(self.clickedObj.getH()+1)
			elif (self.keyMap["right"]!=0):
				self.clickedObj.setH(self.clickedObj.getH()-1)
			if (self.keyMap["forward"]!=0):
				self.clickedObj.setY(self.clickedObj, -speedFactor)
			elif (self.keyMap["backward"]!=0):
				self.clickedObj.setY(self.clickedObj, speedFactor)

			#Respeitando os limites do terreno
			if (self.clickedObj.getX() < 0):
				self.clickedObj.setX(0)
			elif (self.clickedObj.getX() > self.terrainSize):
				self.clickedObj.setX(self.terrainSize)
			if (self.clickedObj.getY() < 0):
				self.clickedObj.setY(0)
			elif (self.clickedObj.getY() > self.terrainSize):
				self.clickedObj.setY(self.terrainSize)
Exemplo n.º 28
0
class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        base.disableMouse()

        #Carrega o terreno
        self.terrain = loadCharEnvir().loadEnvir()

        #Declaracao de variaveis
        self.isMoving = False
        self.getClick = 0  #Quantos objetos foram clicados
        self.clickedObj = None
        self.terrainSize = 1024
        self.numLizards = 5
        self.numMaleLizards = 0
        self.numFemaleLizards = 0
        #self.contChamGetMed = 0		#Contador para saber se atualiza o ponto medio

        #Carrega os lagartos iniciais
        self.lizards = []
        for i in range(self.numLizards):
            randNum = random.randint(10, 20)
            randNum2 = random.randint(10, 20)
            lizard = loadCharEnvir().loadLizard(100 + (randNum + randNum2) * i,
                                                150 + (randNum + randNum2) * i,
                                                3)
            lizard.setTag("ID", str(i))
            self.lizards.append(lizard)
            if (lizard.getTag("femaleOrMale") == "1"):
                self.numMaleLizards = self.numMaleLizards + 1
            else:
                self.numFemaleLizards = self.numFemaleLizards + 1

        #Calcula o ponto medio dos lagartos, tanto femeas quantos machos
        self.getMedianGenderPoints()
        #taskMgr.add(self.getCloserToMedian, "Aproxima os lagartos do ponto medio dos generos")

        #Adiciona as tasks e as funcoes de teclado e mouse
        self.taskMgr.add(self.updateTask, "update")
        self.keyboardSetup()

        #CAMERAS:
        #Faz a camera seguir o lagarto
        #self.followcam = FollowCam(self.camera, self.lizards[0])

        #Faz a camera visualizar como um deus
        self.MoveCam = MoveCam(self.camera)

        #Ativa as colisoes
        self.setupMouseCollision()

    #Funcao que ajusta o angulo
    def clampAngle(self, angle):
        while angle < -180:
            angle = angle + 360
        while angle > 180:
            angle = angle - 360

        return angle

    #Atribui um valor especifico para uma chave
    def keyboardSetup(self):
        self.keyMap = {"left": 0, "right": 0, "forward": 0, "backward": 0}
        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("arrow_down", self.setKey, ["backward", 1])
        self.accept("arrow_down-up", self.setKey, ["backward", 0])
        self.accept("mouse1",
                    self.leftMouseCommands)  #Pode ser adicionado um drag aqui
        self.accept("mouse3", self.rightMouseCommands)

    #Funcao que calcula o ponto medio da densidade de lagartos de cada genero
    def getMedianGenderPoints(self):
        self.medianMalePoint = (0, 0, 0)
        self.medianFemalePoint = (0, 0, 0)

        #Calculo do somatorio dos pontos para cada genero
        for i in range(self.numLizards):
            if (self.lizards[i].getTag("femaleOrMale") == "1"):
                self.medianMalePoint = self.lizards[i].getPos(
                ) + self.medianMalePoint
            else:
                self.medianFemalePoint = self.lizards[i].getPos(
                ) + self.medianFemalePoint

        #Calculo do ponto medio de cada genero
        if (self.numMaleLizards != 0):
            self.medianMalePoint = (self.medianMalePoint[0] /
                                    self.numMaleLizards,
                                    self.medianMalePoint[1] /
                                    self.numMaleLizards,
                                    self.medianMalePoint[2] /
                                    self.numMaleLizards)
        if (self.numFemaleLizards != 0):
            self.medianFemalePoint = (self.medianFemalePoint[0] /
                                      self.numFemaleLizards,
                                      self.medianFemalePoint[1] /
                                      self.numFemaleLizards,
                                      self.medianFemalePoint[2] /
                                      self.numFemaleLizards)

#=====================================================================================
#NAO ESTA PRONTA // NAO FUNCIONA
#Funcao que faz com que os lagartos, dependendo do genero, aproximem-se
#=====================================================================================

    """
	def getCloserToMedian(self, task):

		maleMedianPoint = render.attachNewNode("male median point")
		maleMedianPoint.setPos(self.medianMalePoint)
		femaleMedianPoint = render.attachNewNode("female median point")
		femaleMedianPoint.setPos(self.medianFemalePoint)

		for i in range(self.numLizards):
			#Se for macho, procura for femeas
			if (self.lizards[i].getTag("femaleOrMale") == 1):
				lizardAuxPoint = render.attachNewNode("ponto auxiliar para obter heading")
				lizardAuxPoint.setPos(self.lizards[i].getPos())
				lizardAuxPoint.lookAt(femaleMedianPoint)
				self.lizards[i].setH(self.clampAngle(lizardAuxPoint.getH() + 180))
				self.lizards[i].setPos(self.lizards[i], self.lizards[i].getRelativeVector(femaleMedianPoint, Vec3(0.1,-0.1,0)))	
				print self.lizards[i].getRelativeVector(femaleMedianPoint, Vec3(0.1,-0.1,0))
				
				#Respeitando os limites do terreno
				if (self.lizards[i].getX() < 0):
					self.lizards[i].setX(0)
				elif (self.lizards[i].getX() > self.terrainSize):
					self.lizards[i].setX(self.terrainSize)
				if (self.lizards[i].getY() < 0):
					self.lizards[i].setY(0)
				elif (self.lizards[i].getY() > self.terrainSize):
					self.lizards[i].setY(self.terrainSize)
	
			#Se for femea, procura por machos
			else:
				self.lizards[i].lookAt(maleMedianPoint)
				self.lizards[i].setPos(self.lizards[i], self.lizards[i].getRelativeVector(maleMedianPoint, Vec3(0.1,-0.1,0)))
				
				#Respeitando os limites do terreno
				if (self.lizards[i].getX() < 0):
					self.lizards[i].setX(0)
				elif (self.lizards[i].getX() > self.terrainSize):
					self.lizards[i].setX(self.terrainSize)
				if (self.lizards[i].getY() < 0):
					self.lizards[i].setY(0)
				elif (self.lizards[i].getY() > self.terrainSize):
					self.lizards[i].setY(self.terrainSize)

			#Faz uma atualizacao pra saber se deve atualizar o ponto medio
			self.contChamGetMed = self.contChamGetMed + 1
			if (self.contChamGetMed == 1000):
				self.contChamGetMed = 0
				self.getMedianGenderPoints()

		return task.cont"""

    #=====================================================================================
    #A ATRIBUICAO DO BOTAO DIREITO SERA COMPLETAMENTE REFEITA, E ESTA SERVE APENAS PARA ILUSTRAR A IDEIA
    #ESTA ATRIBUICAO ESTA ERRADA
    #=====================================================================================
    def rightMouseCommands(self):
        if self.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            if (self.clickedObj != None):
                self.moveCharacter(mpos.getX(), mpos.getY())

    #FUNCAO PROVISORIA:
    #FALTA AJUSTAR - COMO FAZER PARA OPERAR AS ENTRADAS SEPARADAMENTE?
    def moveCharacter(self, posX, posY):
        self.mClickRay.setFromLens(self.camNode, posX, posY)
        self.mClicker.traverse(self.render)
        if (self.mCollisionQue.getNumEntries() > 0):
            self.mCollisionQue.sortEntries()
            entry = self.mCollisionQue.getEntry(0)

            self.target = render.attachNewNode("target point")
            self.target.setPos(
                2 * self.clickedObj.getX() -
                entry.getSurfacePoint(render).getX(),
                2 * self.clickedObj.getY() -
                entry.getSurfacePoint(render).getY(),
                entry.getSurfacePoint(render).getZ())
            self.finalPosY = self.target.getY()
            self.finalPosX = self.target.getX()

            finalHeading = render.attachNewNode("final heading")
            finalHeading.setPos(self.clickedObj.getPos())
            finalHeading.lookAt(self.target.getPos())
            self.Heading = finalHeading.getH()
            self.Heading = self.clampAngle(self.Heading)

            if (self.Heading - self.clickedObj.getH() > 150):
                turnTime = 4
            else:
                if (self.Heading - self.clickedObj.getH() > 100):
                    turnTime = 3
                else:
                    if (self.Heading - self.clickedObj.getH() > 50):
                        turnTime = 2
                    else:
                        if (self.Heading - self.clickedObj.getH() < -50):
                            turnTime = 2
                        else:
                            if (self.Heading - self.clickedObj.getH() < -100):
                                turnTime = 3
                            else:
                                if (self.Heading - self.clickedObj.getH() <
                                        -150):
                                    turnTime = 4
                                else:
                                    turnTime = 1
            self.deltaSX = self.target.getX() - self.clickedObj.getX()
            self.deltaSY = self.target.getY() - self.clickedObj.getY()
            self.deltaS = sqrt((self.target.getY() - self.clickedObj.getY()) *
                               (self.target.getY() - self.clickedObj.getY()) +
                               (self.target.getX() - self.clickedObj.getX()) *
                               (self.target.getX() - self.clickedObj.getX()))
            t = self.deltaS / 3
            changeHeading = self.clickedObj.hprInterval(
                turnTime, (self.Heading, 0, 0), (self.clickedObj.getH(), 0, 0))
            changePos = self.clickedObj.posInterval(t, self.target.getPos(),
                                                    self.clickedObj.getPos())
            self.clickedObj.loop("walk", restart=0)
            self.counter = 0
            moveInterv = Sequence(changeHeading, Func(self.stopAnimation))
            moveInterv.start()

    def stopAnimation(self):
        taskMgr.add(self.movingCharacter, "moving character")

    def movingCharacter(self, task):
        if self.counter < 130:
            self.clickedObj.setX(self.clickedObj.getX() - self.deltaSX / 130)
            self.clickedObj.setY(self.clickedObj.getY() - self.deltaSY / 130)
            self.counter = self.counter + 1
            return task.cont
        else:
            self.clickedObj.stop()
            taskMgr.remove("moving character")


#=====================================================================================
#=====================================================================================
#=====================================================================================

#Atribui valor a uma chave

    def setKey(self, key, value):
        self.keyMap[key] = value

    #Atualiza o game
    def updateTask(self, task):
        self.updateLizard()
        return Task.cont

    #Funcao do botao esquerdo do mouse
    def leftMouseCommands(self):
        if self.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()

            self.mClickRay.setFromLens(self.camNode, mpos.getX(), mpos.getY())

            self.mClicker.traverse(self.render)

            if (self.mCollisionQue.getNumEntries() > 0):
                self.mCollisionQue.sortEntries()
                entry = self.mCollisionQue.getEntry(0)
                clickedObject = entry.getIntoNodePath()

                clickedObject = clickedObject.findNetTag("clickable")
                if not clickedObject.isEmpty():
                    pos = entry.getSurfacePoint(self.render)
                    self.getClick = 1
                    clickedObjectId = clickedObject.findNetTag("ID")
                    self.clickedObjId = clickedObjectId
                    #Procura o lagarto clicado
                    for i in range(self.numLizards):
                        if (self.lizards[i].getTag("ID") ==
                                self.clickedObjId.getTag("ID")):
                            self.clickedObj = self.lizards[i]
                    return
                else:
                    #Zera se nao houverem objetos clicaveis proximos
                    self.getClick = 0

    #Define a colisao do mouse com objetos no terreno
    def setupMouseCollision(self):

        self.mClicker = CollisionTraverser()
        self.mCollisionQue = CollisionHandlerQueue()

        self.mClickRay = CollisionRay()
        self.mClickRay.setOrigin(self.camera.getPos(self.render))
        self.mClickRay.setDirection(
            render.getRelativeVector(camera, Vec3(0, 1, 0)))

        self.mClickNode = CollisionNode('clickRay')
        self.mClickNode.addSolid(self.mClickRay)

        self.mClickNP = self.camera.attachNewNode(self.mClickNode)

        self.mClickNode.setFromCollideMask(GeomNode.getDefaultCollideMask())

        self.mClicker.addCollider(self.mClickNP, self.mCollisionQue)

    #Atualiza o personagem se algum botao foi pressionado
    #POSTERIORMENTE SERA RETIRADA - ESTA AQUI APENAS PARA DEBUG/EXEMPLIFICACAO
    def updateLizard(self):
        speedFactor = 3

        if (self.getClick != 0):

            #Se o personagem esta se mexendo, rode a animacao
            #BUG - Se o jogador estiver pressionando o botao de andar enquanto muda de personagem, trava a animacao
            if (self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or (
                    self.keyMap["right"] != 0) or (self.keyMap["backward"] !=
                                                   0):
                if self.isMoving is False:
                    self.clickedObj.loop("walk", restart=0)
                    self.isMoving = True
            else:
                if self.isMoving:
                    self.clickedObj.stop()
                    self.isMoving = False

            #if (self.clicked != None):
            if (self.keyMap["left"] != 0):
                self.clickedObj.setH(self.clickedObj.getH() + 1)
            elif (self.keyMap["right"] != 0):
                self.clickedObj.setH(self.clickedObj.getH() - 1)
            if (self.keyMap["forward"] != 0):
                self.clickedObj.setY(self.clickedObj, -speedFactor)
            elif (self.keyMap["backward"] != 0):
                self.clickedObj.setY(self.clickedObj, speedFactor)

            #Respeitando os limites do terreno
            if (self.clickedObj.getX() < 0):
                self.clickedObj.setX(0)
            elif (self.clickedObj.getX() > self.terrainSize):
                self.clickedObj.setX(self.terrainSize)
            if (self.clickedObj.getY() < 0):
                self.clickedObj.setY(0)
            elif (self.clickedObj.getY() > self.terrainSize):
                self.clickedObj.setY(self.terrainSize)
Exemplo n.º 29
0
class World(DirectObject):

    def __init__(self):
               
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)
        
        host = "localhost"
        port = 9898
        self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
        #self.received = 1
        
        #store a dictionary of active players with username player as key value pair
        #the dictionary also contain a special player named panda
        self.players = {}
        
        #for display the list on the screen
        self.temp = []
        
        #store a dictionary of playerObject
        self.playerObjects = {}
        self.render = render
        self.loginSuccessful = False
        self.isMoving = False
        self.justStoping = False
        self.targetPlayer = None        
        
        if self.connection:
            self.cReader.addConnection(self.connection)
            taskMgr.add(self.updateRoutine, 'updateRoutine')
            #taskMgr.doMethodLater(0.5, self.updateRoutine, 'updateRoutine')
            #taskMgr.add(self.updatePandaAttack, 'updatePandaAttack')
            #taskMgr.doMethodLater(3, self.updatePandaAttack, 'updatePandaAttack')
            self.loginRegister()
            

    #################Communication Method################
    
    def loginRegister(self):
        print "1. Login"
        print "2. Register"
        userInput = str(raw_input("Enter 1 or 2: "))
        if userInput == "1":
            self.login()
        elif userInput == "2":
            self.register();
        else:
            print "Invalid input"
            self.loginRegister()
    
    def register(self):
        print "Please enter your username: "******"Please enter your password: "******"{} {} {}".format(REGISTER, username, password)
        self.sendRequest(msg)
    
    #define self.username to specify the username for this object   
    def login(self):
        print "Please enter your username: "******"Please enter your password: "******"{} {} {}".format(LOGIN, self.username, password)            
        self.sendRequest(msg)
  
    #user need to press esc key to logout       
    def logout(self, x, y, z, h):
        print "logout called"
        player = self.players[self.username]
        
        msg = "{} {},{},{},{},{}".format(LOGOUT, self.username, 
                        player.getX(), player.getY(), player.getZ(), player.getH())         
        print msg          
        self.sendRequest(msg)
        sys.exit()  
    
    def updateMovement(self, isMove, x, y, z, h):
        #send code username,ismove,x,y,z,h to the server according to the protocol
        msg = "{} {},{},{},{},{},{}".format(UPDATE_PLAYER_MOVE, self.username, isMove, x, y, z, h)
        self.sendRequest(msg)
    
    def possibleAttackRequest(self, distance):
        msg = "{} {},{}".format(PANDA_ATTACK_REQUEST, self.username, distance)
        self.sendRequest(msg)
        
    def composeStringMessage(self, msg):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(msg)
        return myPyDatagram
                
    def retrieveStringMessage(self,datagram):
        myIterator = PyDatagramIterator(datagram)
        msg = myIterator.getString()
        #print msg, " received"
        return msg
            
#     def sendRequest(self):
#         if(self.received):
#             print "->Client request:"
#             # Send a request to the server
#         mylist = ["apple", "ball", "cat", "dog"] 
#         
#         msg = random.choice(mylist)
#         request = self.composeStringMessage(msg)
#         ack = self.cWriter.send(request,self.connection)                
#         print msg, " sent"
#         self.received = 0

    def sendRequest(self, msg):
        request = self.composeStringMessage(msg)
        ack = self.cWriter.send(request,self.connection)                
        #print msg, " sent"
        #self.received = 0
        
    def receiveResponse(self):
        #print "<-Server response:"
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                msg = self.retrieveStringMessage(datagram)
                msgs = msg.split(' ')
                #print msgs[0]
                
                if msgs[0] == REGISTER_SUCCESSFUL:
                    self.registerSuccessfulResponse()
                elif msgs[0] == USERNAME_EXIST:
                    self.usernameExistResponse()
                elif msgs[0] == LOGIN_SUCCESSFUL:
                    self.loginSuccessfulResponse(msgs[1])
                elif msgs[0] == ADD_NEW_PLAYER:
                    self.addNewPlayerResponse(msgs[1])
                elif msgs[0] == LOGIN_FAIL:
                    self.loginFailResponse()
                elif msgs[0] == LOGOUT:
                    self.logoutResponse(msgs[1])
                elif msgs[0] == UPDATE_PLAYER_MOVE_RESPONSE:
                    self.updateMoveResponse(msgs[1])
                elif msgs[0] == PANDA_ATTACK:
                    self.pandaAttackResponse(msgs[1])
                #self.received = 1
                
#     def communicate(self):
#         #print "communicate"
#         #self.sendRequest()
#         self.receiveResponse()
        
    def updateRoutine(self,task):
        #self.communicate()
        self.receiveResponse()
        return task.again;
    
    def registerSuccessfulResponse(self):
        print "You have successfully registered. Please login to start the game."
        self.login()
    
    def usernameExistResponse(self):
        print "Username already exist. Please choose another username."
        self.register()
    
    #initail a dictionary of players
    def loginSuccessfulResponse(self, playerListMsg):
        actorsMsg = playerListMsg.split(":")
        #the dictionary also adds a special player named panda
        for aMsg in actorsMsg:
            elements = aMsg.split(",")
            actor = Player(elements[0], float(elements[1]), float(elements[2]), float(elements[3]), 
                           float(elements[4]))
            self.players[elements[0]] = actor
            
        print "login successful"
        
        #display other players' Ralph
        for username, value in self.players.iteritems():
            if username == self.username:
                #display this player's Ralph
                self.showRalph(value)      
            elif username != self.username and username != "panda":
                self.createActor(self.render, value)
            elif username == "panda":
                self.createPanda(self.render, value)
            else:
                pass
        
        self.loginSuccessful = True       
    
    #add new player to the players dictionary
    def addNewPlayerResponse(self, msg):
        elements = msg.split(",")
        actor = Player(elements[0], float(elements[1]), float(elements[2]), float(elements[3]), 
                       float(elements[4]))
        self.players[elements[0]] = actor        
        print "add new player: ", self.players[elements[0]].getUsername(), self.players[elements[0]].getX()
        self.createActor(self.render, actor)
        
        ###Line's Added###
        textMsg = elements[0]+" has logged in"
        self.notifyPlayer(textMsg)
        
    def loginFailResponse(self):
        print "Username and password does not match, please re-login or register."
        self.loginRegister()
        
    def logoutResponse(self, username):
        if username in self.players:
            del self.players[username]
        
        if username in self.playerObjects:
            playerObject = self.playerObjects[username]
            playerObject.getActor().delete()
        
            del self.playerObjects[username]
        #self.playerObjects
        print "{} logout".format(username)
        
        ###Lines Added###
        msg = username+" has logged out"
        self.notifyPlayer(msg)
        
    def notifyPlayer(self,msg):
        #label = DirectLabel(text=msg)
        label = OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
        taskMgr.doMethodLater(5, self.destroyLabel, 'destroyLabel', extraArgs=[label])
        
    def destroyLabel(self,label):
        label.destroy()
        
    def updateMoveResponse(self, msg):
        if self.loginSuccessful:
            #msg contain username,isMoving,x,y,z,h
            msgs = msg.split(",")
            username = msgs[0]
            if username == self.username:
                #self already move, no need to update
                pass
            else:
                if username in self.playerObjects.keys(): 
                    player = self.players[username]
                    player.setX(float(msgs[2]))
                    player.setY(float(msgs[3]))        
                    player.setZ(float(msgs[4]))    
                     
                    actor = self.playerObjects[username].getActor()
                    actor.setPos(float(msgs[2]), float(msgs[3]), float(msgs[4]))
                    actor.setH(float(msgs[5]))
                    self.playerObjects[username].move(msgs[1])
    
    def pandaAttackResponse(self, msg):
        #msg contain targetUsername
        #print "pan Att: ", msg
        #msgs = msg.split(",")
        
        targetUsername = msg
        targetPlayer = self.players[targetUsername]

        pandaActor = self.pandaObject.getActor()
        pandax = pandaActor.getX()
        panday = pandaActor.getY()
        pandaz = pandaActor.getZ()        
         
        x = targetPlayer.getX()
        y = targetPlayer.getY()
        z = targetPlayer.getZ()
         
        distance = self.getDistance(pandax, panday, pandaz, x, y, z)
      
        if distance < PANDA_ATTACK_RANGE:
            if pandax > x and panday > y:
                self.pandaObject.setH(135)
            elif pandax > x and panday < y:
                self.pandaObject.setH(180)
            elif pandax < x and panday > y:
                self.pandaObject.setH(135)
            else:
                self.pandaObject.setH(90)
            #self.pandaObject.turn(180)         
            self.pandaObject.move(x-0.5, y-0.5, z)
            
            panda = self.players["panda"]
            panda.setX(pandax);
            panda.setY(panday);
            panda.setZ(pandaz);
        
        #self.setTargetPlayer(msg)
        
    def setTargetPlayer(self, username):
        self.targetPlayer = self.players[username]
        
    def getTargetPlayer(self):
        return self.targetPlayer        
                    
    def createActor(self, render, actor):
        playerObject = PlayerObject(render, actor)
        self.playerObjects[actor.getUsername()] = playerObject
#         nameplate = TextNode('textNode username_' + str(actor.username))
#         nameplate.setText(actor.username)
#         npNodePath = actor.actor.attachNewNode(nameplate)
#         npNodePath.setScale(1.0)
#         npNodePath.setBillboardPointEye()
#         npNodePath.setZ(8.0)
        
    def createPanda(self, render, actor):
        self.pandaObject = PandaObject(render, actor)
        
    def checkPossibleAttack(self, x, y, z):
        panda = self.players["panda"]
        pandax = panda.getX();
        panday = panda.getY();
        pandaz = panda.getZ();
        
        distance = self.getDistance(pandax, panday, pandaz, x, y, z)
        
        if distance < PANDA_ATTACK_RANGE:
            self.possibleAttackRequest(distance)
            
    def getDistance(self, pandax, panday, pandaz, x, y, z):
        
        return math.sqrt( math.pow(pandax-x, 2) + math.pow(panday-y, 2) + math.pow(pandaz-z, 2) )
        
    #################################################################
    
    ################Ralph code ##################### 
       
    def showRalph(self, player):        
        
#         self.render = render
         
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))
 
        # Post the instructions
 
        #self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right")
        
        self.inst8 = addInstructions(0.60, "[l] Show Players on the right corner")
         
        # 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)
        self.environ.setPos(0,0,0)
        
        # 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)
        
        self.ralph.setPos(player.getX(), player.getY(), player.getZ())
        self.ralph.setH(player.getH())
        
        #####################################


        # 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("escape", self.logout, [self.ralph.getX(), self.ralph.getY(), self.ralph.getZ(), self.ralph.getH()])
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        
        # 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
        
    '''method to show player list'''
    def showPlayers(self, set):
        for i in self.temp:
            i.destroy()
        self.temp = []
        y=[]
        i = 0
        while(i!=set.__len__()):
            y.append(0.95-(i*0.05))
            i=i+1
        i = 0
        while(i!=y.__len__()):
            if set[i] == "panda":
                pass
            else:
                self.temp.append(OnscreenText(text=set[i], style=1, fg=(1,1,1,1),
                        pos=(1.3, y[i]), align=TextNode.ARight, scale = .07))
            i=i+1  

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):
        
        '''Call to Show player list'''
        x = self.players.keys()
        self.accept("l", self.showPlayers, [x])
        ''' call end '''

        # 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())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -25 * 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["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                self.ralph.loop("run")
                self.isMoving = True
                self.justStoping = False
        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk",5)
                self.isMoving = False
                self.justStoping = True
                
        
        #print self.ralph.getX(), self.ralph.getY(), self.ralph.getZ(), self.ralph.getH()
        if(self.isMoving or self.justStoping):       
            self.updateMovement(self.isMoving, self.ralph.getX(), self.ralph.getY(), 
                                self.ralph.getZ(), self.ralph.getH())
            
            #check if in panda attach range
            self.checkPossibleAttack(self.ralph.getX(), self.ralph.getY(), self.ralph.getZ())
            
            player = self.players[self.username]
            player.setX(self.ralph.getX())
            player.setY(self.ralph.getY())
            player.setZ(self.ralph.getZ())
            player.setH(self.ralph.getH())
            self.justStoping = 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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        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
Exemplo n.º 30
0
class Labryn(DirectObject):
    
    def keyControl(self):
        # get user input
        self.accept("escape", sys.exit) # ESC to quit
        self.accept("arrow_up",self.moveBallWrapper,["u"])
        self.accept("arrow_down",self.moveBallWrapper,["d"])
        self.accept("arrow_left",self.moveBallWrapper,["l"])
        self.accept("arrow_right",self.moveBallWrapper,["r"])
        self.accept("arrow_up_up",self.moveBallWrapper,[False])
        self.accept("arrow_down_up",self.moveBallWrapper,[False])
        self.accept("arrow_left_up",self.moveBallWrapper,[False])
        self.accept("arrow_right_up",self.moveBallWrapper,[False])
        self.accept("r", self.setCamera, [True])
        self.accept("r-up", self.setCamera, [False])

    def setCamera(self, spin):
        self.spin = spin
        
    def spinCamera(self, task):
        if self.spin == True:
            self.cameraSpinCount  += 1
            count = self.cameraSpinCount
            angleDegrees = count
            angleRadians =  angleDegrees * (pi/ 180)
            camera.setPos(12*cos(-pi/2+angleRadians),
                          12*sin(-pi/2+angleRadians), 25)
            camera.setHpr(angleDegrees,-65,0)
        return Task.cont
        
    def initialize(self):
        self.loadBackground(_BGIMG)
        self.loadMyPokemon()
        base.disableMouse()
        camera.setPosHpr(0,-12,25,0,-65,0)
        self.arrowKeyPressed = False
        self.pokemonDirection = None
        # direction the ball is going
        self.jerkDirection = None
        self.spin = False
        self.cameraSpinCount = 0
        self.jerk = (0,0,0)
        self.loadLabyrinth()
        self.keyControl()
        self.loadPokemonLevel1()
        self.light()
        self.loadBall()
        
    def loadBackground(self, imagePath):
        self.background = OnscreenImage(parent=render2dp, image=imagePath)
        base.cam2dp.node().getDisplayRegion(0).setSort(-20)

    def loadMyPokemon(self, pokes=['caterpie', 'charmander', 'geodude']):
        path = r"../google_drive/ball/data/img/myPoke"
        pokePath = path + r"/%s" %(pokes[0]) + r".png"
        poke = OnscreenImage(parent=aspect2d, image=pokePath, pos=(1,0,-0.8),
                             scale=(0.16,1,0.12))
        poke.setTransparency(TransparencyAttrib.MAlpha)
        
    def loadLabyrinth(self):
        self.MAZE = load_model("3.egg")
        self.MAZE.reparentTo(render)
        self.MAZE.setPos(0,0,0)
        self.MAZE.setHpr(90,0,0)

    def loadPokemonLevel1(self):
        self.pikachu = load_model("pikachu.egg")
        self.pikachu.reparentTo(render)
        self.pikachu.setScale(0.3)
        endPos = self.MAZE.find("**/end").getPos()
        self.pikachu.setPos(endPos) 

    def light(self):
        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))

    def loadBall(self):
        self.ballRoot = render.attachNewNode("ballRoot")
        self.ball = load_model("ball")
        self.ball.reparentTo(self.ballRoot)
        self.ball_tex = load_tex("pokeball.png")
        self.ball.setTexture(self.ball_tex,1)
        self.ball.setScale(0.8)
        # Find the collision sphere for the ball in egg.
        self.ballSphere = self.ball.find("**/ball")
        self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
        self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())
        #self.ballSphere.show()
        # Now we create a ray to cast down at the ball.
        self.ballGroundRay = CollisionRay()
        self.ballGroundRay.setOrigin(0,0,10)
        self.ballGroundRay.setDirection(0,0,-1)

        # Collision solids go in CollisionNode
        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)
        
        # light
        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))
        # material to the ball
        m = Material()
        m.setSpecular(Vec4(1,1,1,1))
        m.setShininess(96)
        self.ball.setMaterial(m,1)

    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))
                                         
        # 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)
        # collision traversers have a built-in tool to visualize collisons
        # self.cTrav.showCollisions(render)
        self.start()

    def pokemonTurn(self, pokemon, direction):
        if direction  == 'l' and self.pokemonDirection != 'l':
            pokemon.setH(-90)
        if direction  == 'r' and self.pokemonDirection != 'r':
            pokemon.setH(90)
        if direction  == 'd' and self.pokemonDirection != 'd':
            pokemon.setH(0)
        if direction  == 'u' and self.pokemonDirection != 'u':
            pokemon.setH(180)
                        
    def pokemonMove(self, pokemon, direction):
        self.pokemonTurn(pokemon, direction)
        if direction == 'l':
            newX = pokemon.getX() - _SPEED
            pokemon.setX(newX)
        elif direction == 'r':
            newX = pokemon.getX() + _SPEED
            pokemon.setX(newX)
        elif direction == 'u':
            newY = pokemon.getY() + _SPEED
            pokemon.setY(newY)
        elif direction == 'd':
            newY = pokemon.getY() - _SPEED
            pokemon.setY(newY)
        elif direction == "s": # stop
            pass
        
    def whereToGo(self, task):
        # this returns the direction pokemon should go
        # tell MAZE pokemon and ball's board position
        MAZE.setPokeCoord(self.pikachu.getX(), self.pikachu.getY())
        MAZE.setBallCoord(self.ballRoot.getX(), self.ballRoot.getY())
        # find out which direction to go
        direction = MAZE.getDecision()
        self.pokemonMove(self.pikachu,direction)
        return Task.cont

    def getInformation(self):
        # get information on the board
        pass
    
    def start(self):
        # maze model has a locator in it
        # self.ballRoot.show()
        startPos = self.MAZE.find("**/start").getPos()
        self.ballRoot.setPos(startPos) # set the ball in the pos
        self.ballV = Vec3(0,0,0) # initial velocity
        self.accelV = Vec3(0,0,0) # initial acceleration

        # for a traverser to work, need to call traverser.traverse()
        # base has a task that does this once a frame
        base.cTrav = self.cTrav

        # create the movement task, make sure its not already running
        taskMgr.remove("rollTask")
        taskMgr.add(self.spinCamera, "spinCamera")
        taskMgr.add(self.whereToGo, "whereToGo")
        taskMgr.add(lambda task: self.moveBall(task, self.jerkDirection),
                    "moveBall")
        self.mainLoop = taskMgr.add(self.rollTask, "rollTask")
        self.mainLoop.last = 0

    def moveBallWrapper(self, direction):
        if direction == False:
            self.arrowKeyPressed = False
        else:
            self.arrowKeyPressed = True
            self.jerkDirection = direction
        
    def moveBall(self, task, direction):
        if self.arrowKeyPressed == True:
            if direction == "u":
                self.jerk = Vec3(0,_JERK,0)
            elif direction == "d":
                self.jerk = Vec3(0,-_JERK,0)
            elif direction == "l":
                self.jerk = Vec3(-_JERK,0,0)
            elif direction == "r":
                self.jerk = Vec3(_JERK,0,0)
        return Task.cont
        
    # collision between ray and ground
    # info about the interaction is passed in colEntry
    def groundCollideHandler(self,colEntry):
        # set the ball to the appropriate Z for it to be on the ground
        newZ = colEntry.getSurfacePoint(render).getZ()
        self.ballRoot.setZ(newZ+.4)

        # up vector X normal vector
        norm = colEntry.getSurfaceNormal(render)
        accelSide = norm.cross(UP)
        self.accelV = norm.cross(accelSide)

    # collision between the ball and a wall
    def wallCollideHandler(self,colEntry):
        # some vectors needed to do the calculation
        norm = colEntry.getSurfaceNormal(render) * -1
        norm.normalize()
        curSpeed = self.ballV.length()
        inVec = self.ballV/curSpeed
        velAngle = norm.dot(inVec) # angle of incidance
        hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
        hitDir.normalize()
        hitAngle = norm.dot(hitDir)
    # deal with collision cases

        if velAngle > 0 and hitAngle >.995:
            # standard reflection equation
            reflectVec = (norm * norm.dot(inVec*-1)*2) + inVec

            # makes velocity half of hitting dead-on
            self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5))

            # a collision means the ball is already a little bit buried in
            # move it so exactly touching the wall
            disp = (colEntry.getSurfacePoint(render) -
                    colEntry.getInteriorPoint(render))
            newPos = self.ballRoot.getPos() + disp
            self.ballRoot.setPos(newPos)
            
    def rollTask(self,task):
        # 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 is a HICCUP
        # ignore the frame
        if dt > .2: return Task.cont

        # dispatch which function to handle the collision based on name
        for i in range(self.cHandler.getNumEntries()):
            entry = self.cHandler.getEntry(i)
            name = entry.getIntoNode().getName()
       
            if name == "Wall.004":
                self.wallCollideHandler(entry)
            elif name=="Cube.004":
                self.groundCollideHandler(entry)

        # read the mouse position and tilt the maze accordingly
        self.accelV += self.jerk
        # move the ball, update the velocity based on accel
        self.ballV += self.accelV * dt * ACCELERATION
        # clamp the velocity to the max speed
        if self.ballV.lengthSquared() > MAX_SPEED_SQ:
            self.ballV.normalize()
            self.ballV *= MAX_SPEED
        # update the position
        self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV*dt))

        # uses quaternion to rotate the ball
        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
Exemplo n.º 31
0
    def __init__(self):
        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)
        base.setBackgroundColor(0, 0, 0)

        self.accept("escape", sys.exit)  # Escape quits
        self.disableMouse()
        camera.setPosHpr(0, 0, 0, 0, 0, 0)

        lens = PerspectiveLens()
        lens.setFov(90, 60)
        lens.setNear(0.01)
        lens.setFar(100000)
        self.cam.node().setLens(lens)

        self.ballSize = 0.025
        self.cueLength = 0.2
        # self.ballRoot = render.attachNewNode("ballRoot")
        # #self.ball = loader.loadModel("models/ball")
        # self.ball = loader.loadModel("models/ball_0_center.egg")
        # #self.ball = loader.loadModel("models/ball.dae")
        # self.ball.setScale(ballSize, ballSize, ballSize)
        # self.ball.reparentTo(self.ballRoot)
        # #print(self.ball.getBounds())
        # #exit(1)
        # #self.ballSphere = self.ball.find("**/ball")
        # #print(self.ball.getScale()[0])
        # cs = CollisionSphere(0, 0, 0, 1)
        # self.ballSphere = self.ball.attachNewNode(CollisionNode('ball'))
        # self.ballSphere.node().addSolid(cs)

        # self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
        # self.ballSphere.node().setIntoCollideMask(BitMask32.bit(1))

        self.sceneIndex = 0
        self.planeInfo = PlaneScene(self.sceneIndex)

        self.planeScene = self.planeInfo.generateEggModel()
        self.planeScene.setTwoSided(True)
        self.planeScene.reparentTo(render)
        self.planeScene.hide()

        #get geometries from plane predictions
        planeTriangles, horizontalPlaneTriangles, self.gravityDirection = self.planeInfo.getPlaneTriangles(
        )

        # add pool balls
        self.ballRoots = []
        self.balls = []
        self.ballSpheres = []
        self.ballGroundRays = []
        for ballIndex in xrange(3):
            ballRoot = render.attachNewNode("ballRoot_" + str(ballIndex))
            ball = loader.loadModel("models/ball_" + str(ballIndex) +
                                    "_center.egg")
            ball.setScale(self.ballSize, self.ballSize, self.ballSize)

            cs = CollisionSphere(0, 0, 0, 1)
            ballSphere = ball.attachNewNode(
                CollisionNode('ball_' + str(ballIndex)))
            ballSphere.node().addSolid(cs)
            ballSphere.node().setFromCollideMask(
                BitMask32.bit(0) | BitMask32.bit(1) | BitMask32.bit(3)
                | BitMask32.bit(4))
            ballSphere.node().setIntoCollideMask(BitMask32.bit(1))

            ball.reparentTo(ballRoot)
            self.ballRoots.append(ballRoot)
            self.balls.append(ball)
            self.ballSpheres.append(ballSphere)

            ballGroundRay = CollisionRay()  # Create the ray
            ballGroundRay.setOrigin(0, 0, 0)  # Set its origin
            ballGroundRay.setDirection(
                self.gravityDirection[0], self.gravityDirection[1],
                self.gravityDirection[2])  # And its direction
            # Collision solids go in CollisionNode
            # Create and name the node
            ballGroundCol = CollisionNode('ball_ray_' + str(ballIndex))
            ballGroundCol.addSolid(ballGroundRay)  # Add the ray
            ballGroundCol.setFromCollideMask(
                BitMask32.bit(2))  # Set its bitmasks
            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)
            ballGroundColNp = ballRoot.attachNewNode(ballGroundCol)
            self.ballGroundRays.append(ballGroundColNp)

            ballRoot.hide()
            continue

        # Finally, we create a CollisionTraverser. CollisionTraversers are what
        # do the job of walking the scene graph and calculating collisions.
        # For a traverser to actually do collisions, you need to call
        # traverser.traverse() on a part of the scene. Fortunately, ShowBase
        # has a task that does this for the entire scene once a frame.  By
        # assigning it to self.cTrav, we designate that this is the one that
        # it should call traverse() on each frame.
        self.cTrav = CollisionTraverser()

        # Collision traversers 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)
        for ballSphere in self.ballSpheres:
            self.cTrav.addCollider(ballSphere, self.cHandler)
            continue
        for ballGroundRay in self.ballGroundRays:
            self.cTrav.addCollider(ballGroundRay, self.cHandler)
            continue
        #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((.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))

        for ballRoot in self.ballRoots:
            ballRoot.setLight(render.attachNewNode(ambientLight))
            ballRoot.setLight(render.attachNewNode(directionalLight))
            continue

        # This section deals with adding a specular highlight to the ball to make
        # it look shiny.  Normally, this is specified in the .egg file.
        m = Material()
        m.setSpecular((1, 1, 1, 1))
        m.setShininess(96)
        for ball in self.balls:
            ball.setMaterial(m, 1)
            continue

        # self.original = False
        # if self.original:
        #     camera.setPosHpr(0, 0, 25, 0, -90, 0)
        #     self.maze = loader.loadModel("models/maze")
        #     self.maze.reparentTo(render)
        #     self.walls = self.maze.find("**/wall_collide")
        #     self.walls.node().setIntoCollideMask(BitMask32.bit(0))
        #     self.walls.show()
        #     pass

        # create collision entities from plane predictions
        self.triNPs = []
        for triangleIndex, triangle in enumerate(planeTriangles):
            #print(triangleIndex)
            #for triangle in triangles:
            #print(triangle)
            tri = CollisionPolygon(
                Point3(triangle[0][0], triangle[0][1], triangle[0][2]),
                Point3(triangle[1][0], triangle[1][1], triangle[1][2]),
                Point3(triangle[2][0], triangle[2][1], triangle[2][2]))
            triNP = render.attachNewNode(
                CollisionNode('tri_' + str(triangleIndex)))
            triNP.node().setIntoCollideMask(BitMask32.bit(0))
            triNP.node().addSolid(tri)
            self.triNPs.append(triNP)
            #triNP.show()
            continue

        # create special collision entities for horizontal planes so that balls can fall on one horizontal plane and bounce on it
        for triangleIndex, triangle in enumerate(horizontalPlaneTriangles):
            #print(triangleIndex)
            #for triangle in triangles:
            #print(triangle)
            tri = CollisionPolygon(
                Point3(triangle[0][0], triangle[0][1], triangle[0][2]),
                Point3(triangle[1][0], triangle[1][1], triangle[1][2]),
                Point3(triangle[2][0], triangle[2][1], triangle[2][2]))
            triNP = render.attachNewNode(
                CollisionNode('ground_' + str(triangleIndex)))
            triNP.node().setIntoCollideMask(BitMask32.bit(2))
            triNP.node().addSolid(tri)
            self.triNPs.append(triNP)
            #triNP.show()
            continue

        # tri = CollisionPolygon(Point3(-1, 4, -1), Point3(2, 4, -1), Point3(2, 4, 2))
        # triNP = render.attachNewNode(CollisionNode('tri'))
        # triNP.node().setIntoCollideMask(BitMask32.bit(0))
        # triNP.node().addSolid(tri)
        # triNP.show()

        #self.planeScene.node().setIntoCollideMask(BitMask32.bit(0))
        # roomRootNP = self.planeScene
        # roomRootNP.flattenLight()
        # mesh = BulletTriangleMesh()
        # polygons = roomRootNP.findAllMatches("**/+GeomNode")

        # # p0 = Point3(-10, 4, -10)
        # # p1 = Point3(-10, 4, 10)
        # # p2 = Point3(10, 4, 10)
        # # p3 = Point3(10, 4, -10)
        # # mesh.addTriangle(p0, p1, p2)
        # # mesh.addTriangle(p1, p2, p3)

        # print(polygons)
        # for polygon in polygons:
        #     geom_node = polygon.node()
        #     #geom_node.reparentTo(self.render)
        #     #print(geom_node.getNumGeoms())
        #     ts = geom_node.getTransform()
        #     #print(ts)
        #     for geom in geom_node.getGeoms():
        #         mesh.addGeom(geom, ts)
        #         continue
        #     continue
        # #self.scene = roomRootNP
        # shape = BulletTriangleMeshShape(mesh, dynamic=False)
        # #shape = BulletPlaneShape(Vec3(0, 0, 1), 1)
        # room = BulletRigidBodyNode('scene')
        # room.addShape(shape)
        # #room.setLinearDamping(0.0)
        # #room.setFriction(0.0)
        # print(shape)
        # room.setDeactivationEnabled(False)
        # roomNP = render.attachNewNode(room)
        # roomNP.setPos(0, 0, 0)
        # roomNP.node().setIntoCollideMask(BitMask32.bit(0))
        # self.world = BulletWorld()
        # self.world.setGravity(Vec3(0, 0, 0))
        # self.world.attachRigidBody(roomNP.node())
        #room.setRestitution(1)

        #self.roomNP = self.scene

        # create the cue
        self.cueRoot = render.attachNewNode("cueRoot")
        self.cue = loader.loadModel("models/cue_center.egg")
        self.cue.setScale(self.cueLength * 3, self.cueLength * 3,
                          self.cueLength)
        self.cue.reparentTo(self.cueRoot)

        self.cuePos = (10, 0, 0)

        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 separate it
        self.pickerNode.setFromCollideMask(BitMask32.bit(2))
        self.pickerNode.setIntoCollideMask(BitMask32.allOff())
        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.cTrav.addCollider(self.pickerNP, self.cHandler)

        self.accept("mouse1", self.hit)  # left-click grabs a piece

        # create holes
        self.holeLength = 0.06
        holePos, holeHpr = self.planeInfo.getHolePos()
        self.holeRoot = render.attachNewNode("holeRoot")
        #self.hole = loader.loadModel("models/hole_horizontal_center.egg")
        self.hole = loader.loadModel("models/hole_color.egg")
        #self.hole = loader.loadModel("models/billiards_hole_center.egg")
        self.hole.setScale(self.holeLength, self.holeLength, self.holeLength)
        self.hole.reparentTo(self.holeRoot)
        self.hole.setTwoSided(True)
        self.holeRoot.setPos(holePos[0], holePos[1], holePos[2])
        self.holeRoot.setHpr(holeHpr[0], holeHpr[1], holeHpr[2])
        #tex = loader.loadTexture('models/Black_Hole.jpg')
        #self.hole.setTexture(tex, 1)
        self.holeRoot.hide()

        ct = CollisionTube(0, 0, 0, 0, 0.001, 0, 0.5)
        self.holeTube = self.hole.attachNewNode(CollisionNode('hole'))
        self.holeTube.node().addSolid(ct)
        self.holeTube.node().setFromCollideMask(BitMask32.allOff())
        self.holeTube.node().setIntoCollideMask(BitMask32.bit(4))
        #self.holeTube.show()

        # create portals
        inPortalPos, inPortalHpr, outPortalPos, outPortalHpr, self.portalNormal = self.planeInfo.getPortalPos(
        )
        self.portalLength = 0.06
        self.inPortalRoot = render.attachNewNode("inPortalRoot")
        self.inPortal = loader.loadModel("models/portal_2_center.egg")
        self.inPortal.setScale(self.portalLength, self.portalLength,
                               self.portalLength)
        self.inPortal.reparentTo(self.inPortalRoot)
        self.inPortalRoot.setPos(inPortalPos[0], inPortalPos[1],
                                 inPortalPos[2])
        self.inPortalRoot.setHpr(inPortalHpr[0], inPortalHpr[1],
                                 inPortalHpr[2])
        self.inPortalRoot.hide()

        ct = CollisionTube(0, 0, 0, 0, 0.001, 0, 1)
        self.inPortalTube = self.inPortal.attachNewNode(
            CollisionNode('portal_in'))
        self.inPortalTube.node().addSolid(ct)
        self.inPortalTube.node().setFromCollideMask(BitMask32.allOff())
        self.inPortalTube.node().setIntoCollideMask(BitMask32.bit(3))
        #self.inPortalTube.hide()

        self.outPortalRoot = render.attachNewNode("outPortalRoot")
        self.outPortal = loader.loadModel("models/portal_2_center.egg")
        self.outPortal.setScale(self.portalLength, self.portalLength,
                                self.portalLength)
        self.outPortal.reparentTo(self.outPortalRoot)
        self.outPortalRoot.setPos(outPortalPos[0], outPortalPos[1],
                                  outPortalPos[2])
        self.outPortalRoot.setHpr(outPortalHpr[0], outPortalHpr[1],
                                  outPortalHpr[2])
        self.outPortalRoot.hide()

        ct = CollisionTube(0, 0, 0, 0, 0.001, 0, 1)
        self.outPortalTube = self.outPortal.attachNewNode(
            CollisionNode('portal_out'))
        self.outPortalTube.node().addSolid(ct)
        self.outPortalTube.node().setFromCollideMask(BitMask32.allOff())
        self.outPortalTube.node().setIntoCollideMask(BitMask32.bit(3))
        #self.outPortalTube.hide()
        #self.inPortalTube.show()
        #self.outPortalTube.show()
        #self.holeTube.show()

        #self.cTrav.addCollider(self.holeTube, self.cHandler)

        # create background image
        background_image = loader.loadTexture('dump/' + str(self.sceneIndex) +
                                              '_image.png')
        cm = CardMaker('background')
        cm.setHas3dUvs(True)
        info = np.load('dump/' + str(self.sceneIndex) + '_info.npy')
        #self.camera = getCameraFromInfo(self.info)
        depth = 10.0
        sizeU = info[2] / info[0] * depth
        sizeV = info[6] / info[5] * depth
        cm.setFrame(Point3(-sizeU, depth, -sizeV),
                    Point3(sizeU, depth, -sizeV), Point3(sizeU, depth, sizeV),
                    Point3(-sizeU, depth, sizeV))
        self.card = self.render.attachNewNode(cm.generate())
        self.card.setTransparency(True)
        self.card.setTexture(background_image)
        self.card.hide()

        self.ballGroundMap = {}
        self.ballBouncing = np.full(len(self.balls), 3)

        self.started = False
        self.start()

        #self.hitIndex = -1

        self.showing = 'parts'
        self.showingProgress = 0

        partsScene = PartsScene(self.sceneIndex)
        self.planeNPs, self.planeCenters = partsScene.generateEggModel()
        return
Exemplo n.º 32
0
class RoamingRalphDemo(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
        """)

        if alt:
            ShowBase.__init__(self)
            self.render_pipeline = render_pipeline
            self.render_pipeline.create(self)
        else:
            # ------ Begin of render pipeline code (else case) ------

            # 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 = "../tobsprRenderPipeline"

            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, "roaming_ralph_pipeline_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(
            "roaming_ralph_pipeline_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(
            "roaming_ralph_pipeline_resources/ralph", {
                "run": "roaming_ralph_pipeline_resources/ralph-run",
                "walk": "roaming_ralph_pipeline_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
Exemplo n.º 33
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # Set the background color to black
        self.win.setClearColor((0, 0, 0, 1))

        # 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 trackpad]: Rotate Left")
        self.inst3 = addInstructions(0.18, "[Right trackpad]: Rotate Right")
        self.inst4 = addInstructions(0.24, "[Up trackpad]: Walk Forward")
        self.inst4 = addInstructions(0.30, "[Down trackpad]: Walk Backward")

        # 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)

        # Create the main character, Ralph

        self.vr = RoamingRalphVR()
        self.vr.init(msaa=4)

        self.ralph = render.attachNewNode('ralph')
        self.ralphStartPos = self.environ.find("**/start_point").getPos()
        self.vr.tracking_space.setPos(self.ralphStartPos)
        self.ralph.setPos(self.vr.hmd_anchor.getPos(render))

        self.accept("escape", sys.exit)

        taskMgr.add(self.collision, "collisionTask")

        # Set up the camera
        self.disableMouse()

        # 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, 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)

        # Uncomment this line to see the collision rays
        #self.ralphGroundColNp.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))

    # Grid checking and collision detection
    def collision(self, task):

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #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 = list(self.ralphGroundHandler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        if len(entries) > 0 and entries[0].getIntoNode().getName(
        ) == "terrain":
            self.vr.tracking_space.setZ(
                entries[0].getSurfacePoint(render).getZ())
        else:
            self.vr.tracking_space.setPos(self.ralphStartPos)
        self.ralph.setPos(self.vr.hmd_anchor.getPos(render))

        # save ralph's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        self.ralphStartPos = self.vr.tracking_space.getPos()

        return task.cont
Exemplo n.º 34
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # 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, "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.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.36, "[S]: Rotate Camera Right")
        self.dirText = addInstructions(0.42, "pos")
        self.anglesText = addInstructions(0.48, "angle")

        # 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)

        self.createArm()

        # 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, 0.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", self.exitButton)
        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("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("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(15, 0, 3)#self.ralph.getX(), self.ralph.getY() + 10, 2)
        self.camera.setHpr(90, -5, 0)

        # 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, 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.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((.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))

    def exitButton(self):
      servos.exit()
      __import__('sys').exit()

    def createArm(self):
        self.robotarm = Actor("models/robotarm")
        self.robotarm.reparentTo(render)
        self.robotarm.setPos(0,0,0)
        self.robotarm.setScale(.2)
        self.jointForearm = self.robotarm.controlJoint(None, "modelRoot", "forearm")
        self.jointBase = self.robotarm.controlJoint(None, "modelRoot", "base")
        taskMgr.add(self.monitorArm, "robot arm")

        inc = 15
        self.accept("i", self.setForearm, [inc])
        self.accept("u", self.setForearm, [-inc])
        self.accept("j", self.setBase, [inc])
        self.accept("k", self.setBase, [-inc])

    def monitorArm(self, task):
        def clamp1(x): return min(1, max(-1, x))

        direction = self.ralph.get_pos() - self.robotarm.get_pos()
        direction.z += 1
        direction.normalize()

        # camera starts facing along x
        dec = math.asin(direction.x)
        cosdec = math.cos(dec) 
        if cosdec > 1e-05:
          ra = math.asin(clamp1(direction.z / cosdec))
          ra2 = math.acos(clamp1(direction.y / cosdec))
        else: ra = ra2 = math.pi/2#float('nan')
        #print(cosdec, direction)
        #print(dec, ra, ra2, cosdec)

        if direction.z < 0: 
          if ra2 < math.pi/2: ra2 = 0
          else: ra2 = math.pi

        self.jointForearm.setH(-dec * 180/math.pi)
        self.jointBase.setP(ra2 * 180/math.pi) 

        self.dirText.setText(str(direction)) 
        self.anglesText.setText(str((dec, ra, ra2, cosdec)))

        a = self.jointForearm.getH() / 90.0 * 300 + 512
        b = self.jointBase.getP()    / 90.0 * 300 + 212
        #print(a, b)
        baseID = 9
        servos.setAngle({baseID:int(round(b)), (baseID+1):int(round(a))})
        return task.again

    def monitorArmServos(self, task):
        baseID = 9
        a = self.jointForearm.getH() / 90.0 * 300 + 512
        b = self.jointBase.getP()    / 90.0 * 300 + 212
        #print(a, b)
        servos.setAngle({baseID:int(round(a)), (baseID+1):int(round(b))})

#	frac = task.time - int(task.time) 
#        if frac > .9 and frac < .99:
        #print(self.jointForearm.getH(), self.jointBase.getP())
        return task.again

    def setForearm(self, inc):
        #self.jointForearm.setH(random.random()*180-90)
        self.jointForearm.setH(self.jointForearm.getH() + inc)
    def setBase(self, inc):
        #self.jointBase.setP(random.random()*180)
        self.jointBase.setP(self.jointBase.getP() + inc)


    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

        # 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"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -25 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap["right"]:
            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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #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 = list(self.ralphGroundHandler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        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 = 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.ralph.getZ() + 2.0:
            self.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.camera.lookAt(self.floater)"""

        return task.cont
Exemplo n.º 35
0
class World(DirectObject):

    def __init__(self):
        self.itemID = 0
        self.switchState = True
        self.iAktion = "E"
        self.altIPos = [0,0]
        self.switchCam = False
        self.kampf = Battle.Kampf()
        self.itemDa = False
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        self.environ = loader.loadModel("models/world")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)

 
        self.spieler = Players.Player(Actor("models/box.x"))
        self.spieler.actor.reparentTo(render)
        spielerStartPos = (-107.575, 26.6066, -0.490075)
        self.spieler.actor.setPos(spielerStartPos)
        self.textObjectSpieler = OnscreenText(text = self.spieler.name+":  "+str(self.spieler.energie)+"/"+str(self.spieler.maxenergie)+" HP", pos = (-0.90, -0.98), scale = 0.07, fg = (1,0,0,1))        

        # Erstellt Gegner
        
        self.gegnerStartPos = ([(-39.1143569946,25.1781406403,-0.136657714844),
                                (-102.375793457,-30.6321983337,0.0),
                                (-56.927986145, -34.6329650879, -0.16748046875),
                                (-79.6673126221,30.8231620789,2.89721679688),
                                (-4.37648868561,30.5158863068,2.18450927734),
                                (22.6527004242,4.99837779999,3.11364746094),
                                (-23.8257598877,-7.87773084641,1.36920166016),
                                (-80.6140823364,19.5769443512,4.70764160156),
                                (-75.0773696899,-15.2991075516,6.24676513672)
                                ])
        
        gegnerPos = random.choice(self.gegnerStartPos)
        self.gegnerErstellen(gegnerPos)
        self.textObjectGegner = OnscreenText(text = str(self.gegner.name)+": "+str(self.gegner.energie)+"/"+str(self.gegner.maxenergie)+" HP", pos = (0.90, -0.98), scale = 0.07, fg = (1,0,0,1))
        
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        self.item = None
        
        # Handling der Usereingaben für Bewegung

        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("i", self.setKey, ["inventar",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        self.accept("e", self.iAktionsHandler,["e"])
        self.accept("v", self.iAktionsHandler,["v"])
        self.accept("w", self.iAktionsHandler,["w"])
        
        taskMgr.add(self.move,"moveTask")
        taskMgr.add(self.erkenneKampf,"Kampferkennung")
        taskMgr.add(self.screentexts,"Screentexte")


        # Menü erstellen

        self.createMenu()
        
        # Kameraeinstellungen
        
        base.disableMouse()
        base.camera.setPos(self.spieler.actor.getX(),self.spieler.actor.getY()+10,2)
        
        self.collisionInit();
        
        self.setAI()
        
        # Licht
        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))

        # Hintergrund (Himmel)

        self.setupSkySphere()

    def iAktionsHandler(self,key):
        if key == "e":
            self.iAktion = "E"
        elif key == "w":
            self.iAktion = "W"
        elif key == "v":
            self.iAktion = "V"
            

    def collisionInit(self):
        # Kollisionserkennung, um auf dem Boden zu laufen. Der Collisionray
        # erkennt die Hoehe des Gelaendes und wenn ein Objekt da ist, wird 
        # die Bewegung als illegal gewertet.

        self.cTrav = CollisionTraverser()

        self.spielerGroundRay = CollisionRay()
        self.spielerGroundRay.setOrigin(0,0,1000)
        self.spielerGroundRay.setDirection(0,0,-1)
        self.spielerGroundCol = CollisionNode('spielerRay')
        self.spielerGroundCol.addSolid(self.spielerGroundRay)
        self.spielerGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.spielerGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.spielerGroundColNp = self.spieler.actor.attachNewNode(self.spielerGroundCol)
        self.spielerGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.spielerGroundColNp, self.spielerGroundHandler)

        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)

        self.gegnerGroundRay = CollisionRay()
        self.gegnerGroundRay.setOrigin(0,0,1000)
        self.gegnerGroundRay.setDirection(0,0,-1)
        self.gegnerGroundCol = CollisionNode('gegnerRay')
        self.gegnerGroundCol.addSolid(self.gegnerGroundRay)
        self.gegnerGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.gegnerGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.gegnerGroundColNp = self.gegner.actor.attachNewNode(self.gegnerGroundCol)
        self.gegnerGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.gegnerGroundColNp, self.gegnerGroundHandler)


    def setupSkySphere(self):
        self.skysphere = loader.loadModel("models/LinearPinkSkySphere.bam")
        # Textur für den Himmel laden
        self.sky_tex = loader.loadTexture("Images/Sterne.jpg")
        # Himmel Textur konfigurieren
        self.skysphere.setTexture(self.sky_tex, 1)
	self.skysphere.setBin('background', 1) 
        self.skysphere.setDepthWrite(0) 
        self.skysphere.reparentTo(render)
        self.skysphere.setScale(40)
        taskMgr.add(self.skysphereTask, "SkySphere Task") 

    def skysphereTask(self, task): 
        self.skysphere.setPos(base.camera, 0, 0, 0) 
        return task.cont

    def createMenu(self):
        self.createFrame()
        itemListe = self.spieler.inventar.anzeigen(1)
        standardpos = [0.18, 0.98, 0.83]
        self.buttonListe = []
        beutelLabel = DirectLabel(text = itemListe[0][0], pos = (0.18, 0.98, 0.95), scale = 0.07, text_fg = (1,0,0,1), text_bg = (0, 50, 50, 1), textMayChange = 1)
        del itemListe [0][0]
        for zeile in range(4):
            for i in range(0,5):
                Button = DirectButton(text = itemListe [zeile] [i], pos = standardpos, scale = 0.07, text_fg = (1,0,0,1), text_bg = (0, 50, 50, 1), textMayChange = 1, extraArgs = [zeile,i], command = self.inventarAktion)
                self.buttonListe.append (Button)
                standardpos[0] += 0.25
            standardpos[0] = 0.18    
            standardpos[2] -= 0.15
            
    def createFrame(self):
        self.myFrame = DirectFrame(frameColor=(0, 50, 50, 0.5),
                      frameSize=(-1, 1, -.7, 1),
                      pos=(1, -1, 1))

    def inventarAktion(self,zeile,spalte):
        if self.iAktion == "E":
            self.spieler.inventar.entfernen(1,[zeile,spalte])
            self.myFrame.destroy()
            i = 0
            for item in self.buttonListe:
                    self.buttonListe [i].destroy()
                    i += 1
            del self.buttonListe[:]
            self.createMenu()  
        elif self.iAktion == "W":
            self.altIPos = [zeile,spalte]
        elif self.iAktion == "V":
            self.spieler.inventar.verschieben(1,1,self.altIPos,[zeile,spalte])
            self.myFrame.destroy()
            i = 0
            for item in self.buttonListe:
                    self.buttonListe [i].destroy()
                    i += 1
            del self.buttonListe[:]
            self.createMenu()        
        
        
    # Erkennt den Status der Eingabe
    def setKey(self, key, value):
        self.keyMap[key] = value

    def screentexts(self,task):
        self.textObjectSpieler.destroy()
        self.textObjectSpieler = OnscreenText(text = self.spieler.name+":  "+str(self.spieler.energie)+"/"+str(self.spieler.maxenergie)+" HP", pos = (-0.90, -0.98), scale = 0.07, fg = (1,0,0,1))
        self.textObjectGegner.destroy()
        if self.kampf.active == True:
            self.textObjectGegner = OnscreenText(text = str(self.gegner.name)+": "+str(self.gegner.energie)+"/"+str(self.gegner.maxenergie)+" HP", pos = (0.90, -0.98), scale = 0.07, fg = (1,0,0,1))
        else:
            self.textObjectGegner = OnscreenText(text = "Kein Gegner vorhanden", pos = (0.90, -0.98), scale = 0.07, fg = (1,0,0,1))
        return Task.cont

    def camera(self):
         # cam-left Key: Kamera nach links
        # cam-right Key: Kamera nach rechts
        base.camera.lookAt(self.spieler.actor)
        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())

        # Wenn die Kamera zu weit weg ist, zoom heran.
        # Wenn die Kamera zu nah dran ist, zoom weg.

        camvec = self.spieler.actor.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

        # Haelt die Kamera einen Schritt über dem Boden
        # oder zwei Schritte ueber dem Spieler, je nachdem, was groesser ist.
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.spieler.actor.getZ() + 2.0):
            base.camera.setZ(self.spieler.actor.getZ() + 2.0)
            
        # Die Kamera soll in die Richtung des Spielers gucken, aber auch
        # immer horizontal bleiben.
        
        self.floater.setPos(self.spieler.actor.getPos())
        self.floater.setZ(self.spieler.actor.getZ() + 2.0)
        base.camera.lookAt(self.floater)

    def collisions(self,startpos):
        
        # Überprüfen auf Itemkollision
        
        if self.item <> None:
            if (self.item.actor.getX() - self.spieler.actor.getX() < 1
            and self.item.actor.getY() - self.spieler.actor.getY() < 1
            and self.item.actor.getZ() - self.spieler.actor.getZ() <1
            and self.itemDa == True):
                self.itemDa = False
                self.item.actor.detachNode()
                self.spieler.inventar.einfuegen(self.item)
                self.myFrame.destroy()
                del self.buttonListe[:]
                self.createMenu()

         # Start der Kollisionserkennung

        self.cTrav.traverse(render)


        # Aendert die Z Koordinate des Spielers. Wenn er etwas trifft, bewegt
        # ihn entsprechend, wenn er nichts trifft, setzt die Koordinate 
        # auf den Stand des letzten Frames
        self.dummyMethode(self.spielerGroundHandler, self.spieler.actor,startpos)

    
    def move(self,task):

        self.camera();
        
        # Speichert die Startposition, damit der Spieler zurueckgesetzt
        # werden kann, sollte er irgendwo runterfallen

        startpos = self.spieler.actor.getPos()

        # Wenn einer der Move Keys gedrueckt wird, wird der Spieler
        # in die ensprechende Richtung bewegt

        if (self.keyMap["left"]!=0):
            self.spieler.actor.setH(self.spieler.actor.getH() + 150 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.spieler.actor.setH(self.spieler.actor.getH() - 150 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.spieler.actor.setY(self.spieler.actor, -12 * globalClock.getDt())

        self.collisions(startpos);

        return Task.cont

    def gegnermove(self):
 
        # Zeit seit dem letzten Frame. Benötigt fuer
        # framerateunabhaengige Bewegung.
        elapsed = globalClock.getDt()

        startpos = self.gegner.actor.getPos()
 
        # Aendert die Z Koordinate des Gegners. Wenn er etwas trifft, bewegt
        # ihn entsprechend, wenn er nichts trifft, setzt die Koordinate 
        # auf den Stand des letzten Frames
 
        self.cTrav.traverse(render)
        self.dummyMethode(self.gegnerGroundHandler, self.gegner.actor,startpos)
 
        self.gegner.actor.setP(0)
        if self.gegner.energie == 0:
            return Task.done
        else:
            return Task.cont

    def dummyMethode(self, handler, actor,startpos):
        entries = []
        for i in range(handler.getNumEntries()):
            entry = handler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            actor.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            actor.setPos(startpos)
	
	
	
    def setAI(self):
        # Erstellt die AI World
        self.AIworld = AIWorld(render)
 
        self.AIchar = AICharacter("gegner",self.gegner.actor, 100, 0.02, 1)
        self.AIworld.addAiChar(self.AIchar)
        self.AIbehaviors = self.AIchar.getAiBehaviors()
 
        self.AIbehaviors.wander(360, 0, 15, 1.0)
 
        #AI World update zum Tasknamager hinzufügen       
        taskMgr.add(self.AIUpdate,"AIUpdate")
 
 
    # Update der AI World   
    def AIUpdate(self,task):
        if self.kampf.active == False:
            self.AIworld.update()
            self.gegnermove()
 
        return Task.cont

    # Startet bei einem Abstand von 4 zwischen Spieler und Gegner einen Kampf
    def erkenneKampf(self,task):
        if (self.spieler.actor.getX() - self.gegner.actor.getX() < 4
        and self.spieler.actor.getX() - self.gegner.actor.getX() > -4
        and self.kampf.active == False):
            self.kampf.active = True
            self.startzeit = globalClock.getLongTime()
        if self.kampf.active == True:
            self.Kampf(self)
        if self.gegner.energie == 0:
            return Task.done
        else:
            return Task.cont

    def gegnerErstellen(self,pos):
        self.gegner = Monster.Goblin(Actor("models/box.x"))
        self.gegner.actor.reparentTo(render)
        self.gegner.actor.setPos(pos)
        self.gegnerAltPos = pos
        self.setAI()

    def gegnerTod(self):
        self.kampf.active = False
        itemPos = self.gegner.actor.getPos()
        self.gegner.actor.detachNode()
        self.item = Items.Axt()
        self.item.ID = self.itemID
        self.itemID += 1
        self.itemDa = True
        self.item.actor.setScale(0.3)
        self.item.actor.reparentTo(render)
        self.item.actor.setPos(itemPos)
        gegnerNeuPos = random.choice(self.gegnerStartPos)
        while gegnerNeuPos == self.gegnerAltPos:
            gegnerNeuPos = random.choice(self.gegnerStartPos)
        self.gegnerErstellen(gegnerNeuPos)

    # Lässt Spieler und Gegner nach bestimmter Zeit Aktionen ausführen. Bei Tod des
    # Gegners wird ein neuer Gegner sowie ein Item generiert
    def Kampf(self,task):
        if ((int(globalClock.getLongTime()) - int(self.startzeit)) % 5 == 0
        and self.kampf.active == True):
            erg = self.kampf.Kampf(self.spieler,self.gegner)
            self.spieler = erg[0]
            self.gegner = erg[1]
            self.startzeit -= 1
            if self.spieler.energie == 0:
                sys.exit
            elif self.gegner.energie == 0:
                self.gegnerTod();
        if self.startzeit <= 0:
            self.startzeit = globalClock.getLongTime()
Exemplo n.º 36
0
    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
Exemplo n.º 37
0
class Labryn(ShowBase):
    def setCamera(self, spin):
        # set camera spin state
        self.spin = spin

    def displayInformation(self):
        self.title = addTitle("Single Player")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[wasd]: Move")
        self.inst3 = addInstructions(0.85, "[q/e]: spin camera")
        self.inst4 = addInstructions(0.80, "[z/c]: zoom in/out")
        self.inst5 = addInstructions(0.75, "[shift]: hold and pan")
        self.inst6 = addInstructions(0.70, "[1/2/3]: use moves")
        self.inst7 = addInstructions(0.65, "[h]: hide instructions")
        self.insts = [self.title, self.inst1, self.inst2, self.inst3,
                      self.inst4, self.inst5, self.inst6, self.inst7]

    def hideInstructions(self):
        if self.instStatus == "show":
            self.instStatus = "hide"
            groupHide(self.insts)
        else: # instructions are hidden
            self.instStatus = "show"
            groupShow(self.insts)        
        
    def loadNextMusic(self, task):
        # random load background music
        if (self.music.status()!=self.music.PLAYING):
            # not playing
            self.musicCounter += 1
            index = self.musicCounter % len(_BGMUSIC)
            self.music = load_bgmusic(_BGMUSIC[index])
            self.music.play()
        return task.cont
        
    def spinCamera(self, task):
        # deal with spinning the camera
        # _FOCUS: focus point, changed by panning the camera
        # CAM_R: radius, changed by zooming
        # cameraSpinCount: amount of spinning, changed by spinning
        if self.spin == 1: # spin counter-clockwise
            self.cameraSpinCount += 1
            angleDegrees = self.cameraSpinCount
            angleRadians =  angleDegrees * (pi/ 180)
            self.CAM_RAD = angleRadians
            camera.setPos(_FOCUS[0]+self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1]+self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R) 
            camera.setHpr(angleDegrees,-65,0)
        elif self.spin == 2: # spin clockwise
            self.cameraSpinCount  -= 1
            angleDegrees = self.cameraSpinCount
            angleRadians =  angleDegrees * (pi/ 180)
            self.CAM_RAD = angleRadians
            camera.setPos(_FOCUS[0]+self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1]+self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R)
            camera.setHpr(angleDegrees,-65,0)
        elif self.spin == 3: # ZOOM IN not spin
            self.cameraZoomCount += 1
            deltaR = self.cameraZoomCount * 0.1
            new_R = 12-deltaR
            self.CAM_R = new_R
            camera.setPos(_FOCUS[0] + self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1] + self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*new_R)
        elif self.spin == 4: # ZOOM OUT
            self.cameraZoomCount -= 1
            deltaR = self.cameraZoomCount * 0.1
            new_R = 12-deltaR
            self.CAM_R = new_R
            camera.setPos(_FOCUS[0] + self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1] + self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R)
        return Task.cont

    def takeRecord(self):
        def myCMP(aString, bString):
            a = float(aString.split(',')[0])
            b = float(bString.split(',')[0])
            return int(10*(a - b))
        
        msg = "%.2f,%s\n" %(self.clock/100.0, time.ctime())
        with open('record.txt') as f:
            data = f.readlines()
        # if has no previous data
        if len(data) == 0:
            data.append(msg)
            with open('record.txt','w') as f:
                f.writelines(data)
        else:
            data.append(msg)
            processedData = sorted(data, myCMP)
            with open('record.txt', 'w') as f:
                f.writelines(processedData)

    def printResults(self):
        addEndMessage(self.clock)
        with open('record.txt') as f:
            data = f.readlines()
        for i in xrange(0, len(data)):
            if i < 5: # only print the top 5
                string = data[i]
                printRank(i, string)
        
    def checkForWin(self, task):
        if (checkWin(self.pikachu.getX(), self.pikachu.getY(),
                    self.ballRoot.getX(), self.ballRoot.getY()) and
            self.gameOver == False):
            self.takeRecord()
            self.printResults()
            self.gameOver = True
            # if top 10, if top 1,
            print "WIN"
            # print previous best 10 results
        return Task.cont
    
    def pikachuBark(self, task):
        if self.distance < 3:
            if random.randint(1,200) == 1:
            # randomly bark dangerous sound
                if self.dangerous.status() != self.dangerous.PLAYING:
                    self.dangerous.play()
        elif self.distance > 10:
            if random.randint(1,430) == 1:
                if self.safe.status() != self.safe.PLAYING:
                    self.safe.play()
        return Task.cont
            
    def checkMouse(self, task):
        # get mouse position 
        if base.mouseWatcherNode.hasMouse():
            self.mouseX=base.mouseWatcherNode.getMouseX()
            self.mouseY=base.mouseWatcherNode.getMouseY()
        return Task.cont

    def dropRock(self):
        # when the user clicks, rock is dropped
        if self.pokeMoveChoice == 1: # selected Geodude
            result = MAZE.canDropRock(self.rockX, self.rockY)
            if result != False: # can place rock here
                MAZE.dropRock(result[0],result[1])
                self.rock.setPos(self.rockX, self.rockY, 1)
                self.rockOnMaze = True
                self.pokeMoveChoice = None
                self.myPokeName.hide()
                self.myPokeName = None
                self.updateTwoD()
                self.playerCandyCount -= 1

    def restart(self):
        sys.exit()
                
    def useFlame(self):
        # use flame to Pikachu -> cannot move
        self.onFire = True # on fire
        self.playerCandyCount -= 1
        self.pokeStatus = 1
        self.flame = ParticleEffect()
        self.flame.loadConfig("fireish.ptf")
        self.flame.setPos(self.pikachu.getPos())
        self.flame.start(parent=render, renderParent=render)
        self.updateTwoD()

    def useStringShot(self):
        # use string shot -> speed goes down
        self.pokeStatus = 2
        self.updateTwoD()

    def useThunder(self):
        self.onThunder = True
        self.pokeCandyCount -= 1
        self.thunder = ParticleEffect()
        self.thunder.loadConfig("thunder.ptf")
        self.thunder.start(parent=render, renderParent=render)
        self.use.play()
                
    def placeRock(self, task):
        # rock moves with mouse cursor
        if self.pokeMoveChoice == 1: # selected Geodude
            dX,dY = ((self.mouseX-self.rockRefX),
                     (self.mouseY-self.rockRefY))
            self.rockX, self.rockY = MAZE.translateRockPosition(self.rockRefX,
                                                      self.rockRefY,
                                                      dX, dY)
            self.rock.show()
            self.rock.setPos(self.rockX, self.rockY, 1)
        self.updateTwoD()
        return Task.cont
    
    def placeRareCandy(self, task):
        # place rare candy with interval
        # needs to be improved
        if int(task.time) % 4 == 9 and self.candyOnBoard:
            self.candy.hide()
            self.candyOnBoard = False
            MAZE.clearCandy()
        if int(task.time) % 10 ==  0 and (self.candyOnBoard == False):
            # every 10 seconds
            self.candy.setPos(MAZE.generateCandyPos())
            self.candy.show()
            self.candyOnBoard = True
        return Task.cont

    def updateTwoD(self):
        # update player candy count
        self.playerCandyStatus.destroy()
        self.playerCandyStatus = candyStatus(0, self.playerCandyCount)
        self.pokeCandyStatus.destroy()
        self.pokeCandyStatus = candyStatus(1, self.pokeCandyCount)
        # update my pokes color     
        if self.playerCandyCount == 0 :
            groupHide(self.myPokesBright)
            groupShow(self.myPokesDark)
            # update name
            if self.myPokeName != None:
                self.myPokeName.destroy()

    def clearRock(self):
        # clear rock 
        self.rock.hide()
        self.rockOnMaze = False
        MAZE.clearRock() # clear it in 2D

    def clearFlame(self):
        # clear flame
        self.onFire = False
        self.flame.cleanup()
        self.pokeStatus = 0
        self.pokeMoveChoice = None
        try:
            self.myPokeName.destroy()
        except:
            pass
        self.myPokeName = None

    def clearString(self):
        # clear string shot
        self.pokeStatus = 0
        self.pokeMoveChoice = None
        try:
            self.myPokeName.destroy()
        except:
            pass
        self.myPokeName = None

    def clearThunder(self):
        self.onThunder = False
        try:
            self.thunder.cleanup()
        except:
            pass
        
    def timer(self, task): # deals with moves' lasting effects
        ##############################################################
        self.clock += 1
        if self.rockOnMaze: # rock on maze
            self.rockCounter += 1
        elif self.rockCounter != 1: # rock not on maze, counter not cleared
            self.rockCounter = 0

        if self.onFire:
            self.fireCounter += 1
        elif self.fireCounter != 1:
            self.fireCounter = 0

        if self.pokeStatus == 2: # string shot
            self.stringCounter += 1
        elif self.stringCounter != 1:
            self.stringCounter = 0

        if self.onThunder: # thunderbolt
            self.thunderCounter += 1
        elif self.thunderCounter != 1:
            self.thunderCounter = 0

        if self.gameOver == True: # game is over
            self.gameOverCounter += 1

        ##################################################################
        if self.rockCounter >= 100:
            self.clearRock()

        if self.fireCounter >= 80:
            self.clearFlame()

        if self.thunderCounter >= 150:
            self.clearThunder()
            
        if self.stringCounter >= 120:
            self.clearString()

        if self.gameOverCounter >= 800: # quit the game
            sys.exit()
            
        return Task.cont
    
    def usePokeMove(self, number):
        # use pokemon move
        if self.playerCandyCount > 0: # have more than one candy
            if number == 1 and self.rockOnMaze == False:
                if self.pokeMoveChoice == None: # no choice
                    # set to center position
                    centerx =  base.win.getProperties().getXSize()/2
                    centery =  base.win.getProperties().getYSize()/2
                    base.win.movePointer(0,centerx,centery)
                    self.pokeMoveChoice = 1 # placeRock called here
                    self.rockRefX, self.rockRefY = 0,0
                    self.rock.show()
                    self.rock.setPos(0,0,1)
                elif self.pokeMoveChoice != 1:
                    pass

                else: # self.pokeMoveChoice is already 1, cancel the choice
                    self.pokeMoveChoice = None
                    self.clearRock() # clear rock
            elif number == 2:
                if self.pokeMoveChoice == None:
                    self.pokeMoveChoice = 2
                    self.useFlame()
                elif self.pokeMoveChoice != 2:
                    pass
                else:
                    self.pokeMoveChoice = None

            elif number == 3:
                if self.pokeMoveChoice == None:
                    self.pokeMoveChoice = 3
                    self.useStringShot()
                elif self.pokeMoveChoice != 3:
                    pass
                else: # already 3
                    self.pokeMoveChoice = None

            if self.pokeMoveChoice == None: # no choice
                if self.myPokeName != None: # there is a name on board
                    self.myPokeName.destroy() # kill it
                else: # no name
                    pass
            else: # there is a choice
                if self.myPokeName != None:
                    self.myPokeName.destroy()
                self.myPokeName = writePokeName(self.pokeMoveChoice)
  
    def loadRareCandy(self):
        # load rare candy (a box)
        # needs to be improved
        self.candy = Model_Load.loadRareCandy()
        self.candy.reparentTo(render)
        self.candy.setScale(0.1)
        self.candy.hide()
        
    def eatRareCandy(self, task):
        # check who eats candy
        if self.candyOnBoard: # candy on board
            if checkEat(self.ballRoot.getX(), self.ballRoot.getY(),
                        self.candy.getX(), self.candy.getY()): # ball eats
                self.candy.hide() # eaten
                self.candyOnBoard = False
                if self.playerCandyCount < 3:
                    self.playerCandyCount += 1
                groupShow(self.myPokesBright)
                MAZE.clearCandy()
            elif checkEatPika(self.pikachu.getX(), self.pikachu.getY(),
                          self.candy.getX(), self.candy.getY()):
                self.candy.hide()
                self.candyOnBoard = False
                if self.pokeCandyCount < 3:
                    self.pokeCandyCount += 1
                MAZE.clearCandy()                
        return Task.cont

    def setFocus(self, changing):
        # set focus of the camera while panning
        self.changingFocus = changing
        if changing == True: # Just Pressed
            self.referenceX, self.referenceY = self.mouseX, self.mouseY
        else: # cursor moves up
            self.referenceX, self.referenceY = None, None

    def resetView(self):
        # reset the view to default
        self.CAM_R, self.CAM_RAD = 12, 0
        self.cameraSpinCount, self.cameraZoomCount = 0, 0
        # _FOCUS = [0,0,0] does not work WHY???
        _FOCUS[0], _FOCUS[1], _FOCUS[2] = 0,0,0
        self.changingFocus = False
        self.referenceX, self.referenceY = None, None
        camera.setPos(_FOCUS[0], _FOCUS[1]-self.CAM_R, 25)
        camera.setHpr(0, -65, 0)
        
    def changeFocus(self, task):
        # change focus with displacement of mouse cursor
        if (self.changingFocus == True and self.mouseX != None and
            self.mouseY != None ):
            dX, dY = ((self.mouseX - self.referenceX)*0.1,
                      (self.mouseY - self.referenceY)*0.1)
            _FOCUS[0] += dX
            _FOCUS[1] += dY
            camera.setPos(_FOCUS[0] + self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1] + self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R)
        return Task.cont

    def thunderbolt(self, task):
        if self.onThunder == True:
            self.thunder.setPos(self.ballRoot.getPos())
        return Task.cont

    def displayClock(self, task):
        msg = "Time: %.2f" %(self.clock/100.0)
        if self.clockMSG == None:
            self.clockMSG = OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                                         pos=(1.3, .95), align=TextNode.ALeft,
                                         scale = .05)
        else:
            self.clockMSG.destroy()
            self.clockMSG = OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                                         pos=(1.3, .95), align=TextNode.ALeft,
                                         scale = .05)
        return task.cont
    
    def initialize(self):
        taskMgr.stop()
        self.musicCounter, self.clock = 0, 0
        self.gameOverCounter = 0
        self.clockMSG = None
        self.music = load_bgmusic(_BGMUSIC[0])
        self.background = loadBackground()
        base.cam2dp.node().getDisplayRegion(0).setSort(-20)
        self.candyOnBoard = False
        self.playerCandyCount, self.pokeCandyCount = 0, 0
        self.gameOver = False
        self.displayInformation()
        self.instStatus = "show"
        ######################Rare Candy###############################
        pokes=['caterpie', 'charmander', 'geodude']
        self.myPokesDark = loadMyPokemon_Dark(pokes) # my pokemons
        self.myPokesBright = loadMyPokemon_Bright()
        groupHide(self.myPokesBright)
        self.loadRareCandy() # load rare candy
        ######################Camera Initialization####################
        self.CAM_R, self.CAM_RAD = 12, 0
        camera.setPos(_FOCUS[0],_FOCUS[1]-12,_FOCUS[2]+25)
        camera.setHpr(0, -65, 0)
        self.cameraSpinCount, self.cameraZoomCount = 0, 0
        self.changingFocus = False
        self.spin = 0
        #######################ICONS###################################
        self.myIcon = loadMyIcon()
        self.pokeIcon = loadPokeIcon()
        self.playerCandyStatus = candyStatus(0, self.playerCandyCount)
        self.pokeCandyStatus = candyStatus(1, self.pokeCandyCount)
        self.rareCandyImage = loadRareCandyImage()
        self.pokeRareCandyImage = loadRareCandyImage(pos=(-.3,0,-.75))
        #######################FLAMES##################################
        base.enableParticles()
        self.fireCounter = 0
        self.onFire = False
        #######################STRINGSHOT#############################
        self.stringCounter = 0
        #######################THUNDER################################
        self.thunderCounter = 0
        #######################SOUND##################################
        self.dangerous = load_sound("pikachu_d.wav")
        self.safe = load_sound("pikachu_s1.wav")
        self.use = load_sound("pikachu_u.wav")
        #######################"GLOBALS"##############################
        self.speedCounter = 0
        self.onThunder = False
        self.direction = 's'
        self.myDirection = ['zx', 'zy']
        self.rockCounter  = 0
        self.rockX, self.rockY = None, None
        self.rockOnMaze = False
        self.pokeMoveChoice = None
        self.myPokeName = None
        self.arrowKeyPressed = False
        self.pokemonDirection = 'd'
        self.mouseX, self.mouseY = None, None
        # direction the ball is going
        self.jerkDirection = None
        base.disableMouse()
        self.jerk = Vec3(0,0,0)
        self.MAZE = Model_Load.loadLabyrinth()
        Control.keyControl(self)
        self.loadPokemonLevel1()
        self.light()
        self.loadBall()
        self.pokeStatus = 0 # 0 is normal, 1 is burned, 2 is slow-speed
        ########################################ROCK###################
        self.rock = Model_Load.loadRock()
        self.rock.reparentTo(render)
        self.rock.hide() # Do not show, but load beforehand for performance
        
    def loadPokemonLevel1(self):
        self.pikachu = load_model("pikachu.egg")
        self.pikachu.reparentTo(render)
        self.pikachu.setScale(0.3)
        endPos = self.MAZE.find("**/end").getPos()
        self.pikachu.setPos(endPos)
        
    def light(self):
        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))

    def loadBall(self):
        self.ballRoot = render.attachNewNode("ballRoot")
        self.ball = load_model("ball")
        self.ball.reparentTo(self.ballRoot)
        self.ball_tex = load_tex("pokeball.png")
        self.ball.setTexture(self.ball_tex,1)
        self.ball.setScale(0.8)
        # Find the collision sphere for the ball in egg.
        self.ballSphere = self.ball.find("**/ball")
        self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
        self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())
        #self.ballSphere.show()
        # Now we create a ray to cast down at the ball.
        self.ballGroundRay = CollisionRay()
        self.ballGroundRay.setOrigin(0,0,10)
        self.ballGroundRay.setDirection(0,0,-1)

        # Collision solids go in CollisionNode
        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)
        
        # light
        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))
        # material to the ball
        m = Material()
        m.setSpecular(Vec4(1,1,1,1))
        m.setShininess(96)
        self.ball.setMaterial(m,1)
        
    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.node().setIntoCollideMask(BitMask32.bit(0))
        
        # 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 pokemonTurn(self, pokemon, direction):
        if direction  == 'l' and self.pokemonDirection != 'l':
            self.pokemonDirection = 'l'
            pokemon.setH(-90)
        if direction  == 'r' and self.pokemonDirection != 'r':
            self.pokemonDirection = 'r'
            pokemon.setH(90)
        if direction  == 'd' and self.pokemonDirection != 'd':
            self.pokemonDirection = 'd'
            pokemon.setH(0)
        if direction  == 'u' and self.pokemonDirection != 'u':
            self.pokemonDirection = 'u'
            pokemon.setH(180)
                        
    def pokemonMove(self, pokemon, direction):
        self.pokemonTurn(pokemon, direction)
        if self.pokeStatus == 0: speed = _SPEED
        elif self.pokeStatus == 1: speed = 0
        else: # self.pokeStatus == 2
            speed = _SPEED/2.0
        if direction == 'l':
            newX = pokemon.getX() - speed
            pokemon.setX(newX)
        elif direction == 'r':
            newX = pokemon.getX() + speed
            pokemon.setX(newX)
        elif direction == 'u':
            newY = pokemon.getY() + speed
            pokemon.setY(newY)
        elif direction == 'd':
            newY = pokemon.getY() - speed
            pokemon.setY(newY)
        elif direction == "s": # stop
            pass
        
    def whereToGo(self, task):
        # this returns the direction pokemon should go
        # tell MAZE pokemon and ball's board position
        self.pokemonMove(self.pikachu, self.direction)
        MAZE.setPokeCoord(self.pikachu.getX(), self.pikachu.getY(),
                          self.pokemonDirection)
        MAZE.setBallCoord(self.ballRoot.getX(), self.ballRoot.getY())
        MAZE.sendInformation(self.myDirection, self.rockOnMaze,
                             self.onThunder, self.playerCandyCount,
                             self.pokeCandyCount, self.distance)
        # find out which direction to go
        self.direction = MAZE.getDecision()
        self.pokemonMove(self.pikachu,self.direction)
        return Task.cont

    def whatToDo(self, task):
        # determines when to use thunder
        if self.pokeCandyCount > 0: # Pikachu has candies
            decision = MAZE.useThunderDecision()
            if decision == True:
                self.useThunder()
        return Task.cont
    
    def getInformation(self, task):
        # get information on the board
        self.speedCounter += 1 # sample every other call to avoid 
        if self.speedCounter % 2 == 0:
            dX = self.ballRoot.getX() - self.oldPos[0]
            dY = self.ballRoot.getY() - self.oldPos[1]
            if dX < 0 :
                # print "going left"
                self.myDirection[0] = 'l'
            elif abs(dX) < _EPSILON:
                # print "not moving horiz"
                self.myDirection[0] = 'zx'
            else:
                # print "going right"
                self.myDirection[0] = 'r'
            if dY < 0 :
                # print "going down"
                self.myDirection[1] = 'd'
            elif abs(dY) < _EPSILON:
                # print "not moving verti"
                self.myDirection[1] = 'zy'
            else:
                # print "going up"
                self.myDirection[1] = 'u'
            self.oldPos = self.ballRoot.getPos()
        # calculate distance
        self.distance = MAZE.getDistance()
        return Task.cont
    
    def start(self):
        # maze model has a locator in it
        # self.ballRoot.show()
        self.startPos = self.MAZE.find("**/start").getPos()
        self.oldPos = self.MAZE.find("**/start").getPos()
        self.ballRoot.setPos(self.startPos) # set the ball in the pos
        self.ballV = Vec3(0,0,0) # initial velocity
        self.accelV = Vec3(0,0,0) # initial acceleration

        # for a traverser to work, need to call traverser.traverse()
        # base has a task that does this once a frame
        base.cTrav = self.cTrav

        # create the movement task, make sure its not already running
        taskMgr.remove("rollTask")
        taskMgr.add(self.placeRock, "placeRock")
        taskMgr.add(self.displayClock, "displayClock")
        taskMgr.add(self.timer, "timer")
        taskMgr.add(self.loadNextMusic, "loadNextMusic")
        taskMgr.add(self.getInformation, "getInformation")
        taskMgr.add(self.eatRareCandy, "eatRareCandy")
        taskMgr.add(self.placeRareCandy, "placeRareCandy")
        taskMgr.add(self.checkMouse, "checkMouse")
        taskMgr.add(self.spinCamera, "spinCamera")
        taskMgr.add(self.changeFocus, "changeFocus")
        taskMgr.add(self.whereToGo, "whereToGo")
        taskMgr.add(self.whatToDo, "whatToDo")
        taskMgr.add(self.moveBall, "moveBall")
        taskMgr.add(self.thunderbolt, "thunderbolt")
        taskMgr.add(self.checkForWin, "checkForWin")
        taskMgr.add(self.pikachuBark, "pikachuBark")
        self.mainLoop = taskMgr.add(self.rollTask, "rollTask")
        self.mainLoop.last = 0

    def moveBallWrapper(self, direction):
        # wrapper for moving the ball
        # needs to be improved
        if direction == False:
            self.arrowKeyPressed = False
        else:
            self.arrowKeyPressed = True
            self.jerkDirection = direction
    
    def moveBall(self, task):
        # move the ball
        # a key press changes the jerk
        direction = self.jerkDirection
        if self.arrowKeyPressed == True and self.onThunder == False:
            if direction == "u":
                self.jerk = Vec3(0,_JERK,0)
            elif direction == "d":
                self.jerk = Vec3(0,-_JERK,0)
            elif direction == "l":
                self.jerk = Vec3(-_JERK,0,0)
            elif direction == "r":
                self.jerk = Vec3(_JERK,0,0)
        elif self.onThunder == True:
            self.jerk = self.jerk
        return Task.cont        

    # collision between ray and ground
    # info about the interaction is passed in colEntry
    
    def groundCollideHandler(self,colEntry):
        # set the ball to the appropriate Z for it to be on the ground
        newZ = colEntry.getSurfacePoint(render).getZ()
        self.ballRoot.setZ(newZ+.4)

        # up vector X normal vector
        norm = colEntry.getSurfaceNormal(render)
        accelSide = norm.cross(UP)
        self.accelV = norm.cross(accelSide)

    # collision between the ball and a wall
    def wallCollideHandler(self,colEntry):
        # some vectors needed to do the calculation
        norm = colEntry.getSurfaceNormal(render) * -1
        norm.normalize()
        curSpeed = self.ballV.length()
        inVec = self.ballV/curSpeed
        velAngle = norm.dot(inVec) # angle of incidance
        hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
        hitDir.normalize()
        hitAngle = norm.dot(hitDir)
    # deal with collision cases
        if velAngle > 0 and hitAngle >.995:
            # standard reflection equation
            reflectVec = (norm * norm.dot(inVec*-1)*2) + inVec
            # makes velocity half of hitting dead-on
            self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5))
            # a collision means the ball is already a little bit buried in
            # move it so exactly touching the wall
            disp = (colEntry.getSurfacePoint(render) -
                    colEntry.getInteriorPoint(render))
            newPos = self.ballRoot.getPos() + disp
            self.ballRoot.setPos(newPos)
            
    def rollTask(self,task):
        # 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 is a HICCUP
        # ignore the frame
        if dt > .2: return Task.cont
        # dispatch which function to handle the collision based on name
        for i in range(self.cHandler.getNumEntries()):
            entry = self.cHandler.getEntry(i)
            name = entry.getIntoNode().getName()
            if name == "Wall.004":
                self.wallCollideHandler(entry)
            elif name=="Cube.004":
                self.groundCollideHandler(entry)
            else:
                if self.rockOnMaze == True:
                    self.wallCollideHandler(entry)
                    
        self.accelV += self.jerk
        # move the ball, update the velocity based on accel
        self.ballV += self.accelV * dt * ACCELERATION
        # clamp the velocity to the max speed
        if self.ballV.lengthSquared() > MAX_SPEED_SQ:
            self.ballV.normalize()
            self.ballV *= MAX_SPEED
        # update the position
        self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV*dt))

        # uses quaternion to rotate the ball
        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     
Exemplo n.º 38
0
class Collision():
    def __init__(self, ui):

        self.ui = ui

        # 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.ui.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.ui.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.ui.maze.find("**/ground_collide")
        self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1))

        # 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.ui.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.ui.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)
Exemplo n.º 39
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        base.render.setAttrib(LightRampAttrib.makeHdr0())

        # Configure depth pre-pass
        prepass_pass = lionrender.DepthScenePass()

        # Configure scene pass
        scene_fb_props = FrameBufferProperties()
        scene_fb_props.set_rgb_color(True)
        scene_fb_props.set_rgba_bits(8, 8, 8, 0)
        scene_fb_props.set_depth_bits(32)
        scene_pass = lionrender.ScenePass(
            frame_buffer_properties=scene_fb_props,
            clear_color=LColor(0.53, 0.80, 0.92, 1),
            share_depth_with=prepass_pass)
        scene_pass.node_path.set_depth_write(False)

        # Configure post processing
        filter_pass = lionrender.FilterPass(fragment_path='shaders/fsq.frag')
        filter_pass.node_path.set_shader_input('inputTexture',
                                               scene_pass.output)

        # Enable FXAA
        fxaa_pass = lionrender.FxaaFilterPass()
        fxaa_pass.node_path.set_shader_input('inputTexture',
                                             filter_pass.output)

        # Output result
        fxaa_pass.output_to(render2d)

        # 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])
        self.accept("v", self.toggleCards)

        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))

        # Clean up texture attributes
        for texture in self.render.find_all_textures():
            texture.set_format(Texture.F_srgb)

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

        # If a move-key is pressed, move ralph in the specified direction.

        if self.keyMap["left"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -20 * dt)
        if self.keyMap["backward"]:
            self.ralph.setY(self.ralph, +10 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
        currentAnim = self.ralph.getCurrentAnim()

        if self.keyMap["forward"]:
            if currentAnim != "run":
                self.ralph.loop("run")
        elif self.keyMap["backward"]:
            # Play the walk animation backwards.
            if currentAnim != "walk":
                self.ralph.loop("walk")
            self.ralph.setPlayRate(-1.0, "walk")
        elif self.keyMap["left"] or self.keyMap["right"]:
            if currentAnim != "walk":
                self.ralph.loop("walk")
            self.ralph.setPlayRate(1.0, "walk")
        else:
            if currentAnim is not None:
                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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z

        entries = list(self.ralphGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.ralph.setZ(entry.getSurfacePoint(render).getZ())

        # Keep the camera at one unit above the terrain,
        # or two units above ralph, whichever is greater.

        entries = list(self.camGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.camera.setZ(entry.getSurfacePoint(render).getZ() + 1.5)
        if self.camera.getZ() < self.ralph.getZ() + 2.0:
            self.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.camera.lookAt(self.floater)

        return task.cont

    def toggleCards(self):
        self.bufferViewer.toggleEnable()
Exemplo n.º 40
0
class World(DirectObject):
    global bk_text
    bk_text = ' '

    def __init__(self):
        global speed
        global maxspeed

        self.keyMap = {"left":0, "right":0, "forward":0, "accelerate":0, "decelerate":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # Post the instructions
        self.title = addTitle("HW2: Roaming Ralph Modified (Walking on the Moon) with friends")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[A]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[D]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[W]: Move Ralph Forward")
        self.inst5 = addInstructions(0.75, "[P]: Increase Ralph Velocity (Run)")
        self.inst6 = addInstructions(0.70, "[O]: Decrease Ralph Velocity (Walk)")
        self.inst7 = addInstructions(0.60, "[Left Arrow]: Rotate Camera Left")
        self.inst8 = addInstructions(0.55, "[Right Arrow]: Rotate Camera Right")

        # Set up the environment
        self.environ = loader.loadModel("models/square")
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        self.environ.setScale(100,100,1)
        self.moon_tex = loader.loadTexture("models/moon_1k_tex.jpg")
        self.environ.setTexture(self.moon_tex, 1)

        # Create the main character, Ralph

        if(v ==[0]):
            print(model)
            self.ralph = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"})
            self.ralph.setScale(.2)
        elif(v == [1]):
            print(model)
            self.ralph = Actor("models/panda-model", {"walk": "models/panda-walk4"})
            speed = 100
            maxspeed =10000
            self.ralph.setScale(0.0001, 0.00015, 0.0005)
            self.ralph.setScale(.002)

            self.ralph.setPlayRate(100.0, "models/panda-walk4")
            speed = 100
            maxspeed =10000
            self.ralph.setScale(.0035)
        else:
            print(model)
            self.ralph = Actor("models/GroundRoamer.egg")
            self.ralph.setScale(.15)
            self.ralph.setHpr(180,0,0)
            self.Groundroamer_texture = loader.loadTexture("models/Groundroamer.tif")
            self.ralph.setTexture(self.Groundroamer_texture)

        self.ralph.reparentTo(render)
        self.ralph.setPos(0,0,0)

        #creates Earth
        self.earth = Actor("models/planet_sphere.egg.pz")
        self.earth.reparentTo(render)
        self.earth.setScale(6.0)
        self.earth.setPos(40,25,6)
        self.earth_texture = loader.loadTexture("models/earth_1k_tex.jpg")
        self.earth.setTexture(self.earth_texture)

        #creates Mercury
        self.mercury = Actor("models/planet_sphere.egg.pz")
        self.mercury.reparentTo(render)
        self.mercury.setScale(2.0)
        self.mercury.setPos(-40,-25,2)
        self.mercury_texture = loader.loadTexture("models/mercury_1k_tex.jpg")
        self.mercury.setTexture(self.mercury_texture)

        #creates Venus
        self.venus = Actor("models/planet_sphere.egg.pz")
        self.venus.reparentTo(render)
        self.venus.setScale(4.0)
        self.venus.setPos(40,-30,4)
        self.venus_texture = loader.loadTexture("models/venus_1k_tex.jpg")
        self.venus.setTexture(self.venus_texture)

        # 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("arrow_left-up", self.setKey, ["cam-left",0])
        self.accept("arrow_right-up", self.setKey, ["cam-right",0])
        self.accept("p", self.setKey, ["accelerate",1])
        self.accept("o", self.setKey, ["decelerate",1])
        self.accept("p-up", self.setKey, ["accelerate",0])
        self.accept("o-up", self.setKey, ["decelerate",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)

        self.cTrav = CollisionTraverser()

        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)


        # 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


    # 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()

        # pring the inital position
        #print startpos

        global speed
        global maxspeed
        # 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())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            if (v == [2]):
                self.ralph.setY(self.ralph, speed * globalClock.getDt())
            else:
                self.ralph.setY(self.ralph, -speed * globalClock.getDt())

        if (self.keyMap["accelerate"]!=0):
            speed += 100
        if (speed > maxspeed):
            speed = maxspeed
        elif (self.keyMap["decelerate"]!=0):
            speed -= 1
        if (speed < 10.0):
            speed = 10.0

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                self.ralph.loop("walk")
                self.ralph.loop("run")
                self.isMoving = True
        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk",5)
                self.isMoving = False
                speed = 10.0

        # 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

        # 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 World(DirectObject):

    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # number of collectibles
        self.numObjects = 10;
        
        # print the number of objects
        printNumObj(self.numObjects)

        # Post the instructions
        self.title = addTitle("Roaming Ralph (Edited by Adam Gressen)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[A]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[D]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[W]: Run Ralph Forward")
        self.inst5 = addInstructions(0.75, "[S]: Run Ralph Backward")
        self.inst6 = addInstructions(0.70, "[Space]: Run, Ralph, Run")
        
        # 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)
        self.environ.setPos(0,0,0)
        
        # Timer to increment in the move task
        self.time = 0
        
        # Get bounds of environment
        min, max = self.environ.getTightBounds()
        self.mapSize = max-min
        
        # Create the main character, Ralph
        self.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(self.ralphStartPos)
        
        # ralph's health
        self.health = 100
        
        # ralph's stamina
        self.stamina = 100

        # 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)
        
        # these don't work well in combination with the space bar
        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("arrow_down", self.setKey, ["backward",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("arrow_down-up", self.setKey, ["backward",0])
        
        self.accept("space", self.runRalph, [True])
        self.accept("space-up", self.runRalph, [False])
        
        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("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])

        # Game state variables
        self.isMoving = False
        self.isRunning = False

        # Set up the camera
        base.disableMouse()
        #base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        base.camera.setPos(0, 0, 0)
        base.camera.reparentTo(self.ralph)
        base.camera.setPos(0, 40, 2)
        base.camera.lookAt(self.ralph)
        
        # 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.

        base.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0,0,300)
        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()
        base.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        # camera ground collision handler
        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,300)
        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()
        base.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # Place the health items
        self.placeHealthItems()
        
        # Place the collectibles
        self.placeCollectibles()
       
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        #base.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))
        
        taskMgr.add(self.move,"moveTask")
        taskMgr.doMethodLater(0.5, self.healthDec, "healthTask")
    
    # reinitialize all necessary parts of the game
    def restart(self):
        self.numObjects = 10
        printNumObj(self.numObjects)
        self.ralph.setPos(self.ralphStartPos)
        self.health = 100
        self.stamina = 100
        self.time = 0
        base.camera.setPos(0, 0, 0)
        base.camera.reparentTo(self.ralph)
        base.camera.setPos(0, 40, 2)
        base.camera.lookAt(self.ralph)
        self.placeHealthItems()
        self.placeCollectibles()
        taskMgr.add(self.move,"moveTask")
        taskMgr.doMethodLater(0.5, self.healthDec, "healthTask")
    
    # Display ralph's health
    def displayHealth(self):
        healthBar['scale'] = (self.health*0.01*BAR_WIDTH,0.2,0.2)
    
    # Display ralph's stamina
    def displayStamina(self):
        sprintBar['scale'] = (self.stamina*0.01*BAR_WIDTH,0.2,0.2)
    
    # Allow ralph to collect the health items
    def collectHealthItems(self, entry):
        # refill ralph's health
        self.health = 100
        # reposition the collectible
        self.placeItem(entry.getIntoNodePath().getParent())
    
    def collectCollectibles(self, entry):
        # remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # update the number of objects
        self.numObjects -= 1
        printNumObj(self.numObjects)
        
    # Places an item randomly on the map    
    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 placeHealthItems(self):
        self.placeholder = render.attachNewNode("HealthItem-Placeholder")
        self.placeholder.setPos(0,0,0)
        
        # Add the health items to the placeholder node
        for i in range(5):
            # Load in the health item model
            self.healthy = loader.loadModel("models/sphere")
            self.healthy.setPos(0,0,0)
            self.healthy.reparentTo(self.placeholder)
            
            self.placeItem(self.healthy)
            
            # Add spherical collision detection
            healthSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('healthSphere')
            sphereNode.addSolid(healthSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.healthy.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)
            
    def placeCollectibles(self):
        self.placeCol = render.attachNewNode("Collectible-Placeholder")
        self.placeCol.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.numObjects):
            # Load in the health item model
            self.collect = loader.loadModel("models/jack")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeCol)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            colSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('colSphere')
            sphereNode.addSolid(colSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)
        
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    
    # Makes ralph's health decrease over time
    def healthDec(self, task):
        if (self.health <= 0):
            self.die()
        elif (self.numObjects != 0):
            self.health -= 1
            print self.health
            return task.again
        else:
            return task.done
    
    # Make ralph's stamina regenerate
    def staminaReg(self, task):
        if (self.stamina >= 100):
            self.stamina = 100
            return task.done
        else:
            self.stamina += 1
            task.setDelay(1)
            return task.again
        
    # Make ralph run
    def runRalph(self, arg):
        self.isRunning = arg
    
    # 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 self.numObjects != 0:
            # print the time
            self.time += globalClock.getDt()
            timeText['text'] = str(self.time)
        else:
            self.die()
        
        # 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()
        
        # calculate ralph's speed
        if (self.isRunning and self.stamina > 0):
            taskMgr.remove("staminaTask")
            ralphSpeed = 45
            self.stamina -= 0.5
        else:
            taskMgr.doMethodLater(5, self.staminaReg, "staminaTask")
            ralphSpeed = 25

        # If a move-key is pressed, move ralph in the specified direction.
        # and rotate the camera to remain behind ralph
        if (self.keyMap["left"]!=0):
            self.ralph.setH(self.ralph.getH() + 100 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 100 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -ralphSpeed * globalClock.getDt())
        if (self.keyMap["backward"]!=0):
            self.ralph.setY(self.ralph, ralphSpeed *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["left"]!=0) 
            or (self.keyMap["right"]!=0) or (self.keyMap["backward"]!=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

        # so the following line is unnecessary
        base.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.
        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
            #base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+5)
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "healthSphere"):
            self.collectHealthItems(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "colSphere"):
            self.collectCollectibles(entries[0])
        else:
            self.ralph.setPos(startpos)
        
        # Keep the camera above the terrain
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            modZ = entries[0].getSurfacePoint(render).getZ()
            base.camera.setZ(20.0+modZ+(modZ-self.ralph.getZ()))
        
        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ()+2.0)
        base.camera.lookAt(self.floater)
        
        self.displayHealth()
        self.displayStamina()

        return task.cont
    
    # Restart or End?
    def die(self):
        # end all running tasks
        taskMgr.remove("moveTask")
        taskMgr.remove("healthTask")
        
        # open the file
        f = open('scores.txt', 'r')
        
        # current name, time, and collected items score
        n = f.readline()
        t = f.readline()
        c = f.readline()
        
        # close the file
        f.close()
        
        # number of collected collectibles
        colObj = 10 - self.numObjects
        
        # enter new high score
        if int(c) < colObj or (int(c) == colObj and float(t) > self.time):
            self.label = DirectLabel(text="New High Score! Enter Your Name:",
                                      scale=.05, pos=(0,0,0.2))
            self.entry = DirectEntry(text="", scale=.05, initialText="",
                                      numLines=1, focus=1, pos=(-0.25,0,0),
                                       command=self.submitScore)
        else:
            # display high score
            self.highscore = OkDialog(dialogName="highscoreDialog", 
                                      text="Current High Score:\n\nName: " + n + "Time: " + t + "Items Collected: " + c,
                                      command=self.showDialog)
    
    def showDialog(self, arg):
        # cleanup highscore dialog
        self.highscore.cleanup()
        # display restart or exit dialog
        self.dialog = YesNoDialog(dialogName="endDialog",
                                   text="Would you like to play again?", 
                                   command=self.endResult)
    
    def submitScore(self, name):
        f = open('scores.txt', 'w')
        
        # add new high score
        value = name + '\n' + str(self.time) + '\n' + str(10 - self.numObjects)
        f.write(value)
        
        f.close()
        
        self.entry.remove()
        self.label.remove()
        
        self.dialog = YesNoDialog(dialogName="endDialog",
                                   text="Would you like to play again?",
                                    command=self.endResult)
    
    # Handle the dialog result
    def endResult(self, arg):
        if (arg):
            # cleanup the dialog box
            self.dialog.cleanup()
            # restart the game
            self.restart()
        else:
            sys.exit()
Exemplo n.º 42
0
class KlobWorld(ShowBase):
    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 = []

    def allSounds(self):
    
        self.audio = Audio3DManager(self.sfxManagerList[0])
        
        self.audio.attachListener(base.camera)
        
        self.heartBeat = base.loadMusic("sounds/heartbeat.wav")
        self.cheer = base.loadMusic("sounds/cheer.wav")
        
        
        self.intro = base.loadMusic("sounds/Mario.wav")
        self.bulletSound = base.loadMusic("sounds/gun_shot.wav")
        self.laserSound = base.loadMusic("sounds/gun_shot.wav")
        self.deadSound = base.loadMusic("sounds/pacman_death.wav")
        self.sound = self.audio.loadSfx("sounds/forest.wav")
        self.gust = base.loadMusic("sounds/gust.wav")
        self.siren = base.loadMusic("sounds/siren_2.wav")
        self.waterfallSound = self.audio.loadSfx("sounds/waterfall.wav")
        self.etSound = base.loadMusic("sounds/et-sound.wav")
        self.walking = base.loadMusic("sounds/running.wav")
        self.mainMenuMusic = base.loadMusic("sounds/intro.wav")
        self.rainforestMusic = self.loader.loadSfx("sounds/rainforest.wav")
        self.egyptMusic = self.loader.loadSfx("sounds/egypt.wav")
        self.asiaMusic = self.loader.loadSfx("sounds/asia.wav")
        self.newyorkMusic = self.loader.loadSfx("sounds/newyork.wav")
        
        self.mainMenuMusic.setLoop(True)
        self.rainforestMusic.setLoop(True)
        self.egyptMusic.setLoop(True)
        self.asiaMusic.setLoop(True)
        self.newyorkMusic.setLoop(True)
        
        self.gust.setLoop(True)
        self.sound.setLoop(True)
        self.siren.setLoop(True)
        
        self.walking.setVolume(5)
        self.heartBeat.setVolume(5)
        self.deadSound.setVolume(.5)
        self.laserSound.setVolume(.2)
        self.bulletSound.setVolume(.2)
        self.sound.setVolume(2)
        self.rainforestMusic.setVolume(.6)
        self.egyptMusic.setVolume(2)
        self.siren.setVolume(.3)
    
    def stopAllSounds(self):
        self.audio.detachSound(self.waterfallSound)
        self.audio.detachSound(self.sound)
        self.audio.detachSound(self.rainforestMusic)
        self.audio.detachSound(self.egyptMusic)
        self.audio.detachSound(self.newyorkMusic)
        
        self.intro.stop()
        self.bulletSound.stop()
        self.laserSound.stop()
        self.deadSound.stop()
        self.sound.stop()
        self.gust.stop()
        self.siren.stop()
        self.waterfallSound.stop()
        self.etSound.stop()
        self.walking.stop()
        self.mainMenuMusic.stop()
        self.rainforestMusic.stop()
        self.egyptMusic.stop()
        self.asiaMusic.stop()
        self.newyorkMusic.stop()
        
        
       
    def MainMenuLevels(self):
        if(self.currentLevel != "start"):
            self.destroyLevel()
            self.stopAllSounds()
            
        self.level1Btn = DirectButton(
                                scale = (0.27,0.1,0.1),
                                command = self.loadRainforestLevel,
                                pos = Vec3(0, 0, 0.4),
                                image = 'GUI/southamericabutton.png', 
                                relief = None)
        self.level2Btn = DirectButton(
                                scale = (0.27,0.1,0.1),
                                command = self.loadAfricaLevel,
                                pos = Vec3(0, 0, 0.15),
                                image = 'GUI/africabutton.png', 
                                relief = None)
        self.level3Btn = DirectButton(
                                scale = (0.27,0.1,0.1),
                                command = self.loadAsiaLevel,
                                pos = Vec3(0, 0, -0.1),
                                image = 'GUI/asiabutton.png', 
                                relief = None)
        self.level4Btn = DirectButton(
                                scale = (0.27,0.1,0.1),
                                command = self.loadNewYorkLevel,
                                pos = Vec3(0, 0, -0.35),
                                image = 'GUI/americabutton.png', 
                                relief = None)    
       
        self.level2Btn.setTransparency(TransparencyAttrib.MAlpha)
        self.level3Btn.setTransparency(TransparencyAttrib.MAlpha)
        self.level4Btn.setTransparency(TransparencyAttrib.MAlpha)
        self.level1Btn.setTransparency(TransparencyAttrib.MAlpha)
    

    def destroyMainMenuLevels(self):
        self.level1Btn.destroy()
        self.level2Btn.destroy()
        self.level3Btn.destroy()
        self.level4Btn.destroy()
        self.mainMenuBtn = DirectButton(
                        text="Main Menu",
                        scale = (0.1,0.1,0.1),
                        command = self.MainMenuLevels,
                        pos = Vec3(0.8, 0, -0.9))
        
    def MainMenu(self):
        if(self.currentLevel == "help"):
            self.destroyHelpMenu()
        elif(self.currentLevel != "start"):
            self.destroyLevel()
            self.mainMenuBtn.destroy()
            self.stopAllSounds()
            
        self.currentLevel="start"
        self.mainMenuImage = OnscreenImage("GUI/mainmenu.png",pos = Vec3(0, 0.0,-0.8), scale=(1.8, 0, 1.8))
        self.mainMenuImage.reparentTo(aspect2d)
        self.mainMenuImage.setTransparency(1)
        self.mainMenuMusic.play()
        mapStart = loader.loadModel('GUI/button_maps.egg') 
        self.startBtn = DirectButton(geom =
                        (mapStart.find('**/start_but'),
                         mapStart.find('**/start_but_click'),
                         mapStart.find('**/start_but_roll'),
                         mapStart.find('**/start_but_disabled')),
                         relief = None,
                         command = self.introScreen,
                         scale = (0.7,0.7,0.7),
                         pos = Vec3(0.6, 0, -0.35))
        self.startBtn.setTransparency(TransparencyAttrib.MAlpha)
        mapHelp = loader.loadModel('GUI/helpbutton_maps.egg') 
        self.helpBtn = DirectButton(geom =
                        (mapHelp.find('**/help_but'),
                         mapHelp.find('**/help_but_click'),
                         mapHelp.find('**/help_but_roll'),
                         mapHelp.find('**/help_but_disabled')),
                         relief = None,
                         command = self.HelpMenu,
                         scale = (0.8,0.65,0.65),
                         pos = Vec3(0.6, 0,-0.65))
        self.helpBtn.setTransparency(TransparencyAttrib.MAlpha)
        
    def destroyMainMenu(self):
        self.startBtn.destroy()
        self.helpBtn.destroy()
        self.mainMenuImage.destroy()
        self.stopAllSounds()
        
    def HelpMenu(self):
        self.destroyMainMenu()
        self.currentLevel="help"
        self.helpMenuImage = OnscreenImage("GUI/helpmenu.png",pos = Vec3(0, 0.0,-0.8), scale=(1.8, 0, 1.8))
        self.helpMenuImage.reparentTo(aspect2d)
        self.helpMenuImage.setTransparency(1)
        
        mapHelp = loader.loadModel('GUI/backbutton_maps.egg') 
        self.backBtn = DirectButton(geom =
                        (mapHelp.find('**/backBtn'),
                         mapHelp.find('**/backBtn_click'),
                         mapHelp.find('**/backBtn_roll'),
                         mapHelp.find('**/backBtn_disabled')),
                         relief = None,
                         command = self.MainMenu,
                         scale = (0.7,0.7,0.7),
                         pos = Vec3(-1.4, 0, 0.8))
        self.backBtn.setTransparency(TransparencyAttrib.MAlpha)
      ###......
      #code missing.
     ### ....
        
    ##Records the state of the arrow keys###
    def setKey(self, key, value):
        if(self.pause is False):
            self.keyMap[key] = value
    
            
            if(self.keyMap["fire-down"] != 0 ):
                if( self.energy['value'] != 0 ):
    
                    if(self.bossDead is False):
                        self.beamC.append( self.loadLaser() )
                        self.laserAmo.append( self.laser() )
                    if(self.laserAmo):    
                        self.laserAmo[self.laserAmoCount].start()
                    self.energy['value'] -= 3
                    self.laserAmoCount = self.laserAmoCount + 1
                    
        
            
    def loadEnviron(self, filename, scale):
        
        self.environ = self.loader.loadModel(filename)
        self.environ.setScale(scale)
        self.environ.reparentTo(self.render)
        self.environ.setPos(0, 0, 0)
        self.environ.setTag('wall','1')
        self.environ.setCollideMask(BitMask32(0x01))
        
        alight = AmbientLight('alight')
        alight.setColor(VBase4(0.8, 0.8, 0.8, 1))
        alnp = render.attachNewNode(alight)
        render.setLight(alnp)
    
    
    def loadAlien(self, point):

        ###Load alien actor###
        self.alien = Actor("models/alien/slugrocket-model",
                           {"walk":"models/alien/slugrocket-anim"})
                           
        self.alien.reparentTo(render)
        self.alien.setScale(3)
        self.alien.setPos(point)
        self.alien.setPlayRate(1.2, "walk")
        self.alien.setBlend(frameBlend = True)
        
        self.dlight = DirectionalLight('my dlight')
        self.dlnp = render.attachNewNode(self.dlight)
        self.dlnp.reparentTo(base.camera)
        self.dlnp.lookAt(self.alien)
        self.dlight.setColor(VBase4(0.8, 0.8, 0.5, 1))
        render.setLight(self.dlnp)
        
        base.camera.setPos(0,-10,2)
        base.camera.reparentTo(self.alien)
        

        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(2))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        base.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
        
        
        csAlien = CollisionSphere(0,0,0.6,0.6)
        cnodeAlienPath = self.alien.attachNewNode(CollisionNode('csAlien'))
        cnodeAlienPath.node().addSolid(csAlien)
        self.pusher.addCollider(cnodeAlienPath, self.alien)
        base.cTrav.addCollider(cnodeAlienPath, self.pusher)
        
        ### Uncomment the following comment to show 
        ### the Collision Sphere on the alien
        ## cnodeAlienPath.show()

        self.health = DirectWaitBar(scale = 0.5,
                            range = 100,
                            value = 100,
                            barColor = (0,1,0,1),
                            pos = Vec3(0.75, 0, 0.9))
                                    
        self.energy = DirectWaitBar(scale = 0.5,
                                    range = 100,
                                    value = 100,
                                    barColor = (1,1,0,1),
                                    pos = Vec3(-0.75, 0, 0.9))
        self.energy.reparentTo(aspect2d)
        self.health.reparentTo(aspect2d)
        self.hud = OnscreenImage("GUI/hud.png",scale = Vec3(1.43, 1.0, 1.03),pos = Vec3(0, 0.0,0.045))
        self.hud.reparentTo(aspect2d)
        self.hud.setTransparency(1)
        self.extraElements.append(self.energy)
        self.extraElements.append(self.health)
        self.extraElements.append(self.hud)

        
        
    def alienDie(self, currLvl):
        self.alien.stop()
        self.pause=True
        temp = NodePath(PandaNode("temp"))
        
        base.camera.reparentTo(self.floater)
        base.camera.setZ(base.camera.getZ()+1)
        base.camera.setY(base.camera.getY()-25)
        self.deadSound.play()
        
        fall = LerpHprInterval(nodePath=self.alien, duration=1.5, hpr=(self.alien.getH(),self.alien.getP(), self.alien.getR()-80))
        fall.start()
        
        
        taskMgr.remove("moveTask")
        taskMgr.remove("laterFc")
        transition = Transitions(loader) 
        transition.setFadeColor(0, 0, 0)
        self.dieImage = OnscreenImage("GUI/died.png",scale = Vec3(0.7, 0, 0.2),pos = Vec3(0, 0,-0.5))
        self.dieImage.reparentTo(aspect2d)
        self.dieImage.setTransparency(1)
        if(self.currentLevel == "rainforest"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(2.0),Func(self.destroyLevel),Func(self.loadRainforestLevel),Func(self.dieImage.destroy),Func(transition.fadeIn)).start()
        elif(self.currentLevel == "africa"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(2.0),Func(self.destroyLevel),Func(self.loadAfricaLevel),Func(self.dieImage.destroy),Func(transition.fadeIn)).start()
        elif(self.currentLevel == "asia"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(2.0),Func(self.destroyLevel),Func(self.loadAsiaLevel),Func(self.dieImage.destroy),Func(transition.fadeIn)).start()
        elif(self.currentLevel == "newyork"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(2.0),Func(self.destroyLevel),Func(self.loadNewYorkLevel),Func(self.dieImage.destroy),Func(transition.fadeIn)).start()
        
        
    def collide(self, collEntry):
        collEntry.getFromNodePath().getParent().removeNode()
        
        
        
    def setAcceptKeys(self):
        
        ###Accept the control keys for movement and rotation###
        self.accept("escape", sys.exit)
        self.accept("p", self.setKey, ["p",1])
        
        
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        
        self.accept("arrow_down", self.setKey, ["backward", 1])
        self.accept("arrow_down-up", self.setKey, ["backward", 0])
        
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_right-up", self.setKey, ["right",0])

        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("a-up", self.setKey, ["cam-left",0])
        
        self.accept("s", self.setKey, ["cam-right",1])    
        self.accept("s-up", self.setKey, ["cam-right",0])
        
        self.accept("z", self.setKey, ["cam-up",1])
        self.accept("z-up", self.setKey, ["cam-up",0])
        
        self.accept("x", self.setKey, ["cam-down", 1])
        self.accept("x-up", self.setKey, ["cam-down", 0])
        
        # Accept f to fire 
        self.accept("f", self.setKey, ["fire-down",1])
        self.accept("f-up", self.setKey, ["fire-down",0])
        self.cTrav.traverse(render)
    
        
    
    
    #gun / laser code ommitted
    
    def getDistance(self, actor):
       self.vecAlien = Vec3(self.alien.getPos())
       self.vecObj = Vec3(actor.getPos())
       disVec = self.vecObj - self.vecAlien

       return disVec.length()    

    def myFunction(self,task):
        
        self.walking.play()
        
        if(self.pause is False):
            for r in range(0, len(self.crAct)):
                self.crAct[r].setTarget(self.alien)     
                self.bulletC.append( self.createBullet(self.crAct[r]) )
                self.loaded.append( self.loadBullet( self.crAct[r]) )                        
                self.loaded[self.gunAmmoCount].start()
                self.gunAmmoCount += 1
                self.bulletSound.play()
            return task.again    
        
        
    def bossLvlTask(self, dec, task):
        self.crAct[0].setAiPursue(self.alien)
                
        if(self.pause is False):
            self.deleteProjectiles()
            
            self.charcMoveKeys()
            startpos = self.alien.getPos()
            
            self.floater.setPos(self.alien.getPos())
            self.floater.setZ(self.alien.getZ() + 2.0)
            base.camera.lookAt(self.floater)
            
            self.collHandQueEne.sortEntries()
            
            if(self.collHandQueEne.getNumEntries() > 0):
                entryb = self.collHandQueEne.getEntry(0)
              
                if( entryb.getIntoNodePath().getName() == "csAlien"):
                    
                    self.health['value'] -=5
                    if(self.bulletC):
                        self.bulletC[self.gunAmmoCount-1].remove()
                        self.bulletC.pop(self.gunAmmoCount-1)
                        self.loaded.pop(self.gunAmmoCount-1)
                        self.gunAmmoCount -= 1
                    if( self.health['value'] < 20 ):
                        self.heartBeat.play()
                    if(self.health['value'] == 0):
                        self.alienDie(self.currentLevel)
                else:
                    self.bulletC[self.gunAmmoCount-1].remove()
                    self.bulletC.pop(self.gunAmmoCount-1)
                    self.loaded.pop(self.gunAmmoCount-1)
                    self.gunAmmoCount -= 1
                    
                    
            self.collHandQue.sortEntries()
            if( self.collHandQue.getNumEntries() > 0 ):
                
                entry = self.collHandQue.getEntry(0)   
                

                if( entry.getIntoNodePath().getName() == self.crAct[0].getCNP()):
                            
                    self.crAct[0].runAround(self.alien)
                            
                    self.crAct[0].setHitCount(1)
                    self.crAct[0].decreaseHealth(dec)
                            
                    if( self.beamC):
                        self.beamC[self.laserAmoCount-1].remove()
                        self.beamC.pop(self.laserAmoCount-1)
                        if(self.laserAmo):
                            self.laserAmo.pop(self.laserAmoCount-1)
                        self.laserAmoCount -= 1

                    if( self.crAct[0].getHealth()%4 == 0):
                        self.crAct[0].jumpAway(self.alien)
                                
                    if( self.crAct[0].getHealth() == 0 ):
                        ## print x.getDeaths()
                        ## if( x.canRespawn() ):
                            ## x.setDeaths(1)
                            ## x.resetHitCount(0)
                
                                    
                            ## x.setX(random.randint(0, 50))
                            ## x.setY(self.alien.getY()+15)
                        ## else:
                        self.crAct[0].cleanup()
                        self.crAct[0].remove()
                        self.crAct.pop(0)
                        self.cutScene()
                           
        if( self.crAct ):
            self.crAct[0].AIworld.update()
                                
        if( self.keyMap["p"]!= 0):
            self.cutScene()
                    
        return task.cont
    
    
    def move(self, task):
        ##ommmitted
        
               
            return task.cont

    
    def deleteProjectiles(self):
        ## if(self.pause is False):
        if(self.laserAmo):
            for i, x in enumerate(self.laserAmo):
                if( not x.isPlaying() ):
                        
                    self.beamC[i].remove()
                    self.beamC.pop(i)
                    self.laserAmo.pop(i)
                    self.laserAmoCount = self.laserAmoCount -1
                        
        if(self.loaded):
            for i, x in enumerate(self.loaded):
                if(not x.isPlaying()):
                    #self.crAct[i].setTarget(self.alien)
                    self.bulletC[i].remove()
                    self.bulletC.pop(i)
                    self.loaded.pop(i)
                    self.gunAmmoCount = self.gunAmmoCount -1
                        
        self.energyTime = self.energyTime + globalClock.getDt()
            
        if(self.energyTime > 2 ):
            if(self.energy['value'] != 100):
                self.energy['value'] +=5
                self.energyTime = 0
                    

    def charcMoveKeys(self):
        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())
                
        if (self.keyMap["cam-up"]!=0):
            base.camera.setY(base.camera, -20 * globalClock.getDt())
                
        if (self.keyMap["cam-down"]!=0):
            base.camera.setY(base.camera, +20 * globalClock.getDt())
                
        if (self.keyMap["forward"]!=0):
            self.alien.setY(self.alien, 10 * globalClock.getDt())
                
                
        if (self.keyMap["backward"]!=0):
            self.alien.setY(self.alien, -10 * globalClock.getDt())
        
                    
        if (self.keyMap["left"]!=0):
                self.alien.setH(self.alien.getH() + 40 * globalClock.getDt())

                
        if (self.keyMap["right"]!=0):
                self.alien.setH(self.alien.getH() - 40 * globalClock.getDt())

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0) or (self.keyMap["backward"] != 0):
            if self.isMoving is False:
                self.alien.loop("walk")
                self.isMoving = True
        else:
            if self.isMoving:
                self.alien.stop()
                self.alien.pose("walk",5)
                self.isMoving = False
                

    def loadingScreen(self):
        self.intro.play()
        transition = Transitions(loader) 
        transition.setFadeColor(0, 0, 0)
        text = TextNode('node name')
        dummy = NodePath(PandaNode("dummy"))
        black = OnscreenImage(image="GUI/black.png",pos=(0,0,0), scale=100)
        black.reparentTo(dummy)
        textNodePath = aspect2d.attachNewNode(text)
        textNodePath.reparentTo(aspect2d, 2)
        textNodePath.setScale(0.07)
        text.setTextColor(1, 1, 1, 1)
        
        if(self.currentLevel=="newyork"):
            Sequence(Func(transition.fadeOut),Func(black.reparentTo, aspect2d),Func(transition.fadeIn),Func(textNodePath.reparentTo,aspect2d, 10),Func(text.setText, "loading"),Wait(1.0),Func(text.setText, "loading."), 
                    Wait(1.0),Func(text.setText, "loading.."), Wait(1.0), Func(text.setText, "loading..."), Func(self.loadNextLevel),Wait(3.0),Func(transition.fadeIn),Func(textNodePath.remove), Func(black.destroy)).start()
        elif(self.currentLevel=="asia"):
            Sequence(Func(transition.fadeOut),Func(black.reparentTo, aspect2d),Func(transition.fadeIn),Func(textNodePath.reparentTo,aspect2d, 10),Func(text.setText, "loading"),Wait(1.0),Func(text.setText, "loading."), 
                    Wait(1.0),Func(text.setText, "loading.."), Wait(1.0), Func(text.setText, "loading..."), Func(self.loadNextLevel),Wait(3.0),Func(transition.fadeIn),Func(textNodePath.remove), Func(black.destroy)).start()
        else:
            Sequence(Func(transition.fadeOut),Func(black.reparentTo, aspect2d),Func(transition.fadeIn),Func(textNodePath.reparentTo,aspect2d, 10),Func(text.setText, "loading"),Wait(0.5),Func(text.setText, "loading."), 
                    Wait(0.5),Func(text.setText, "loading.."), Wait(0.5), Func(text.setText, "loading..."), Func(self.loadNextLevel),Wait(1.5),Func(transition.fadeIn),Func(textNodePath.remove), Func(black.destroy)).start()
        
        
    def cutScene(self):
        self.destroyLevel()
        self.stopAllSounds()
        
        self.cut = OnscreenImage("GUI/bossKilled.png",scale = Vec3(1.6, 0, 1.0),pos = Vec3(0, 0,0))
        self.cut.reparentTo(aspect2d)
        self.cut.setTransparency(1)
        transition = Transitions(loader) 
        transition.setFadeColor(0, 0, 0)
        self.cheer.play()
        if(self.currentLevel=="rainforest"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(1.0),Func(transition.fadeIn),Func(self.cut.setImage,"GUI/map_11.png"),
                     Wait(1.5),Func(self.cut.setImage, "GUI/map_12.png"),Wait(0.5),Func(self.cut.setImage,"GUI/map_13.png"),
                     Wait(0.5),Func(self.cut.setImage,"GUI/map_14.png"),Wait(0.5),Func(self.cut.setImage,"GUI/map_15.png"),
                     Wait(0.5),Func(self.cut.setImage,"GUI/map_16.png"),Wait(3.5),Func(self.cut.destroy), Func(transition.fadeOut), Func(self.loadingScreen), Wait(1.0),Func(transition.fadeIn)).start()
        elif(self.currentLevel=="africa"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(1.0),Func(transition.fadeIn),Func(self.cut.setImage,"GUI/map_21.png"),
                     Wait(1.5),Func(self.cut.setImage, "GUI/map_22.png"),Wait(0.5),Func(self.cut.setImage,"GUI/map_23.png"),
                     Wait(0.5),Func(self.cut.setImage,"GUI/map_24.png"),Wait(0.5),Func(self.cut.setImage,"GUI/map_25.png"),
                     Wait(0.5),Func(self.cut.setImage,"GUI/map_26.png"), Wait(3.5),Func(self.cut.destroy), Func(transition.fadeOut),Func(self.loadingScreen), Wait(1.0),Func(transition.fadeIn)).start()
        elif(self.currentLevel=="asia"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(1.0),Func(transition.fadeIn),Func(self.cut.setImage,"GUI/map_31.png"),
                     Wait(1.5),Func(self.cut.setImage, "GUI/map_32.png"),Wait(0.5),Func(self.cut.setImage,"GUI/map_33.png"),
                     Wait(0.5),Func(self.cut.setImage,"GUI/map_34.png"),Wait(0.5),Func(self.cut.setImage,"GUI/map_35.png"),
                     Wait(0.5),Func(self.cut.setImage,"GUI/map_36.png"),Wait(3.5),Func(self.cut.destroy), Func(transition.fadeOut),Func(self.loadingScreen), Wait(1.0),Func(transition.fadeIn)).start()
        elif(self.currentLevel=="newyork"):
            Sequence(Wait(2.0),Func(transition.fadeOut),Wait(1.0),Func(transition.fadeIn),Func(self.cut.setImage,"GUI/win.png"),
                     Wait(6.5),Func(self.cut.destroy), Func(transition.fadeOut),Func(self.loadingScreen), Wait(1.0),Func(transition.fadeIn)).start()
            
     
    def loadNextLevel(self):
        if(self.currentLevel=="start"):
            self.loadRainforestLevel()
        elif(self.currentLevel=="rainforest"):
            self.loadAfricaLevel()
        elif(self.currentLevel=="africa"):
            self.loadAsiaLevel()
        elif(self.currentLevel=="asia"):
            self.loadNewYorkLevel()
        else:
            self.MainMenu()
  
    def destroyLevel(self):
        self.mainMenuBtn.destroy()
        taskMgr.remove("moveTask")
        taskMgr.remove("bossTask")
        taskMgr.remove("myFunction")
        self.alien.cleanup()
        for enemy in self.crAct:
            enemy.cleanup()
            enemy.remove()
        self.alien.cleanup()
        self.alien.remove()    
        for element in self.extraElements:
            element.removeNode()
        for beam in self.beamC:
            beam.removeNode()
        self.render.clearFog    
        self.laserBeam2.removeNode()
        
        self.environ.removeNode()
        self.crAct[:] = []
        self.extraElements[:] = []

        self.laserAmo[:] =[]
        self.laserAmoCount = 0

        
    def loadBossActor(self):
        self.bossLvl = True
        ###Load Ralph Boss actor###
        difficult = 10
        taskMgr.remove("moveTask")
        taskMgr.remove("myFunction")
        self.health['value'] = 100
        self.energy['value'] = 100
        
        if(self.bossDead is False):
            self.bossImage = OnscreenImage("GUI/bossLoad.png",scale = Vec3(1.6, 0, 1.0),pos = Vec3(0, 0,0))
            self.bossImage.reparentTo(aspect2d)
            self.bossImage.setTransparency(1)
            self.ralphBoss = EnemyActor(1,difficult,True)
            self.ralphBoss.enemy.setScale(2.0)
            self.crAct.append(self.ralphBoss)
            Sequence(Wait(3.0), Func(self.bossImage.destroy), Func(self.crAct[0].showHealthBar)).start()
            
            self.extraElements.append(self.crAct[0].bossHud)
            self.extraElements.append(self.crAct[0].health)
            self.crAct[0].setAiPursue(self.alien)
            self.pusher.addCollider(self.crAct[0].getFromObj(), self.crAct[0].enemy)
            base.cTrav.addCollider(self.crAct[0].getFromObj(), self.pusher)
            gunTex = loader.loadTexture('models/gun_tex.png')
            if(self.currentLevel == "rainforest"):
                dec = 5
                self.ralphBoss.enemy.setPos(0,90,0)
                ralphTex = loader.loadTexture('models/ralph2rainforest.png')
                self.ralphBoss.enemy.setTexture(ralphTex, 1)
                self.ralphBoss.gunPos.setTexture(gunTex, 1)
            elif(self.currentLevel == "africa"):
                dec = 4
                self.ralphBoss.enemy.setPos(-100,-90,0)
                ralphTex = loader.loadTexture('models/ralph2egypt.png')
                self.ralphBoss.enemy.setTexture(ralphTex, 1)
                self.ralphBoss.gunPos.setTexture(gunTex, 1)
            elif(self.currentLevel == "asia"):
                dec = 3
                self.ralphBoss.enemy.setPos(0,0,0)
                ralphTex = loader.loadTexture('models/ralph2asia.png')
                self.ralphBoss.enemy.setTexture(ralphTex, 1)
                self.ralphBoss.gunPos.setTexture(gunTex, 1)
            elif(self.currentLevel == "newyork"):
                dec = 2
                self.ralphBoss.enemy.setPos(120,10,0)
         
        taskMgr.add(self.bossLvlTask,"bossTask", extraArgs = [dec], appendTask=True)
        taskMgr.doMethodLater(1,self.myFunction,"myFunction")
            
    
    
    def loadRainforestLevel(self):
        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}
        self.pause = False
        self.currentLevel = "rainforest"
        self.destroyIntro()
        difficulty = 2
        self.bossLvl = False
        self.bossDead = False
        ###Load alien###
        startPos = Point3(0,0,0)
        self.loadAlien(startPos)
        self.rainforestMusic.play()
        ###Load the enemies###
        ralphTex = loader.loadTexture('models/ralph2rainforest.png')
        gunTex = loader.loadTexture('models/gun_tex.png')
        for i in range(0,2):
            enemy = EnemyActor(i, difficulty, False)
            enemy.enemy.setTexture(ralphTex, 1)
            enemy.gunPos.setTexture(gunTex, 1)
            
            enemy.setX(random.randint(-50,50))
            enemy.setY(random.randint(-50,50))
            enemy.setZ(0)
            
            self.crAct.append(enemy)
            self.crAct[i].setAiPursue(self.alien)
            
            self.pusher.addCollider(self.crAct[i].getFromObj(), self.crAct[i].enemy)
            base.cTrav.addCollider(self.crAct[i].getFromObj(), self.pusher)
        
            
        taskMgr.add(self.move,"moveTask")
        taskMgr.doMethodLater(3,self.myFunction,"myFunction")
        self.loadLaser2()
        self.loadLaser()
        
        ###Load the environment###
        self.loadEnviron("models/south_america/rainforest", 5)
        self.plants = self.loader.loadModel("models/south_america/rainforest-nocollision")
        self.plants.reparentTo(self.render)
        self.plants.setScale(4)
        self.plants.setTwoSided(True)
        self.extraElements.append(self.plants)
        
        self.myFog = Fog("FOG")
        self.myFog.setColor(0.5,0.6,0.5)
        self.myFog.setExpDensity(0.005)
        render.setFog(self.myFog)
        self.audio.attachSoundToObject(self.sound, self.environ)
        self.audio.setSoundVelocityAuto(self.sound)
        self.audio.setListenerVelocityAuto()
        
        self.sound.play()
        
    
    def loadAfricaLevel(self):
        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}
        self.pause = False
        self.currentLevel="africa"
        
        difficulty = 3
        self.bossLvl = False
        self.bossDead = False
        ###Load alien###
        startPos = Point3(-130,-130,0)
        self.loadAlien(startPos)
        self.alien.setH(-40)
        
        ###Load the enemies###
        ralphTex = loader.loadTexture('models/ralph2egypt.png')
        gunTex = loader.loadTexture('models/gun_tex.png')
        for i in range(0,3):
            enemy = EnemyActor(i, difficulty, False)
            enemy.enemy.setTexture(ralphTex, 1)
            enemy.gunPos.setTexture(gunTex, 1)
            enemy.setX(random.randint(-170,-50))
            enemy.setY(random.randint(-170,-50))
            enemy.setZ(0)
        
            self.crAct.append(enemy)
            
            self.crAct[i].setAiPursue(self.alien)
            
            self.pusher.addCollider(self.crAct[i].getFromObj(), self.crAct[i].enemy)
            base.cTrav.addCollider(self.crAct[i].getFromObj(), self.pusher)

        taskMgr.add(self.move,"moveTask")
        taskMgr.doMethodLater(3,self.myFunction,"myFunction")
        
        self.loadLaser2()
        self.loadLaser()
       
        ###Load environment###
        self.loadEnviron("models/africa/egypt", 7)
        self.egypt_nc = self.loader.loadModel("models/africa/egypt-nocollision")
        self.egypt_nc.reparentTo(self.render)
        self.egypt_nc.setPos(0,0,0)
        self.egypt_nc.setScale(7)
        self.extraElements.append(self.egypt_nc)
        self.sphinx = self.loader.loadModel("models/africa/sphinx")
        self.sphinx.setPos(0,80,0)
        self.sphinx.setH(180)
        self.sphinx.setScale(0.12)
        self.sphinx.reparentTo(self.render)
        self.extraElements.append(self.sphinx)
        
        cs = CollisionSphere(0,0,0,200)
        nodePath = self.sphinx.attachNewNode(CollisionNode('nodePath'))
        nodePath.node().addSolid(cs)
        self.gust.play()
        self.audio.attachSoundToObject(self.egyptMusic, self.environ)
        self.audio.setSoundVelocityAuto(self.egyptMusic)
        self.audio.setListenerVelocityAuto()
        self.egyptMusic.play()
        
        
    def loadAsiaLevel(self):
        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}
        self.pause = False
        self.currentLevel = "asia"

        difficulty = 4
        self.bossLvl = False
        self.bossDead = False
        ###Load alien###
        startPos = Point3(190,-140,0)
        self.loadAlien(startPos)
        ###Load the enemies###
        ralphTex = loader.loadTexture('models/ralph2asia.png')
        gunTex = loader.loadTexture('models/gun_tex.png')
        for i in range(0,4):
            enemy = EnemyActor(i, difficulty, False)
            enemy.enemy.setTexture(ralphTex, 1)
            enemy.gunPos.setTexture(gunTex, 1)
            enemy.setX(random.randint(0,100))
            enemy.setY(random.randint(-150,-50))
            enemy.setZ(0)
      
            self.crAct.append(enemy)
            self.crAct[i].setAiPursue(self.alien)
            
            self.pusher.addCollider(self.crAct[i].getFromObj(), self.crAct[i].enemy)
            base.cTrav.addCollider(self.crAct[i].getFromObj(), self.pusher)
            
        taskMgr.add(self.move,"moveTask")
        taskMgr.doMethodLater(3,self.myFunction,"myFunction")
        
        self.loadLaser2()
        self.loadLaser()
        
        ###Load the environment###
        self.loadEnviron("models/asia/asia2", 5)
        self.asia_nc = self.loader.loadModel("models/asia/asia-nocollision")
        self.asia_nc.reparentTo(self.render)
        self.asia_nc.setPos(0,0,0)
        self.asia_nc.setScale(5)
        self.extraElements.append(self.asia_nc)
        
        self.myFog = Fog("FOG")
        self.myFog.setColor(0.8,0.8,0.8)
        self.myFog.setExpDensity(0.002)
        render.setFog(self.myFog)
        
        self.bonzai = self.loader.loadModel("models/asia/bonzai")
        self.bonzai.reparentTo(self.render)
        self.bonzai.setPos(170,20,0)
        self.bonzai.setScale(0.015)
        self.bonzai.setH(90)
        self.extraElements.append(self.bonzai)
        cs = CollisionSphere(0,0,200,200)
        nodePath = self.bonzai.attachNewNode(CollisionNode('nodePath'))
        nodePath.node().addSolid(cs)
        self.pusher.addCollider(nodePath, self.bonzai)
        
        self.waterfall = self.loader.loadModel("models/asia/waterFall")
        self.waterfall.reparentTo(self.render)
        self.waterfall.setPos(200,80,-.5)
        self.waterfall.setScale(0.25)
        self.waterfall.setH(180)
        self.extraElements.append(self.waterfall)
        cs = CollisionSphere(0,15,-5,130)
        nodePath = self.waterfall.attachNewNode(CollisionNode('nodePath'))
        nodePath.node().addSolid(cs)
        self.pusher.addCollider(nodePath, self.waterfall)
        
        self.waterfallSound.setLoop(True)
        self.audio.attachSoundToObject(self.waterfallSound,self.waterfall)
        self.audio.setSoundVelocityAuto(self.waterfallSound)
        self.audio.setListenerVelocityAuto()
        self.audio.setDistanceFactor(1.5)
        self.waterfallSound.play()
        
        self.tree1 = self.loader.loadModel("models/asia/bamboo")
        self.tree1.reparentTo(self.render)
        self.tree1.setPos(-50,-50,0)
        self.tree1.setScale(0.6,0.6,0.6)
        self.tree1.setBillboardAxis()
        self.extraElements.append(self.tree1)
        
        #Child bamboos scattered around
        placeholder = render.attachNewNode("Bamboo-Placeholder")
        placeholder.setPos(180,-40,0)
        placeholder.setScale(0.8)
        self.tree1.instanceTo(placeholder)
        self.extraElements.append(placeholder)
        
        placeholder = render.attachNewNode("Babmboo-Placeholder")
        placeholder.setPos(-20,-120,0)
        placeholder.setScale(1.0)
        self.tree1.instanceTo(placeholder)
        self.extraElements.append(placeholder)
                
        placeholder = render.attachNewNode("Bamboo-Placeholder")
        placeholder.setPos(-50,180,0)
        placeholder.setScale(1.0)
        self.tree1.instanceTo(placeholder)
        self.extraElements.append(placeholder)
        
        placeholder = render.attachNewNode("Bamboo-Placeholder")
        placeholder.setPos(-60,165,0)
        placeholder.setScale(0.6)
        self.tree1.instanceTo(placeholder)
        self.extraElements.append(placeholder)
        
        placeholder = render.attachNewNode("Bamboo-Placeholder")
        placeholder.setPos(-110,70,0)
        placeholder.setScale(1.0)
        self.tree1.instanceTo(placeholder)
        self.extraElements.append(placeholder)
        
        placeholder = render.attachNewNode("Bamboo-Placeholder")
        placeholder.setPos(-100,-50,0)
        placeholder.setScale(1.6)
        self.tree1.instanceTo(placeholder)
        self.extraElements.append(placeholder)
        
        self.asiaMusic.play()

    
    def loadNewYorkLevel(self):
        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}
        self.pause = False
        self.currentLevel = "newyork"
        #self.destroyMainMenuLevels()
        difficulty = 5
        ###Load alien###
        startPos = Point3(20,10,0)
        self.loadAlien(startPos)
        self.alien.setH(90)
        
        base.camera.setH(90)
        self.bossLvl = False
        self.bossDead = False
        ###Load the enemies###
        for i in range(0,5):
            enemy = EnemyActor(i, difficulty, False)      
            enemy.setX(random.randint(-100,100))
            enemy.setY(random.randint(8,12))
            enemy.setZ(0)
            
            self.crAct.append(enemy)
            self.crAct[i].setAiPursue(self.alien)
            
            self.pusher.addCollider(self.crAct[i].getFromObj(), self.crAct[i].enemy)
            base.cTrav.addCollider(self.crAct[i].getFromObj(), self.pusher)
            
        taskMgr.add(self.move,"moveTask")
        taskMgr.doMethodLater(2,self.myFunction, "myFunction")
     
        self.loadLaser2()
        self.loadLaser()
        
        ###Load the environment###
        self.loadEnviron("models/america/newyork", 4)
        self.ny_nc = self.loader.loadModel("models/america/newyork-nocollision")
        self.ny_nc.reparentTo(self.render)
        self.ny_nc.setScale(4)
        self.extraElements.append(self.ny_nc)
        
        self.statue = self.loader.loadModel("models/america/statue")
        self.statue.reparentTo(self.render)
        self.statue.setPos(270,-100,13)
        self.statue.setScale(1)
        self.statue.setBillboardAxis()
        self.statue.setTwoSided(True)
        self.extraElements.append(self.statue)
        
        self.myFog = Fog("FOG")
        self.myFog.setColor(0.3,0.3,0.3)
        self.myFog.setExpDensity(0.005)
        render.setFog(self.myFog)
        self.siren.play()
        self.newyorkMusic.play()
Exemplo n.º 43
0
class World(DirectObject):
    def __init__(self):

        self.startvar = 0
        self.startdialog = YesNoDialog(dialogName="START GAME",
                                       text="START GAME",
                                       command=self.endbox)
        self.timepass = model()
        self.timepass1 = model1()
        self.keyMap = {"left": 0, "right": 0, "forward": 0, "backward": 0}
        base.win.setClearColor(Vec4(0, 0, 0, 1))

        # number of collectibles
        self.numObjects = 0

        #music
        self.backmusic = base.loader.loadSfx("sounds/tales.mp3")
        self.backmusic.setLoop(True)
        self.backmusic.setVolume(0.2)
        self.backmusic.play()

        self.skatemusic = base.loader.loadSfx("sounds/skate.mp3")
        self.skatemusic.setVolume(.65)
        self.skatemusic.setLoop(True)

        self.bombmusic = base.loader.loadSfx("sounds/bomb.mp3")
        self.bombmusic.setVolume(.85)

        self.springmusic = base.loader.loadSfx("sounds/spring.mp3")
        self.springmusic.setVolume(.65)
        self.springmusic.setLoop(True)

        self.colmusic = base.loader.loadSfx("sounds/collect.mp3")
        self.colmusic.setVolume(.65)

        # print the number of objects
        printNumObj(self.numObjects)

        # Post the instructions
        # self.title = addTitle("Roaming Ralph (Edited by Adam Gressen)")
        # self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        # self.inst2 = addInstructions(0.90, "[A]: Rotate Ralph Left")
        # self.inst3 = addInstructions(0.85, "[D]: Rotate Ralph Right")
        # self.inst4 = addInstructions(0.80, "[W]: Run Ralph Forward")
        # self.inst5 = addInstructions(0.75, "[S]: Run Ralph Backward")
        # self.inst6 = addInstructions(0.70, "[Space]: Run, Ralph, Run")

        # 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)
        self.environ.setPos(0, 0, 0)

        # Timer to increment in the move task
        self.time = 0

        # Get bounds of environment
        min, max = self.environ.getTightBounds()
        self.mapSize = max - min

        # Create the main character, Ralph
        self.ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor(
            "models/ralph", {
                "run": "models/ralph-run",
                "jump": "models/ralph-jump",
                "walk": "models/ralph-walk"
            })
        self.ralph.reparentTo(render)
        self.ralph.setScale(.30)
        self.ralph.setPos(self.ralphStartPos)
        #skate
        self.skate = loader.loadModel("models/Skateboard")
        self.skate.reparentTo(render)
        self.skate.setScale(.02)
        self.skate.setPos(-random.randint(38, 50), -random.randint(15, 37),
                          -0.015)
        # ralph's health
        self.health = 100

        #spring
        self.spring = loader.loadModel("models/spring")
        self.spring.reparentTo(render)
        self.spring.setScale(.8)
        self.spring.setPos(-random.randint(72, 78), -random.randint(10, 15),
                           6.715)
        # ralph's stamina
        self.stamina = 100

        # 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)

        # these don't work well in combination with the space bar
        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("arrow_down", self.setKey, ["backward", 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("arrow_down-up", self.setKey, ["backward", 0])

        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("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])

        # Game state variables
        self.isMoving = False
        self.isRunning = False
        self.onboard = 0
        self.boardtime = 0
        self.onspring = 0
        self.isjumping = False
        # Set up the camera
        base.disableMouse()
        #base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        base.camera.setPos(0, 0, 0)
        base.camera.reparentTo(self.ralph)
        base.camera.setPos(0, 40, 2)
        base.camera.lookAt(self.ralph)

        # 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.

        base.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 300)
        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()
        base.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        # camera ground collision handler
        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0, 0, 300)
        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()
        base.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # Place the health items
        self.placeHealthItems()

        # Place the collectibles
        self.placeCollectibles()

        # Place the bomb
        self.placebombItems()

        # Uncomment this line to show a visual representation of the
        # collisions occuring
        #base.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))
        #print self.startvar

        taskMgr.add(self.move, "moveTask")
        #taskMgr.doMethodLater(0.5, self.healthDec, "healthTask")

    # Display ralph's health
    def displayHealth(self):
        healthBar['scale'] = (self.health * 0.01 * BAR_WIDTH, 0.2, 0.2)

    # Display ralph's stamina
    def displayStamina(self):
        sprintBar['scale'] = (self.stamina * 0.01 * BAR_WIDTH, 0.2, 0.2)

    # Allow ralph to collect the health items
    def collectHealthItems(self, entry):
        # refill ralph's health
        self.colmusic.play()
        if (self.health < 100):
            self.health = self.health + 15.5
        # reposition the collectible
        self.placeItem(entry.getIntoNodePath().getParent())

    def collectCollectibles(self, entry):
        # remove the collectible
        #entry.getIntoNodePath().getParent().removeNode()
        self.colmusic.play()
        self.placeItem(entry.getIntoNodePath().getParent())
        # update the number of objects
        self.numObjects += 1
        #self.tot=10-self.numObjects
        printNumObj(self.numObjects)

    def blastbomb(self):
        # remove the collectible
        #self.placeItem(entry.getIntoNodePath().getParent())
        # blast
        self.fire = loader.loadModel("models/fire")
        self.fire.reparentTo(render)
        self.fire.setScale(.01)
        self.fire.setHpr(0, -90, 0)
        self.bombmusic.play()
        self.backmusic.stop()
        self.fire.setPos(self.ralph.getPos())
        self.die()

    # Places an item randomly on the map
    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(-40, 140), -random.randint(-40, 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 placeHealthItems(self):
        self.placeholder = render.attachNewNode("HealthItem-Placeholder")
        self.placeholder.setPos(0, 0, 0)

        # Add the health items to the placeholder node
        for i in range(5):
            # Load in the health item model
            self.healthy = loader.loadModel("models/sphere")
            self.healthy.setPos(0, 0, 0)
            self.healthy.setScale(.4)
            self.healthy.reparentTo(self.placeholder)

            self.placeItem(self.healthy)

            # Add spherical collision detection
            healthSphere = CollisionSphere(0, 0, 0, 1.4)
            sphereNode = CollisionNode('healthSphere')
            sphereNode.addSolid(healthSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.healthy.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

#bomb

    def placebombItems(self):
        self.placebomb = render.attachNewNode("bomb-Placeholder")
        self.placebomb.setPos(0, 0, 0)

        # Add the bomb items to the placeholder node
        for i in range(30):
            # Load in the health item model
            self.bomby = loader.loadModel("models/bomb")
            self.bomby.setPos(0, 0, 0)
            self.bomby.setScale(.4)
            self.bomby.reparentTo(self.placebomb)

            self.placeItem(self.bomby)

            # Add spherical collision detection
            bombSphere = CollisionSphere(0, 0, 0, 1.4)
            sphereNode = CollisionNode('bombSphere')
            sphereNode.addSolid(bombSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.bomby.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

#blue

    def placeCollectibles(self):
        self.placeCol = render.attachNewNode("Collectible-Placeholder")
        self.placeCol.setPos(0, 0, 0)

        # Add the health items to the placeCol node
        for i in range(50):
            # Load in the health item model
            self.collect = loader.loadModel("models/jack")
            self.collect.setPos(0, 0, 0)
            self.collect.setScale(.4)
            self.collect.reparentTo(self.placeCol)

            self.placeItem(self.collect)

            # Add spherical collision detection
            colSphere = CollisionSphere(0, 0, 0, 1.4)
            sphereNode = CollisionNode('colSphere')
            sphereNode.addSolid(colSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Makes ralph's health decrease over time

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):
        #print self.ralph.getPos()
        self.time += globalClock.getDt()
        timeText['text'] = str(self.time)

        # 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.
        # and rotate the camera to remain behind ralph
        if (self.keyMap["left"] != 0) and (self.onboard == 0):
            self.ralph.setH(self.ralph.getH() + 100 * globalClock.getDt())
        if (self.keyMap["right"] != 0) and (self.onboard == 0):
            self.ralph.setH(self.ralph.getH() - 100 * globalClock.getDt())
        if (self.keyMap["forward"] != 0) and (self.onboard == 0):
            self.ralph.setY(self.ralph, -45 * globalClock.getDt())
        if (self.keyMap["backward"] != 0) and (self.onboard == 0):
            self.ralph.setY(self.ralph, 45 * globalClock.getDt())
        if (self.keyMap["forward"] != 0) and (self.onboard
                                              == 0) and (self.onspring > 0):
            self.ralph.setY(self.ralph, -65 * globalClock.getDt())
        if (self.keyMap["backward"] != 0) and (self.onboard
                                               == 0) and (self.onspring > 0):
            self.ralph.setY(self.ralph, +65 * globalClock.getDt())

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
        if (self.isMoving):
            if (self.health <= 0):
                self.ralph.setPos(10000, 10000, 1000)
                self.ralph.stop()
                self.blastbomb()
            else:
                self.health -= .07

        if ((self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or
            (self.keyMap["right"] != 0) or
            (self.keyMap["backward"] != 0)) and (self.onboard == 0):
            if self.isMoving is False:
                self.ralph.loop("run")
                self.isMoving = True
        else:
            if self.isMoving and (self.onspring == 0):
                self.ralph.stop()
                self.ralph.pose("walk", 5)
                self.isMoving = False
#skate
        if (math.fabs(self.skate.getX() - self.ralph.getX()) <
                2) and (math.fabs(self.skate.getY() - self.ralph.getY()) <
                        5) and (self.onspring == 0) and (self.onboard == 0):
            self.onboard = 1
            self.ralph.stop()
            self.ralph.pose("walk", 5)
            self.isMoving = False
            self.isjumping = False
            self.skatemusic.play()

        if (self.onboard == 1):
            if (self.keyMap["left"] != 0):
                self.ralph.setH(self.ralph.getH() + 60 * globalClock.getDt())
                self.skate.setH(self.ralph.getH())
            if (self.keyMap["right"] != 0):
                self.ralph.setH(self.ralph.getH() - 60 * globalClock.getDt())
                self.skate.setH(self.ralph.getH())
            if (self.keyMap["forward"] != 0):
                self.ralph.setY(self.ralph, -100 * globalClock.getDt())
                self.skate.setY(self.ralph.getY())
                self.skate.setZ(self.ralph.getZ())
                self.skate.setX(self.ralph.getX())
            if (self.keyMap["backward"] != 0):
                self.ralph.setY(self.ralph, 100 * globalClock.getDt())
                self.skate.setY(self.ralph.getY())
                self.skate.setZ(self.ralph.getZ())
                self.skate.setX(self.ralph.getX())
            self.boardtime = self.boardtime + 1
            #self.ralph.stop()
            #self.ralph.pose("walk",5)
            #print self.onboard
            if (self.boardtime == 1000):
                self.onboard = 0
                self.boardtime = 0
                self.skate.setPos(-random.randint(72, 78),
                                  -random.randint(10, 15), 6.715)
                self.skatemusic.stop()
#spring

#spring
        if (math.fabs(self.spring.getX() - self.ralph.getX()) <
                2) and (math.fabs(self.spring.getY() - self.ralph.getY()) <
                        2) and (self.onboard == 0) and (self.onspring == 0):
            self.onspring = 500
            self.springmusic.play()
            self.spring.setPos(-random.randint(38, 50),
                               -random.randint(15, 37), -0.015)

        if (self.onspring > 0):
            self.onspring = self.onspring - 1
            #print self.onspring
            if (self.isjumping is False):
                self.ralph.loop("jump")
                self.isjumping = True
        else:
            #print self.ralph.getX()
            if self.isjumping:
                if ((self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0)
                        or (self.keyMap["right"] != 0)):
                    self.ralph.loop("run")
                    self.isMoving = True
                else:
                    self.ralph.stop()
                    self.ralph.pose("walk", 5)
                self.isjumping = False
                self.onspring = 0
                self.springmusic.stop()

        # so the following line is unnecessary
        base.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.
        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        if (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                   == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
            #base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+5)
        elif (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                     == "healthSphere"):
            self.collectHealthItems(entries[0])
        elif (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                     == "colSphere"):
            self.collectCollectibles(entries[0])
        elif (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                     == "bombSphere"):
            self.blastbomb()
        else:
            self.ralph.setPos(startpos)

        # Keep the camera above the terrain
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        if (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                   == "terrain"):
            modZ = entries[0].getSurfacePoint(render).getZ()
            base.camera.setZ(10.0 + modZ + (modZ - self.ralph.getZ()))

        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ() + 2.0)
        base.camera.lookAt(self.floater)

        self.displayHealth()

        return task.cont

    #  End
    def die(self):
        # end all running tasks
        self.ralph.setPos(10000, 10000, 10000)
        taskMgr.remove("moveTask")
        taskMgr.remove("healthTask")
        self.ralph.stop()
        self.skatemusic.stop()
        self.springmusic.stop()
        self.backmusic.stop()

        colObj = self.numObjects
        myscore = str(colObj)

        self.highscore = OkDialog(dialogName="highscoreDialog",
                                  text="Your Score: " + myscore,
                                  command=self.endResult)

    # Handle the dialog result

    def endResult(self, arg):
        sys.exit()

    def endbox(self, arg):
        if (arg):
            self.startvar = 1
            self.startdialog.cleanup()
            # restart the game
            #self.restart()
        else:
            sys.exit()
Exemplo n.º 44
0
class CogdoFlyingCameraManager:
    def __init__(self, cam, parent, player, level):
        self._toon = player.toon
        self._camera = cam
        self._parent = parent
        self._player = player
        self._level = level
        self._enabled = False

    def enable(self):
        if self._enabled:
            return
        self._toon.detachCamera()
        self._prevToonY = 0.0
        levelBounds = self._level.getBounds()
        l = Globals.Camera.LevelBoundsFactor
        self._bounds = ((levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]),
                        (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]),
                        (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2]))
        self._lookAtZ = self._toon.getHeight(
        ) + Globals.Camera.LookAtToonHeightOffset
        self._camParent = NodePath('CamParent')
        self._camParent.reparentTo(self._parent)
        self._camParent.setPos(self._toon, 0, 0, 0)
        self._camParent.setHpr(180, Globals.Camera.Angle, 0)
        self._camera.reparentTo(self._camParent)
        self._camera.setPos(0, Globals.Camera.Distance, 0)
        self._camera.lookAt(self._toon, 0, 0, self._lookAtZ)
        self._cameraLookAtNP = NodePath('CameraLookAt')
        self._cameraLookAtNP.reparentTo(self._camera.getParent())
        self._cameraLookAtNP.setPosHpr(self._camera.getPos(),
                                       self._camera.getHpr())
        self._levelBounds = self._level.getBounds()
        self._enabled = True
        self._frozen = False
        self._initCollisions()

    def _initCollisions(self):
        self._camCollRay = CollisionRay()
        camCollNode = CollisionNode('CameraToonRay')
        camCollNode.addSolid(self._camCollRay)
        camCollNode.setFromCollideMask(OTPGlobals.WallBitmask
                                       | OTPGlobals.CameraBitmask
                                       | ToontownGlobals.FloorEventBitmask
                                       | ToontownGlobals.CeilingBitmask)
        camCollNode.setIntoCollideMask(0)
        self._camCollNP = self._camera.attachNewNode(camCollNode)
        self._camCollNP.show()
        self._collOffset = Vec3(0, 0, 0.5)
        self._collHandler = CollisionHandlerQueue()
        self._collTrav = CollisionTraverser()
        self._collTrav.addCollider(self._camCollNP, self._collHandler)
        self._betweenCamAndToon = {}
        self._transNP = NodePath('trans')
        self._transNP.reparentTo(render)
        self._transNP.setTransparency(True)
        self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon)
        self._transNP.setBin('fixed', 10000)

    def _destroyCollisions(self):
        self._collTrav.removeCollider(self._camCollNP)
        self._camCollNP.removeNode()
        del self._camCollNP
        del self._camCollRay
        del self._collHandler
        del self._collOffset
        del self._betweenCamAndToon
        self._transNP.removeNode()
        del self._transNP

    def freeze(self):
        self._frozen = True

    def unfreeze(self):
        self._frozen = False

    def disable(self):
        if not self._enabled:
            return
        self._destroyCollisions()
        self._camera.wrtReparentTo(render)
        self._cameraLookAtNP.removeNode()
        del self._cameraLookAtNP
        self._camParent.removeNode()
        del self._camParent
        del self._prevToonY
        del self._lookAtZ
        del self._bounds
        del self._frozen
        self._enabled = False

    def update(self, dt=0.0):
        self._updateCam(dt)
        self._updateCollisions()

    def _updateCam(self, dt):
        toonPos = self._toon.getPos()
        camPos = self._camParent.getPos()
        x = camPos[0]
        z = camPos[2]
        toonWorldX = self._toon.getX(render)
        maxX = Globals.Camera.MaxSpinX
        toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX)
        spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / (
            maxX * maxX)
        newH = 180.0 + spinAngle
        self._camParent.setH(newH)
        spinAngle = spinAngle * (pi / 180.0)
        distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle)
        distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle)
        d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0])
        if abs(d) > Globals.Camera.LeewayX:
            if d > Globals.Camera.LeewayX:
                x = toonPos[0] + Globals.Camera.LeewayX
            else:
                x = toonPos[0] - Globals.Camera.LeewayX
        x = self._toon.getX(render) + distToRightOfToon
        boundToonZ = min(toonPos[2], self._bounds[2][1])
        d = z - boundToonZ
        if d > Globals.Camera.MinLeewayZ:
            if self._player.velocity[2] >= 0 and toonPos[
                    1] != self._prevToonY or self._player.velocity[2] > 0:
                z = boundToonZ + d * INVERSE_E**(dt *
                                                 Globals.Camera.CatchUpRateZ)
            elif d > Globals.Camera.MaxLeewayZ:
                z = boundToonZ + Globals.Camera.MaxLeewayZ
        elif d < -Globals.Camera.MinLeewayZ:
            z = boundToonZ - Globals.Camera.MinLeewayZ
        if self._frozen:
            y = camPos[1]
        else:
            y = self._toon.getY(render) - distBehindToon
        self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z))
        if toonPos[2] < self._bounds[2][1]:
            h = self._cameraLookAtNP.getH()
            if d >= Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ)
            elif d <= -Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._camParent, 0, 0,
                                            self._lookAtZ)
            self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0)
            self._camera.setHpr(
                smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr()))
        self._prevToonY = toonPos[1]

    def _updateCollisions(self):
        pos = self._toon.getPos(self._camera) + self._collOffset
        self._camCollRay.setOrigin(pos)
        direction = -Vec3(pos)
        direction.normalize()
        self._camCollRay.setDirection(direction)
        self._collTrav.traverse(render)
        nodesInBetween = {}
        if self._collHandler.getNumEntries() > 0:
            self._collHandler.sortEntries()
            for entry in self._collHandler.getEntries():
                name = entry.getIntoNode().getName()
                if name.find('col_') >= 0:
                    np = entry.getIntoNodePath().getParent()
                    if np not in nodesInBetween:
                        nodesInBetween[np] = np.getParent()

        for np in nodesInBetween.keys():
            if np in self._betweenCamAndToon:
                del self._betweenCamAndToon[np]
            else:
                np.setTransparency(True)
                np.wrtReparentTo(self._transNP)
                if np.getName().find('lightFixture') >= 0:
                    if not np.find('**/*floor_mesh').isEmpty():
                        np.find('**/*floor_mesh').hide()
                elif np.getName().find('platform') >= 0:
                    if not np.find('**/*Floor').isEmpty():
                        np.find('**/*Floor').hide()

        for np, parent in self._betweenCamAndToon.items():
            np.wrtReparentTo(parent)
            np.setTransparency(False)
            if np.getName().find('lightFixture') >= 0:
                if not np.find('**/*floor_mesh').isEmpty():
                    np.find('**/*floor_mesh').show()
            elif np.getName().find('platform') >= 0:
                if not np.find('**/*Floor').isEmpty():
                    np.find('**/*Floor').show()

        self._betweenCamAndToon = nodesInBetween
Exemplo n.º 45
0
class Labryn(DirectObject):

    def setCamera(self, spin):
        self.spin = spin
    
    def spinCamera(self, task):
        if self.spin == 1: # spin counter-clockwise
            self.cameraSpinCount += 1
            angleDegrees = self.cameraSpinCount
            angleRadians =  angleDegrees * (pi/ 180)
            self.CAM_RAD = angleRadians
            camera.setPos(_FOCUS[0]+self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1]+self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R) 
            camera.setHpr(angleDegrees,-65,0)
        elif self.spin == 2: # spin clockwise
            self.cameraSpinCount  -= 1
            angleDegrees = self.cameraSpinCount
            angleRadians =  angleDegrees * (pi/ 180)
            self.CAM_RAD = angleRadians
            camera.setPos(_FOCUS[0]+self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1]+self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R)
            camera.setHpr(angleDegrees,-65,0)
        elif self.spin == 3: # ZOOM IN not spin
            self.cameraZoomCount += 1
            deltaR = self.cameraZoomCount * 0.1
            new_R = 12-deltaR
            self.CAM_R = new_R
            camera.setPos(_FOCUS[0] + self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1] + self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*new_R)
        elif self.spin == 4: # ZOOM OUT
            self.cameraZoomCount -= 1
            deltaR = self.cameraZoomCount * 0.1
            new_R = 12-deltaR
            self.CAM_R = new_R
            camera.setPos(_FOCUS[0] + self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1] + self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R)
                          
        return Task.cont

    def checkMouse(self, task):
        if base.mouseWatcherNode.hasMouse():
            self.mouseX=base.mouseWatcherNode.getMouseX()
            self.mouseY=base.mouseWatcherNode.getMouseY()
        return Task.cont

    def dropRock(self):
        if self.pokeMoveChoice == 1: # selected Geodude
            result = MAZE.canDropRock(self.rockX, self.rockY)
            if result != False: # can place rock here
                MAZE.dropRock(result[0],result[1])
                self.rock.setPos(self.rockX, self.rockY, 1)
                self.rockOnMaze = True
                self.pokeMoveChoice = None
                self.myPokeName.hide()
                self.myPokeName = None
                self.updateTwoD()
                self.playerCandyCount -= 1

    def useFlame(self):
        self.onFire = True # on fire
        self.playerCandyCount -= 1
        self.pokeStatus = 1
        self.flame = ParticleEffect()
        self.flame.loadConfig("fireish.ptf")
        self.flame.setPos(self.pikachu.getPos())
        self.flame.start(parent=render, renderParent=render)
        self.updateTwoD()

    def useStringShot(self):
        self.pokeStatus = 2
        self.updateTwoD()

    def placeRock(self, task):
        if self.pokeMoveChoice == 1: # selected Geodude
            dX,dY = ((self.mouseX-self.rockRefX),
                     (self.mouseY-self.rockRefY))
            self.rockX, self.rockY = MAZE.translateRockPosition(self.rockRefX,
                                                      self.rockRefY,
                                                      dX, dY)
            self.rock.show()
            self.rock.setPos(self.rockX, self.rockY, 1)
        self.updateTwoD()
        return Task.cont
    
    def placeRareCandy(self, task):
        if int(task.time) % 4 == 9 and self.candyOnBoard:
            self.candy.hide()
            self.candyOnBoard = False
        if int(task.time) % 10 ==  0 and (self.candyOnBoard == False):
            # every 10 seconds
            self.candy.setPos(MAZE.generateCandyPos())
            self.candy.show()
            self.candyOnBoard = True
        return Task.cont

    def updateTwoD(self):
        # update player candy count
        self.playerCandyStatus.destroy()
        self.playerCandyStatus = candyStatus(0, self.playerCandyCount)
        # update pikachu candy count
        # TODO
        # update my pokes color     
        if self.playerCandyCount == 0 :
            groupHide(self.myPokesBright)
            groupShow(self.myPokesDark)
            # update name
            if self.myPokeName != None:
                self.myPokeName.destroy()

    def clearRock(self):
        self.rock.hide()
        self.rockOnMaze = False
        MAZE.clearRock() # clear it in 2D

    def clearFlame(self):
        self.onFire = False
        self.flame.cleanup()
        self.pokeStatus = 0
        self.pokeMoveChoice = None
        try:
            self.myPokeName.destroy()
        except:
            pass
        self.myPokeName = None

    def clearString(self):
        self.pokeStatus = 0
        self.pokeMoveChoice = None
        try:
            self.myPokeName.destroy()
        except:
            pass
        self.myPokeName = None

        
    def timer(self, task): # deals with moves' lasting effects
        ##############################################################
        if self.rockOnMaze: # rock on maze
            self.rockCounter += 1
        elif self.rockCounter != 1: # rock not on maze, counter not cleared
            self.rockCounter = 0

        if self.onFire:
            self.fireCounter += 1
        elif self.fireCounter != 1:
            self.fireCounter = 0

        if self.pokeStatus == 2: # string shot
            self.stringCounter += 1
        elif self.stringCounter != 1:
            self.stringCounter = 0

        ##################################################################
        if self.rockCounter == 500:
            self.clearRock()

        if self.fireCounter == 80:
            self.clearFlame()

        if self.stringCounter == 120:
            self.clearString()
            
        return Task.cont
    
    def usePokeMove(self, number):
        if self.playerCandyCount > 0: # have more than one candy
            if number == 1 and self.rockOnMaze == False:
                if self.pokeMoveChoice != 1: # NONE or other
                    # set to center position
                    centerx =  base.win.getProperties().getXSize()/2
                    centery =  base.win.getProperties().getYSize()/2
                    base.win.movePointer(0,centerx,centery)
                    self.pokeMoveChoice = 1 # placeRock called here
                    self.rockRefX, self.rockRefY = 0,0
                    self.rock.show()
                    self.rock.setPos(0,0,1)
                else: # already 1
                    self.pokeMoveChoice = None
                    self.clearRock() # clear rock
            elif number == 2:
                if self.pokeMoveChoice != 2:
                    self.pokeMoveChoice = 2
                    self.useFlame()
                else:
                    self.pokeMoveChoice = None
            elif number == 3:
                if self.pokeMoveChoice != 3:
                    self.pokeMoveChoice = 3
                    self.useStringShot()
                else:
                    self.pokeMoveChoice = None
            if self.pokeMoveChoice == None: # no choice
                if self.myPokeName != None: # there is a name on board
                    self.myPokeName.destroy() # kill it
                else: # no name
                    pass
            else: # there is a choice
                if self.myPokeName != None:
                    self.myPokeName.destroy()
                self.myPokeName = Two_D.writePokeName(self.pokeMoveChoice)
  
    def loadRareCandy(self):
        self.candy = Model_Load.loadRareCandy()
        self.candy.reparentTo(render)
        self.candy.setScale(0.1)
        self.candy.hide()
        
    def eatRareCandy(self, task):
        if self.candyOnBoard: # candy on board
            if checkEat(self.ballRoot.getX(), self.ballRoot.getY(),
                        self.candy.getX(), self.candy.getY()): # ball eats
                self.candy.hide() # eaten
                self.candyOnBoard = False
                self.playerCandyCount += 1
                # self.playerCandyStatus.destroy()
                # self.playerCandyStatus = candyStatus(0,
                                       # self.playerCandyCount) # update
                print "BALL EATS CANDY"
                groupShow(self.myPokesBright)

            elif checkEat(self.pikachu.getX(), self.pikachu.getY(),
                          self.candy.getX(), self.candy.getY()):
                self.candy.hide()
                self.candyOnBoard = False
                self.pokemonCandyCount += 1
        return Task.cont

    def setFocus(self, changing):
        self.changingFocus = changing
        if changing == True: # Just Pressed
            self.referenceX, self.referenceY = self.mouseX, self.mouseY
        else: # cursor moves up
            self.referenceX, self.referenceY = None, None

    def resetView(self):
        self.CAM_R, self.CAM_RAD = 12, 0
        self.cameraSpinCount, self.cameraZoomCount = 0, 0
        # _FOCUS = [0,0,0] does not work WHY???
        _FOCUS[0], _FOCUS[1], _FOCUS[2] = 0,0,0
        self.changingFocus = False
        self.referenceX, self.referenceY = None, None
        camera.setPos(_FOCUS[0], _FOCUS[1]-self.CAM_R, 25)
        camera.setHpr(0, -65, 0)
        
    def changeFocus(self, task):
        if (self.changingFocus == True and self.mouseX != None and
            self.mouseY != None ):
            dX, dY = ((self.mouseX - self.referenceX)*0.1,
                      (self.mouseY - self.referenceY)*0.1)
            _FOCUS[0] += dX
            _FOCUS[1] += dY
            camera.setPos(_FOCUS[0] + self.CAM_R*cos(-pi/2+self.CAM_RAD),
                          _FOCUS[1] + self.CAM_R*sin(-pi/2+self.CAM_RAD),
                          (25.0/12)*self.CAM_R)
        return Task.cont

    def initialize(self):
        #bgmusic = load_bgmusic("palette.mp3")
        #bgmusic.play()

        self.background = Two_D.loadBackground()
        base.cam2dp.node().getDisplayRegion(0).setSort(-20)
        self.candyOnBoard = False
        self.playerCandyCount, self.pokemonCandyCount = 2, 0
        ######################Rare Candy###############################
        pokes=['caterpie', 'charmander', 'geodude']
        self.myPokesDark = Two_D.loadMyPokemon_Dark(pokes) # my pokemons
        self.myPokesBright = Two_D.loadMyPokemon_Bright()
        groupHide(self.myPokesBright)
        self.loadRareCandy() # load rare candy
        ######################Camera Initialization####################
        self.CAM_R, self.CAM_RAD = 12, 0
        camera.setPos(_FOCUS[0],_FOCUS[1]-12,_FOCUS[2]+25)
        camera.setHpr(0, -65, 0)
        self.cameraSpinCount, self.cameraZoomCount = 0, 0
        self.changingFocus = False
        self.spin = 0
        #######################ICONS###################################
        self.myIcon = Two_D.loadMyIcon()
        self.pokeIcon = Two_D.loadPokeIcon()
        self.playerCandyStatus = candyStatus(0, self.playerCandyCount)
        #######################FLAMES##################################
        base.enableParticles()
        self.fireCounter = 0
        self.onFire = False
        #######################STRINGSHOT#############################
        self.stringCounter = 0
        #######################GLOBALS#################################
        self.i = 0
        self.myDirection = ['zx', 'zy']
        self.rockCounter  = 0
        self.rockX, self.rockY = None, None
        self.rockOnMaze = False
        self.pokeMoveChoice = None
        self.myPokeName = None
        self.arrowKeyPressed = False
        self.pokemonDirection = 'd'
        self.mouseX, self.mouseY = None, None
        # direction the ball is going
        self.jerkDirection = None
        base.disableMouse()
        self.jerk = (0,0,0)
        self.MAZE = Model_Load.loadLabyrinth()
        Control.keyControl(self)
        self.loadPokemonLevel1()
        self.light()
        self.loadBall()
        self.pokeStatus = 0 # 0 is normal, 1 is burned, 2 is slow-speed
        ########################################ROCK###################
        self.rock = Model_Load.loadRock()
        self.rock.reparentTo(render)
        self.rock.hide() # Do not show, but load beforehand for performance
        
    def loadPokemonLevel1(self):
        self.pikachu = load_model("pikachu.egg")
        self.pikachu.reparentTo(render)
        self.pikachu.setScale(0.3)
        endPos = self.MAZE.find("**/end").getPos()
        self.pikachu.setPos(endPos) 
        
    def light(self):
        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))

    def loadBall(self):
        self.ballRoot = render.attachNewNode("ballRoot")
        self.ball = load_model("ball")
        self.ball.reparentTo(self.ballRoot)
        self.ball_tex = load_tex("pokeball.png")
        self.ball.setTexture(self.ball_tex,1)
        self.ball.setScale(0.8)
        # Find the collision sphere for the ball in egg.
        self.ballSphere = self.ball.find("**/ball")
        self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
        self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())
        #self.ballSphere.show()
        # Now we create a ray to cast down at the ball.
        self.ballGroundRay = CollisionRay()
        self.ballGroundRay.setOrigin(0,0,10)
        self.ballGroundRay.setDirection(0,0,-1)

        # Collision solids go in CollisionNode
        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)
        
        # light
        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))
        # material to the ball
        m = Material()
        m.setSpecular(Vec4(1,1,1,1))
        m.setShininess(96)
        self.ball.setMaterial(m,1)

    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 pokemonTurn(self, pokemon, direction):
        if direction  == 'l' and self.pokemonDirection != 'l':
            self.pokemonDirection = 'l'
            pokemon.setH(-90)
        if direction  == 'r' and self.pokemonDirection != 'r':
            self.pokemonDirection = 'r'
            pokemon.setH(90)
        if direction  == 'd' and self.pokemonDirection != 'd':
            self.pokemonDirection = 'd'
            pokemon.setH(0)
        if direction  == 'u' and self.pokemonDirection != 'u':
            self.pokemonDirection = 'u'
            pokemon.setH(180)
                        
    def pokemonMove(self, pokemon, direction):
        self.pokemonTurn(pokemon, direction)
        if self.pokeStatus == 0: speed = _SPEED
        elif self.pokeStatus == 1: speed = 0
        else: # self.pokeStatus == 2
            speed = _SPEED/2.0
        if direction == 'l':
            newX = pokemon.getX() - speed
            pokemon.setX(newX)
        elif direction == 'r':
            newX = pokemon.getX() + speed
            pokemon.setX(newX)
        elif direction == 'u':
            newY = pokemon.getY() + speed
            pokemon.setY(newY)
        elif direction == 'd':
            newY = pokemon.getY() - speed
            pokemon.setY(newY)
        elif direction == "s": # stop
            pass
        
    def whereToGo(self, task):
        # this returns the direction pokemon should go
        # tell MAZE pokemon and ball's board position
        print self.myDirection
        MAZE.setPokeCoord(self.pikachu.getX(), self.pikachu.getY(),
                          self.pokemonDirection)
        MAZE.setBallCoord(self.ballRoot.getX(), self.ballRoot.getY())
        # find out which direction to go
        direction = MAZE.getDecision()
        self.pokemonMove(self.pikachu,direction)
        return Task.cont

    def getInformation(self, task):
        # get information on the board
        # TODO
        self.i += 1 # sample every other call to avoid 
        if self.i % 2 == 0:
            dX = self.ballRoot.getX() - self.oldPos[0]
            dY = self.ballRoot.getY() - self.oldPos[1]
            if dX < 0 :
                # print "going left"
                self.myDirection[0] = 'l'
            elif abs(dX) < _EPSILON:
                # print "not moving horiz"
                self.myDirection[0] = 'zx'
            else:
                # print "going right"
                self.myDirection[0] = 'r'

            if dY < 0 :
                # print "going down"
                self.myDirection[1] = 'd'
            elif abs(dY) < _EPSILON:
                # print "not moving verti"
                self.myDirection[1] = 'zy'
            else:
                # print "going up"
                self.myDirection[1] = 'u'
            self.oldPos = self.ballRoot.getPos()
        return Task.cont
    
    def start(self):
        # maze model has a locator in it
        # self.ballRoot.show()
        self.startPos = self.MAZE.find("**/start").getPos()
        self.oldPos = self.MAZE.find("**/start").getPos()
        self.ballRoot.setPos(self.startPos) # set the ball in the pos
        self.ballV = Vec3(0,0,0) # initial velocity
        self.accelV = Vec3(0,0,0) # initial acceleration

        # for a traverser to work, need to call traverser.traverse()
        # base has a task that does this once a frame
        base.cTrav = self.cTrav

        # create the movement task, make sure its not already running
        taskMgr.remove("rollTask")
        taskMgr.add(self.placeRock, "placeRock")
        taskMgr.add(self.timer, "timer")
        taskMgr.add(self.getInformation, "getInformation")
        taskMgr.add(self.eatRareCandy, "eatRareCandy")
        taskMgr.add(self.placeRareCandy, "placeRareCandy")
        taskMgr.add(self.checkMouse, "checkMouse")
        taskMgr.add(self.spinCamera, "spinCamera")
        taskMgr.add(self.changeFocus, "changeFocus")
        taskMgr.add(self.whereToGo, "whereToGo")
        # taskMgr.add(lambda task: self.moveBall(task, self.jerkDirection),
                    # "moveBall")
        taskMgr.add(self.moveBall, "moveBall")
        self.mainLoop = taskMgr.add(self.rollTask, "rollTask")
        self.mainLoop.last = 0

    def moveBallWrapper(self, direction):
        if direction == False:
            self.arrowKeyPressed = False
        else:
            self.arrowKeyPressed = True
            self.jerkDirection = direction
    
    def moveBall(self, task):
        direction = self.jerkDirection
        if self.arrowKeyPressed == True:
            if direction == "u":
                self.jerk = Vec3(0,_JERK,0)
            elif direction == "d":
                self.jerk = Vec3(0,-_JERK,0)
            elif direction == "l":
                self.jerk = Vec3(-_JERK,0,0)
            elif direction == "r":
                self.jerk = Vec3(_JERK,0,0)
        return Task.cont        
    """      
    def moveBall(self, task, direction):
        if self.arrowKeyPressed == True:
            if direction == "u":
                self.jerk = Vec3(0,_JERK,0)
            elif direction == "d":
                self.jerk = Vec3(0,-_JERK,0)
            elif direction == "l":
                self.jerk = Vec3(-_JERK,0,0)
            elif direction == "r":
                self.jerk = Vec3(_JERK,0,0)
        return Task.cont
    """       
    # collision between ray and ground
    # info about the interaction is passed in colEntry
    
    def groundCollideHandler(self,colEntry):
        # set the ball to the appropriate Z for it to be on the ground
        newZ = colEntry.getSurfacePoint(render).getZ()
        self.ballRoot.setZ(newZ+.4)

        # up vector X normal vector
        norm = colEntry.getSurfaceNormal(render)
        accelSide = norm.cross(UP)
        self.accelV = norm.cross(accelSide)

    # collision between the ball and a wall
    def wallCollideHandler(self,colEntry):
        # some vectors needed to do the calculation
        norm = colEntry.getSurfaceNormal(render) * -1
        norm.normalize()
        curSpeed = self.ballV.length()
        inVec = self.ballV/curSpeed
        velAngle = norm.dot(inVec) # angle of incidance
        hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
        hitDir.normalize()
        hitAngle = norm.dot(hitDir)
    # deal with collision cases

        if velAngle > 0 and hitAngle >.995:
            # standard reflection equation
            reflectVec = (norm * norm.dot(inVec*-1)*2) + inVec

            # makes velocity half of hitting dead-on
            self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5))

            # a collision means the ball is already a little bit buried in
            # move it so exactly touching the wall
            disp = (colEntry.getSurfacePoint(render) -
                    colEntry.getInteriorPoint(render))
            newPos = self.ballRoot.getPos() + disp
            self.ballRoot.setPos(newPos)
            
    def rollTask(self,task):
        # 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 is a HICCUP
        # ignore the frame
        if dt > .2: return Task.cont

        # dispatch which function to handle the collision based on name
        for i in range(self.cHandler.getNumEntries()):
            entry = self.cHandler.getEntry(i)
            name = entry.getIntoNode().getName()
       
            if name == "Wall.004":
                self.wallCollideHandler(entry)
            elif name=="Cube.004":
                self.groundCollideHandler(entry)
            else: 
                if self.rockOnMaze == True:
                    self.wallCollideHandler(entry)
        self.accelV += self.jerk
        # move the ball, update the velocity based on accel
        self.ballV += self.accelV * dt * ACCELERATION
        # clamp the velocity to the max speed
        if self.ballV.lengthSquared() > MAX_SPEED_SQ:
            self.ballV.normalize()
            self.ballV *= MAX_SPEED
        # update the position
        self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV*dt))

        # uses quaternion to rotate the ball
        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
Exemplo n.º 46
0
class MousePicker(object):
    def __init__(self, pickTag="MyPickingTag", nodeName="pickRay", showCollisions=False):
        self.pickTag = pickTag
        self.nodeName = nodeName
        self.showCollisions = showCollisions

    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 mousePick(self, traverse=None, tag=None):
        # do we have a mouse
        if base.mouseWatcherNode.hasMouse() == False:
            return None, None

        traverse = traverse or base.render
        tag = tag or self.pickTag

        mpos = base.mouseWatcherNode.getMouse()

        # Set the position of the ray based on the mouse position
        self.mPickRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
        self.mPickerTraverser.traverse(traverse)

        if self.mCollisionQue.getNumEntries() > 0:
            self.mCollisionQue.sortEntries()

            for entry in self.mCollisionQue.getEntries():
                pickedObj = entry.getIntoNodePath()
                pickedObj = pickedObj.findNetTag(tag)

                if not pickedObj.isEmpty():
                    pos = entry.getSurfacePoint(base.render)
                    return pickedObj, pos

        return None, None

    def mousePick2D(self, traverse=None, tag=None, all=False):
        # do we have a mouse
        if base.mouseWatcherNode.hasMouse() == False:
            return None, None

        traverse = traverse or base.render
        tag = tag or self.pickTag

        mpos = base.mouseWatcherNode.getMouse()

        self.mPickRay2D.setFromLens(base.cam2d.node(), mpos.getX(), mpos.getY())

        self.mPickerTraverser2D.traverse(base.aspect2d)

        if self.mCollisionQue2D.getNumEntries() > 0:
            self.mCollisionQue2D.sortEntries()

            if all:
                return (
                    [
                        (entry.getIntoNodePath().findNetTag(tag), entry.getSurfacePoint(base.aspect2d))
                        for entry in self.mCollisionQue2D.getEntries()
                    ],
                    None,
                )
            else:
                entry = self.mCollisionQue2D.getEntry(0)
                pickedObj = entry.getIntoNodePath()

                pickedObj = pickedObj.findNetTag(tag)
                if not pickedObj.isEmpty():
                    pos = entry.getSurfacePoint(base.aspect2d)
                    return pickedObj, pos

        return None, None
class RoamingPenguinDemo(ShowBase):
    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,
        }

    

        ###########################################################################

        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)
        self.setBackgroundColor(.1, .1, .1, 1)
        # Create the main character, person

        #personStartPos = self.environ.find("**/start_point").getPos()
        #self.person = Actor("models/panda",
         #                  {"run": "models/panda-walk",
          #                  "walk": "models/panda-walk"})

        person2StartPos = self.environ.find("**/start_point").getPos()
        self.person2 = Actor("models/passenger_penguin",
                           {"run": "models/passenger_penguin",
                            "walk": "models/passenger_penguin"})

       
        self.person2.reparentTo(render)
        self.person2.setScale(.1)
   
        self.person2.setPos(person2StartPos + (px, py, 1))


        person3StartPos = self.environ.find("**/start_point").getPos()
        self.person3 = Actor("models/MagicBunny",
                           {"run": "models/MagicBunny",
                            "walk": "models/MagicBunny"})

        #px = random.randint(-1,1)
        #py = random.randint(-1,1)


        self.person3.reparentTo(render)
        self.person3.setScale(.04)
        #self.person.setPos(personStartPos + (0, 0, 2))
        self.person3.setPos(person3StartPos + (px/1.5+3, py/2, 0))

        personStartPos = self.environ.find("**/start_point").getPos()
        self.person = Actor("models/panda",
                           {"run": "models/panda-walk",
                            "walk": "models/panda-walk"})


        self.person.reparentTo(render)
        self.person.setScale(.1)
        self.person.setPos(personStartPos + (0, 0, 1.5))
        self.person.loop("run")


        arenaStartPos = self.environ.find("**/start_point").getPos()
        self.arena = Actor("models/FarmHouse")


        self.arena.reparentTo(render)
        self.arena.setScale(.1)
        self.arena.setPos(arenaStartPos + (-1, 0, 0))


        arena2StartPos = self.environ.find("**/start_point").getPos()
        self.arena2 = Actor("models/fence")


        self.arena2.reparentTo(render)
        self.arena2.setScale(5.9)
        self.arena.setPos(arenaStartPos + (px, py-12, 1))
        self.arena2.setPos(arenaStartPos + (8, 5, -1))


        arena2StartPos = self.environ.find("**/start_point").getPos()
        self.arena3 = Actor("models/gate")


        self.arena3.reparentTo(render)
        self.arena3.setScale(.01)

        self.arena3.setPos(arenaStartPos + (px/2+random.randint(12,15), py/2, -1))

        self.arena4 = Actor("models/FarmHouse")
        self.arena4.reparentTo(render)
        self.arena4.setScale(.1)

        self.arena4.setPos(arenaStartPos + (px/3-random.randint(18,22), py/3, -1))


        self.arena5 = Actor("models/gate")
        self.arena5.reparentTo(render)
        self.arena5.setScale(.008)

        self.arena5.setPos(arenaStartPos + (px/1.2-9, py/1.2, -1))

        #####################################################################################################################################
        base.enableParticles()
        self.t = loader.loadModel("teapot") # for the particle enhancer
        self.t.setScale(10)
        self.t.setPos(-10, -20, -1)
        self.t.reparentTo(render)
        #self.setupLights()
        self.p = ParticleEffect()
        self.p.setScale(1000)
        self.loadParticleConfig('smoke.ptf') # looks like a storm at night
        self.p.setScale(20)




        #################################################3

        # Create a floater object, which floats 2 units above person.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.person)
        self.floater.setZ(2.0)

        # Accept the control keys for movement and rotation


        taskMgr.add(self.move, "moveTask")

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.person.getX(), self.person.getY() + 10, 2)

        self.cTrav = CollisionTraverser()

    
        self.personCol = CollisionNode('person')
        self.personCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5))
        self.personCol.addSolid(CollisionSphere(center=(0, -0.25, 4), radius=1.5))
        self.personCol.setFromCollideMask(CollideMask.bit(0))
        self.personCol.setIntoCollideMask(CollideMask.allOff())
        self.personColNp = self.person.attachNewNode(self.personCol)
        self.personPusher = CollisionHandlerPusher()
        self.personPusher.horizontal = True

        self.personPusher.addCollider(self.personColNp, self.person)
        self.cTrav.addCollider(self.personColNp, self.personPusher)

        
        self.personGroundRay = CollisionRay()
        self.personGroundRay.setOrigin(0, 0, 9)
        self.personGroundRay.setDirection(0, 0, -1)
        self.personGroundCol = CollisionNode('personRay')
        self.personGroundCol.addSolid(self.personGroundRay)
        self.personGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.personGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.personGroundColNp = self.person.attachNewNode(self.personGroundCol)
        self.personGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.personGroundColNp, self.personGroundHandler)

        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)

       
   

        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, .2))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((.2, .2, .2, 1))
        directionalLight.setSpecularColor((.1, .1, .1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def loadParticleConfig(self, filename):
        # Start of the code from steam.ptf
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))
    
        self.p.start(self.t)
        self.p.setPos(3.000, 0.000, 2.250)




    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value


    def move(self, task):

      
        dt = globalClock.getDt()
       

        #z = abs(py)
        self.person.setX(self.person, 4 * dt)
        self.person.setX(self.person, -4 * dt)

        ## this is how the Panda finds his friend

        if px < 0 :
            #if self.person.getPos() - self.person2.getPos() < (0, 0, 0) :
            if self.person.getY() - self.person2.getY() < 6 :
            #self.person.getPos(personStartPos + (0, py, 1.5))
                self.person.setY(self.person, 0 * dt)
                self.person.stop()
                self.person.pose("walk", 5)
                self.isMoving = False
            else:
                self.person.setY(self.person, py * dt)
                self.person.setX(self.person, px * dt)
                self.person.setH(self.person, px/(abs(px)+6)* dt)
        else:
            if self.person.getY() - self.person2.getY() < 6 :
            #self.person.getPos(personStartPos + (0, py, 1.5))
                self.person.setY(self.person, 0 * dt)
                self.person.stop()
                self.person.pose("walk", 5)
                self.isMoving = False
            else:
                self.person.setY(self.person, py * dt)
                self.person.setX(self.person, px * dt)
                self.person.setH(self.person, px/(abs(px)+6)* dt)


        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

       
        camvec = self.person.getPos() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

    

        entries = list(self.personGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.person.setZ(entry.getSurfacePoint(render).getZ())

     

        entries = list(self.camGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.camera.setZ(entry.getSurfacePoint(render).getZ() + 3.5)
        if self.camera.getZ() < self.person.getZ() + 4.0:
            self.camera.setZ(self.person.getZ() + 4.0)

       
        self.camera.lookAt(self.floater)

        return task.cont
Exemplo n.º 48
0
class World(DirectObject):
    def __init__(self):
        ## Add the default values to the dictionary.
        self.keyMap = {"left":0, "right":0, "forward":0, \
                       "boost":0, "strafeL":0, "strafeR":0, \
                       "cam-left":0, "cam-right":0}

        base.win.setClearColor(Vec4(0, 0, 0, 1))
        self.jump = False
        self.jumped = False

        # Post the instructions
        self.title = addTitle(
            "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[D]: Rotate Camera Right")
        self.inst8 = addInstructions(0.60, "[B]: Ralph Boost")
        self.inst9 = addInstructions(0.55, "[V]: Strafe Left")
        self.inst10 = addInstructions(0.50, "[N]: Strafe 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)
        self.environ.setPos(0, 0, 0)

        ## Stops the sound as soon as the world renders
        ## Note:Sound won't play very long becasue the game takes seconds to compile and load
        ## Remove loading screen after world is rendered and ready to go.

        loadingText.cleanup()
        mySound.stop()

        # 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)

        # 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("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("d", self.setKey, ["cam-right", 1])
        self.accept("b", self.setKey, ["boost", 1])
        self.accept("v", self.setKey, ["strafeL", 1])
        self.accept("n", self.setKey, ["strafeR", 1])

        ## -up to signify what happens when you let go of the key
        self.accept("b-up", self.setKey, ["boost", 0])
        self.accept("v-up", self.setKey, ["strafeL", 0])
        self.accept("n-up", self.setKey, ["strafeR", 0])
        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("d-up", self.setKey, ["cam-right", 0])

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera

        base.disableMouse()
        base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)

        # 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

    def setZ(self, task):
        x = self.ralph.getX()
        y = self.ralph.getY()
        z = self.ralph.getZ()
        self.ralph.setPos(x, y, 0)
        self.jumped = False

    # 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, -50 * globalClock.getDt())

        # Increased camera rotation speed to match rotation speed of Ralph
        if (self.keyMap["cam-right"] != 0):
            base.camera.setX(base.camera, +50 * 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())
        if (self.keyMap["right"] != 0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"] != 0):
            self.ralph.setY(self.ralph, -25 * globalClock.getDt())
        ## What to do if b was pressed?
        if (self.keyMap["boost"] != 0):
            self.jump = True

        # What to do if n is pressed
        # Ralph will strafe right. If b is also pressed, Ralph will strafe to the right quicker
        if (self.keyMap["strafeR"] != 0):
            self.ralph.setX(self.ralph, -25 * globalClock.getDt())
        if (self.keyMap["strafeL"] != 0):
            self.ralph.setX(self.ralph, 25 * globalClock.getDt())

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        # Function to make Ralph jump up the y-axis and fall back down
        # when 'j' is released

        ## Add boost, strafeL, and strafeR to the animation alteration conditions here.
        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) \
           or (self.keyMap["right"]!=0) or (self.keyMap["boost"]!=0) \
           or (self.keyMap["strafeL"]!=0) or (self.keyMap["strafeR"]!=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)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        if (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                   == "terrain"):
            if self.jump is True:
                self.ralph.setZ(entries[0].getSurfacePoint(render).getZ() + 1)
                self.jumped = True
                self.jump = False
            else:
                if self.jumped is True:
                    taskMgr.doMethodLater(0.1, self.setZ, 'setZ')
                else:
                    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)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        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
Exemplo n.º 49
0
class RoamingRalphDemo(CosmoniumBase):

    def get_local_position(self):
        return base.camera.get_pos()

    def create_terrain_appearance(self):
        self.terrain_appearance.set_shadow(self.shadow_caster)

    def create_terrain_heightmap(self):
        self.heightmap = PatchedHeightmap('heightmap',
                                          self.noise_size,
                                          self.height_scale,
                                          self.size,
                                          self.size,
                                          True,
                                          ShaderHeightmapPatchFactory(self.noise))

    def create_terrain_biome(self):
        self.biome = PatchedHeightmap('biome',
                                      self.biome_size,
                                      1.0,
                                      self.size,
                                      self.size,
                                      False,
                                      ShaderHeightmapPatchFactory(self.biome_noise))

    def create_terrain_shader(self):
#         control4 = HeightColorMap('colormap',
#                 [
#                  ColormapLayer(0.00, top=LRGBColor(0, 0.1, 0.24)),
#                  ColormapLayer(0.40, top=LRGBColor(0, 0.1, 0.24)),
#                  ColormapLayer(0.49, top=LRGBColor(0, 0.6, 0.6)),
#                  ColormapLayer(0.50, bottom=LRGBColor(0.9, 0.8, 0.6), top=LRGBColor(0.5, 0.4, 0.3)),
#                  ColormapLayer(0.80, top=LRGBColor(0.2, 0.3, 0.1)),
#                  ColormapLayer(0.90, top=LRGBColor(0.7, 0.6, 0.4)),
#                  ColormapLayer(1.00, bottom=LRGBColor(1, 1, 1), top=LRGBColor(1, 1, 1)),
#                 ])
        appearance = DetailMap(self.terrain_control, self.heightmap, create_normals=True)
        data_source = [HeightmapDataSource(self.heightmap, PatchedGpuTextureSource, filtering=HeightmapDataSource.F_none),
                       HeightmapDataSource(self.biome, PatchedGpuTextureSource, filtering=HeightmapDataSource.F_none),
                       TextureDictionaryDataSource(self.terrain_appearance, TextureDictionaryDataSource.F_hash)]
        if settings.allow_tesselation:
            tesselation_control = ConstantTesselationControl(invert_v=False)
        else:
            tesselation_control = None
        if self.fog is not None:
            after_effects = [Fog(**self.fog)]
        else:
            after_effects = None
        self.terrain_shader = BasicShader(appearance=appearance,
                                          tesselation_control=tesselation_control,
                                          geometry_control=DisplacementGeometryControl(self.heightmap),
                                          data_source=data_source,
                                          after_effects=after_effects)

    def create_tile(self, x, y):
        self.terrain_shape.add_root_patch(x, y)

    def create_terrain(self):
        self.tile_factory = TileFactory(self.tile_density, self.size, self.has_water, self.water)
        self.terrain_shape = TiledShape(self.tile_factory, self.size, self.max_lod, lod_control=VertexSizeMaxDistancePatchLodControl(self.max_distance, self.max_vertex_size))
        self.create_terrain_heightmap()
        self.create_terrain_biome()
        self.create_terrain_appearance()
        self.create_terrain_shader()
        self.terrain = HeightmapSurface(
                               'surface',
                               0,
                               self.terrain_shape,
                               self.heightmap,
                               self.biome,
                               self.terrain_appearance,
                               self.terrain_shader,
                               self.size,
                               clickable=False,
                               average=True)
        self.terrain.set_parent(self)
        self.terrain.create_instance()

    def toggle_water(self):
        if not self.has_water: return
        self.water.visible = not self.water.visible
        self.terrain_shape.check_settings()

    def get_height(self, position):
        height = self.terrain.get_height(position)
        if self.has_water and self.water.visible and height < self.water.level:
            height = self.water.level
        return height

    #Used by populator
    def get_height_patch(self, patch, u, v):
        height = self.terrain.get_height_patch(patch, u, v)
        if self.has_water and self.water.visible and height < self.water.level:
            height = self.water.level
        return height

    def skybox_init(self):
        skynode = base.cam.attachNewNode('skybox')
        self.skybox = loader.loadModel('ralph-data/models/rgbCube')
        self.skybox.reparentTo(skynode)

        self.skybox.setTextureOff(1)
        self.skybox.setShaderOff(1)
        self.skybox.setTwoSided(True)
        # make big enough to cover whole terrain, else there'll be problems with the water reflections
        self.skybox.setScale(1.5* self.size)
        self.skybox.setBin('background', 1)
        self.skybox.setDepthWrite(False)
        self.skybox.setDepthTest(False)
        self.skybox.setLightOff(1)
        self.skybox.setShaderOff(1)
        self.skybox.setFogOff(1)

        #self.skybox.setColor(.55, .65, .95, 1.0)
        self.skybox_color = LColor(pow(0.5, 1/2.2), pow(0.6, 1/2.2), pow(0.7, 1/2.2), 1.0)
        self.skybox.setColor(self.skybox_color)

    def objects_density_for_patch(self, patch):
        scale = 1 << patch.lod
        return int(self.objects_density / scale + 1.0)

    def create_populator(self):
        if settings.allow_instancing:
            TerrainPopulator = GpuTerrainPopulator
        else:
            TerrainPopulator = CpuTerrainPopulator
        self.rock_collection = TerrainPopulator(RockFactory(self), self.objects_density_for_patch, self.objects_density, RandomObjectPlacer(self))
        self.tree_collection = TerrainPopulator(TreeFactory(self), self.objects_density_for_patch, self.objects_density, RandomObjectPlacer(self))
        self.object_collection = MultiTerrainPopulator()
        self.object_collection.add_populator(self.rock_collection)
        self.object_collection.add_populator(self.tree_collection)

    def set_light_angle(self, angle):
        self.light_angle = angle
        self.light_quat.setFromAxisAngleRad(angle * pi / 180, LVector3.forward())
        self.light_dir = self.light_quat.xform(LVector3.up())
        cosA = self.light_dir.dot(LVector3.up())
        self.vector_to_star = self.light_dir
        if self.shadow_caster is not None:
            self.shadow_caster.set_direction(-self.light_dir)
        if self.directionalLight is not None:
            self.directionalLight.setDirection(-self.light_dir)
        if cosA >= 0:
            coef = sqrt(cosA)
            self.light_color = (1, coef, coef, 1)
            self.directionalLight.setColor(self.light_color)
            self.skybox.setColor(self.skybox_color * cosA)
        else:
            self.light_color = (1, 0, 0, 1)
            self.directionalLight.setColor(self.light_color)
            self.skybox.setColor(self.skybox_color * 0)
        self.update()

    def update(self):
        self.object_collection.update_instance()
        self.terrain.update_instance(None, None)

    def apply_instance(self, instance):
        pass

    def create_instance_delayed(self):
        pass

    def get_apparent_radius(self):
        return 0

    def get_name(self):
        return "terrain"

    def is_emissive(self):
        return False

    def __init__(self):
        CosmoniumBase.__init__(self)

        config = RalphConfigParser()
        (self.noise, self.biome_noise, self.terrain_control, self.terrain_appearance, self.water, self.fog) = config.load_and_parse('ralph-data/ralph.yaml')

        self.tile_density = 64
        self.default_size = 128
        self.max_vertex_size = 64
        self.max_lod = 10

        self.size = 128 * 8
        self.max_distance = 1.001 * self.size * sqrt(2)
        self.noise_size = 512
        self.biome_size = 128
        self.noise_scale = 0.5 * self.size / self.default_size
        self.objects_density = int(25 * (1.0 * self.size / self.default_size) * (1.0 * self.size / self.default_size))
        self.objects_density = 250
        self.height_scale = 100 * 5.0
        self.has_water = True
        self.fullscreen = False
        self.shadow_caster = None
        self.light_angle = None
        self.light_dir = LVector3.up()
        self.vector_to_star = self.light_dir
        self.light_quat = LQuaternion()
        self.light_color = (1.0, 1.0, 1.0, 1.0)
        self.directionalLight = None
        self.shadow_size = self.default_size / 8
        self.shadow_box_length = self.height_scale

        self.observer = RalphCamera(self.cam, self.camLens)
        self.observer.init()

        self.distance_to_obs = float('inf')
        self.height_under = 0.0
        self.scene_position = LVector3()
        self.scene_scale_factor = 1
        self.scene_orientation = LQuaternion()

        #Size of an edge seen from 4 units above
        self.edge_apparent_size = (1.0 * self.size / self.tile_density) / (4.0 * self.observer.pixel_size)
        print("Apparent size:", self.edge_apparent_size)

        self.win.setClearColor((135.0/255, 206.0/255, 235.0/255, 1))

        # 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, "cam-up": 0, "cam-down": 0,
            "sun-left": 0, "sun-right": 0,
            "turbo": 0}

        # Set up the environment
        #
        # Create some lighting
        self.vector_to_obs = base.cam.get_pos()
        self.vector_to_obs.normalize()
        if True:
            self.shadow_caster = ShadowCaster(1024)
            self.shadow_caster.create()
            self.shadow_caster.set_lens(self.shadow_size, -self.shadow_box_length / 2.0, self.shadow_box_length / 2.0, -self.light_dir)
            self.shadow_caster.set_pos(self.light_dir * self.shadow_box_length / 2.0)
            self.shadow_caster.bias = 0.1
        else:
            self.shadow_caster = None

        self.ambientLight = AmbientLight("ambientLight")
        self.ambientLight.setColor((settings.global_ambient, settings.global_ambient, settings.global_ambient, 1))
        self.directionalLight = DirectionalLight("directionalLight")
        self.directionalLight.setDirection(-self.light_dir)
        self.directionalLight.setColor(self.light_color)
        self.directionalLight.setSpecularColor(self.light_color)
        render.setLight(render.attachNewNode(self.ambientLight))
        render.setLight(render.attachNewNode(self.directionalLight))

        render.setShaderAuto()
        base.setFrameRateMeter(True)

        self.create_terrain()
        self.create_populator()
        self.terrain_shape.set_populator(self.object_collection)
        self.create_tile(0, 0)
        self.skybox_init()

        self.set_light_angle(45)

        # Create the main character, Ralph

        ralphStartPos = LPoint3()
        self.ralph = Actor("ralph-data/models/ralph",
                           {"run": "ralph-data/models/ralph-run",
                            "walk": "ralph-data/models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(ralphStartPos + (0, 0, 0.5))
        self.ralph_shape = InstanceShape(self.ralph)
        self.ralph_shape.parent = self
        self.ralph_shape.set_owner(self)
        self.ralph_shape.create_instance()
        self.ralph_appearance = ModelAppearance(self.ralph)
        self.ralph_appearance.set_shadow(self.shadow_caster)
        self.ralph_shader = BasicShader()
        self.ralph_appearance.bake()
        self.ralph_appearance.apply(self.ralph_shape, self.ralph_shader)
        self.ralph_shader.apply(self.ralph_shape, self.ralph_appearance)
        self.ralph_shader.update(self.ralph_shape, self.ralph_appearance)

        # 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("control-q", 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("shift", self.setKey, ["turbo", True])
        self.accept("a", self.setKey, ["cam-left", True], direct=True)
        self.accept("s", self.setKey, ["cam-right", True], direct=True)
        self.accept("u", self.setKey, ["cam-up", True], direct=True)
        self.accept("u-up", self.setKey, ["cam-up", False])
        self.accept("d", self.setKey, ["cam-down", True], direct=True)
        self.accept("d-up", self.setKey, ["cam-down", False])
        self.accept("o", self.setKey, ["sun-left", True], direct=True)
        self.accept("o-up", self.setKey, ["sun-left", False])
        self.accept("p", self.setKey, ["sun-right", True], direct=True)
        self.accept("p-up", self.setKey, ["sun-right", False])
        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("shift-up", self.setKey, ["turbo", False])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])
        self.accept("w", self.toggle_water)
        self.accept("h", self.print_debug)
        self.accept("f2", self.connect_pstats)
        self.accept("f3", self.toggle_filled_wireframe)
        self.accept("shift-f3", self.toggle_wireframe)
        self.accept("f5", self.bufferViewer.toggleEnable)
        self.accept("f8", self.terrain_shape.dump_tree)
        self.accept('alt-enter', self.toggle_fullscreen)

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)
        self.camera_height = 2.0
        render.set_shader_input("camera", self.camera.get_pos())

        self.cTrav = CollisionTraverser()

        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)

        # Uncomment this line to see the collision rays
        #self.ralphGroundColNp.show()

        # Uncomment this line to show a visual representation of the
        # collisions occuring
        #self.cTrav.showCollisions(render)

        #self.terrain_shape.test_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance)
        #self.terrain_shape.update_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance)
        #self.terrain.shape_updated()
        self.terrain.update_instance(LPoint3d(*self.ralph.getPos()), None)

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)
        if self.keyMap["cam-up"]:
            self.camera_height *= (1 + 2 * dt)
        if self.keyMap["cam-down"]:
            self.camera_height *= (1 - 2 * dt)
        if self.camera_height < 1.0:
            self.camera_height = 1.0

        if self.keyMap["sun-left"]:
            self.set_light_angle(self.light_angle + 30 * dt)
        if self.keyMap["sun-right"]:
            self.set_light_angle(self.light_angle - 30 * dt)

        # 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.

        delta = 25
        if self.keyMap["turbo"]:
            delta *= 10
        if self.keyMap["left"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -delta * dt)
        if self.keyMap["backward"]:
            self.ralph.setY(self.ralph, delta * dt)

        #self.limit_pos(self.ralph)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if self.keyMap["forward"] or self.keyMap["backward"] or self.keyMap["left"] or self.keyMap["right"]:
            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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        self.cTrav.traverse(render)

        if False:
            # Adjust ralph's Z coordinate.  If ralph's ray hit anything, put
            # him back where he was last frame.

            entries = list(self.ralphGroundHandler.getEntries())
            entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

            if len(entries) > 0:
                self.ralph.setPos(startpos)
        ralph_height = self.get_height(self.ralph.getPos())
        self.ralph.setZ(ralph_height)

        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.

        camera_height = self.get_height(self.camera.getPos()) + 1.0
        if camera_height < ralph_height + self.camera_height:
            self.camera.setZ(ralph_height + self.camera_height)
        else:
            self.camera.setZ(camera_height)
        #self.limit_pos(self.camera)

        # 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.camera.lookAt(self.floater)

        #self.shadow_caster.set_pos(self.ralph.get_pos())
        self.shadow_caster.set_pos(self.ralph.get_pos() - camvec * camdist + camvec * self.shadow_size / 2)

        render.set_shader_input("camera", self.camera.get_pos())
        self.vector_to_obs = base.cam.get_pos()
        self.vector_to_obs.normalize()

        if self.isMoving:
            #self.terrain_shape.test_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance)
            pass#self.terrain_shape.update_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance)

        self.object_collection.update_instance()
        self.terrain.update_instance(LPoint3d(*self.ralph.getPos()), None)
        return task.cont

    def print_debug(self):
        print("Height:", self.get_height(self.ralph.getPos()), self.terrain.get_height(self.ralph.getPos()))
        print("Ralph:", self.ralph.get_pos())
        print("Camera:", base.camera.get_pos())
Exemplo n.º 50
0
class World(DirectObject):



    def __init__(self):
        #Let's start the Music
        mySound = base.loader.loadSfx("music/music.mp3")
        mySound.setLoopCount(0) #And Keep it On Loop
        mySound.play()
       

        base.setFrameRateMeter(True) #Shows the FrameRate in The Top Corner

        self.walking = Vec3()
        self.isMoving = False
        self.dest = None
        base.win.setClearColor(Vec4(0,0,0,1))


        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        #Here is the number of collectibles in the game
        
        self.rare = 1; 
        self.vasenum = 10;
        self.coinnum = 30;
        self.silvernum = 5;
        self.chestnum = 2;

        #Here is the Obstacles in the game
        self.rocknum = 500;

        #Here is the Score
        self.score = 0;

        #Here is the total Number of Objects to collect
        self.numObjects = self.rare + self.vasenum + self.coinnum + self.silvernum + self.chestnum
   
        # print the number of objects
        printNumObj(self.score)

        # Post the instructions
        self.title = addTitle("Mighty Mountain")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[A]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[D]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[W]: Run Ralph Forward")
        self.inst5 = addInstructions(0.75, "[S]: Run Ralph Backward")
        self.inst6 = addInstructions(0.70, "[Space]: Run, Ralph, Run")
        
        # 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)
        self.environ.setPos(0,0,0)
        
        # Timer to increment in the move task
        self.time = 0
        
        # Get bounds of environment
        min, max = self.environ.getTightBounds()
        self.mapSize = max-min
        
        # Create the main character, Ralph
        self.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(self.ralphStartPos)


        # ralph's stamina
        self.stamina = 200
        # 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", self.endgame)
        
        # these don't work well in combination with the space bar
        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("arrow_down", self.setKey, ["backward",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("arrow_down-up", self.setKey, ["backward",0])
        
        self.accept("space", self.runRalph, [True])
        self.accept("space-up", self.runRalph, [False])
        
        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("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])

        # Game state variables
        self.isMoving = False
        self.isRunning = False

        # Set up the camera
        base.disableMouse()
        #base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        base.camera.setPos(0, 0, 0)
        base.camera.reparentTo(self.ralph)
        base.camera.setPos(0, 40, 2)
        base.camera.lookAt(self.ralph)
        
        # 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.

        base.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0,0,300)
        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()
        base.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        # camera ground collision handler
        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,300)
        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()
        base.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        
        # Place the collectibles
        self.placeCollectibles() #Platinum 
        self.placeVases()
        self.placeCoins()
        self.placeSilver()
        self.placeGold()
        self.placeChests()

        #Place the obstacles
        self.placeRocks() #Cactus 
       
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        #base.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))
        
        taskMgr.add(self.move,"moveTask")


    #Reinitialize all necessary parts of the game
    def restart(self):

        #self.numObjects = 10
        self.score = 0
        printNumObj(self.score)
        self.ralph.setPos(self.ralphStartPos)
        self.stamina = 200
        self.time = 0
        base.camera.setPos(0, 0, 0)
        base.camera.reparentTo(self.ralph)
        base.camera.setPos(0, 40, 2)
        base.camera.lookAt(self.ralph)
        
        # Place the collectibles
        self.placeCollectibles() #Platinum 
        self.placeVases()
        self.placeCoins()
        self.placeSilver()
        self.placeGold()
        self.placeChests()

        #Place the obstacles
        self.placeRocks()

        #Total number of obstacles
        self.numObjects = self.rare + self.vasenum + self.coinnum + self.silvernum + self.chestnum

        taskMgr.add(self.move,"moveTask")
   
    
   
    # Display ralph's stamina
    def displayStamina(self):
        sprintBar['scale'] = (self.stamina*0.01*BAR_WIDTH,0.2,0.2)
    
#Collects the item and modifies score

    def collectCollectibles(self, entry): #Platinum 
        #Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        self.score = self.score * self.numObjects + 500
        self.numObjects = self.numObjects - 1
        printNumObj(self.score)
        

    def collectVase(self, entry):
        # Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        self.score = self.score + 10
        self.numObjects = self.numObjects - 1
        printNumObj(self.score)
    
    def collectCoins(self, entry):
        # Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        self.score = self.score + 1
        printNumObj(self.score)
        self.numObjects = self.numObjects - 1


    def collectSilver(self, entry):
        # Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        self.score = self.score + 20
        printNumObj(self.score)
        self.numObjects = self.numObjects - 1


    def collectGold(self, entry):
        # Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        self.score = self.score + 30
        printNumObj(self.score)
        self.numObjects = self.numObjects - 1

    def collectChest(self, entry):
        # Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        self.score = self.score + 100
        printNumObj(self.score)
        self.numObjects = self.numObjects - 1

#Unique function which handles collisions with a deduction obstacles.
    def deductRocks(self, entry):
        # Remove the collectible
        entry.getIntoNodePath().getParent().removeNode()
        # Update the number of objects
        if self.score > 500:
            randomnum = random.randint(1,2)
            if randomnum == 1:
             self.score = self.score - 100 #Removes Score
            if randomnum == 2:
             self.score = self.score + 100 #Removes Score

        if self.score < 500:
            self.score = self.score - 100

        randomnum = random.randint(1,2)

        if randomnum == 1:
            result =buttonbox(msg='A kind wizard wishes to help you on your quest? Trust him?', title='Alert!', choices=("Yes", "No"))

            if result == "Yes":
                othernum = random.randint(1,100)
                othernum = othernum * self.score + self.numObjects #Y = MX + B

                if othernum > 1000:
                    msgbox("Good choice! Add 1,000 Points to your Score!")
                    self.score = self.score + 1000
                if othernum < 1000:
                    msgbox("The wizard tricked you!He stole 100 Points!")
                    self.score = self.score - 100

        printNumObj(self.score)
      
      
        
    # Places an item randomly on the map    
    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()
    
   
#Places all obstacles on map.          
    def placeCollectibles(self):
        self.placeCol = render.attachNewNode("Collectible-Placeholder")
        self.placeCol.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.rare):
            # Load in the health item model
            self.collect = loader.loadModel("models/moneyBag")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeCol)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            colSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('colSphere')
            sphereNode.addSolid(colSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

    def placeVases(self):
        self.placeV = render.attachNewNode("Collectible-Placeholder")
        self.placeV.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.vasenum):
            # Load in the health item model
            self.collect = loader.loadModel("models/jar.egg")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeV)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            vaseSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('vaseSphere')
            sphereNode.addSolid(vaseSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

    def placeCoins(self):
        self.placeC = render.attachNewNode("Collectible-Placeholder")
        self.placeC.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.coinnum):
            # Load in the health item model
            self.collect = loader.loadModel("models/Cookie.egg")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeC)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            coinSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('coinSphere')
            sphereNode.addSolid(coinSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

    def placeSilver(self):
        self.placeS = render.attachNewNode("Collectible-Placeholder")
        self.placeS.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.silvernum):
            # Load in the health item model
            self.collect = loader.loadModel("models/Anvil.egg")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeS)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            silverSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('silverSphere')
            sphereNode.addSolid(silverSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

    def placeGold(self):
        self.placeG = render.attachNewNode("Collectible-Placeholder")
        self.placeG.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.silvernum):
            # Load in the health item model
            self.collect = loader.loadModel("models/key.egg")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeS)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            goldSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('goldSphere')
            sphereNode.addSolid(goldSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)
    def placeChests(self):
        self.placeCh = render.attachNewNode("Collectible-Placeholder")
        self.placeCh.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.chestnum):
            # Load in the health item model
            self.collect = loader.loadModel("models/Keg.a2c.cr.egg")
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeCh)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            chestSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('chestSphere')
            sphereNode.addSolid(chestSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)

    def placeRocks(self):
        self.placeR = render.attachNewNode("Collectible-Placeholder")
        self.placeR.setPos(0,0,0)
        
        # Add the health items to the placeCol node
        for i in range(self.rocknum):
            # Load in the health item model
            self.collect = loader.loadModel("models/smallcactus.egg")
            self.collect.setScale(0.2)
            self.collect.setPos(0,0,0)
            self.collect.reparentTo(self.placeR)
            
            self.placeItem(self.collect)
            
            # Add spherical collision detection
            rockSphere = CollisionSphere(0,0,0,1)
            sphereNode = CollisionNode('rockSphere')
            sphereNode.addSolid(rockSphere)
            sphereNode.setFromCollideMask(BitMask32.allOff())
            sphereNode.setIntoCollideMask(BitMask32.bit(0))
            sphereNp = self.collect.attachNewNode(sphereNode)
            sphereColHandler = CollisionHandlerQueue()
            base.cTrav.addCollider(sphereNp, sphereColHandler)



        
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    
    # Makes ralph's health decrease over time

    
    # Make ralph's stamina regenerate
    def staminaReg(self, task):
        if (self.stamina >= 200):
            self.stamina = 200
            return task.done
        else:
            self.stamina += 1
            task.setDelay(1)
            return task.again
        
    # Make ralph run
    def runRalph(self, arg):
        self.isRunning = arg
    
    # 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 self.score < 0:
            self.die()

        if self.numObjects == 0:
            self.endgame()

        randomnum1 = random.randint(1,1000)
        randomnum2 = randomnum1 * self.numObjects + self.score

        if randomnum1 == 1000:
            result =buttonbox(msg='An odd villager wishes to help you on your quest? Trust him?', title='Alert!', choices=("Yes", "No"))
            if result == "Yes":
                if randomnum2 > 20000:
                    msgbox("The villager grants you 4,000 Points!")
                    self.score = self.score + 4000
                if randomnum2 < 20000:
                    msgbox("The villager betrays you! He steal 200 points!")
                    self.score = self.score - 200

        
        # 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()
        
        # calculate ralph's speed
        if (self.isRunning and self.stamina > 0):
            taskMgr.remove("staminaTask")
            ralphSpeed = 45
            self.stamina -= 0.5
        else:
            taskMgr.doMethodLater(5, self.staminaReg, "staminaTask")
            ralphSpeed = 25

        # If a move-key is pressed, move ralph in the specified direction.
        # and rotate the camera to remain behind ralph
        if (self.keyMap["left"]!=0):
            self.ralph.setH(self.ralph.getH() + 100 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 100 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -ralphSpeed * globalClock.getDt())
        if (self.keyMap["backward"]!=0):
            self.ralph.setY(self.ralph, ralphSpeed *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["left"]!=0) 
            or (self.keyMap["right"]!=0) or (self.keyMap["backward"]!=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

        # so the following line is unnecessary
        base.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.
        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
            #base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+5)

        #Adds all the items to the map and handles if they get hit.
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "colSphere"):
            self.collectCollectibles(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "vaseSphere"):
            self.collectVase(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "coinSphere"):
            self.collectCoins(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "silverSphere"):
            self.collectSilver(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "goldSphere"):
            self.collectGold(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "chestSphere"):
            self.collectChest(entries[0])
        elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "rockSphere"):
            self.deductRocks(entries[0])

        else:
            self.ralph.setPos(startpos)
        
        # Keep the camera above the terrain
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            modZ = entries[0].getSurfacePoint(render).getZ()
            base.camera.setZ(20.0+modZ+(modZ-self.ralph.getZ()))
        
        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ()+2.0)
        base.camera.lookAt(self.floater)
        
        self.displayStamina()

        return task.cont
    #If the user collects all items and/or ends the game through Escape.
    def endgame(self):
         # end all running tasks
        taskMgr.remove("moveTask")
        taskMgr.remove("healthTask")

        # Open database connection and inserts data.
        conn = MySQLdb.connect("sql5.freemysqlhosting.net","sql5106009","DFxbmhVkvG","sql5106009")
        cursor = conn.cursor()
        cursor.execute("INSERT INTO scores (score, username) VALUES (%s, %s)", (self.score, name))
        conn.commit()
        time.sleep(5) #Error without this...

        #Some text
        self.label = DirectLabel(text="End Game!",
                                      scale=.05, pos=(0,0,0.2))

        self.entry = DirectEntry(text="", scale=.05, initialText="",
                                    numLines=1, focus=1, pos=(-0.25,0,0))

        
   
        #Display high score

        self.highscore = OkDialog(dialogName="highscoreDialog", 
                                  text="Your High Score:\n\nName: " + name + "Score: " + str(self.score),
                                  command=sys.exit())

    # Restart or End?
    def die(self):
        # end all running tasks
        taskMgr.remove("moveTask")
        taskMgr.remove("healthTask")

        # Open database connection
        conn = MySQLdb.connect("sql5.freemysqlhosting.net","sql5106009","DFxbmhVkvG","sql5106009")
        cursor = conn.cursor()
        cursor.execute("INSERT INTO scores (score, username) VALUES (%s, %s)", (self.score, name))
        conn.commit()
        time.sleep(5)

        self.label = DirectLabel(text="Game over!",
                                      scale=.05, pos=(0,0,0.2))

        self.entry = DirectEntry(text="", scale=.05, initialText="",
                                    numLines=1, focus=1, pos=(-0.25,0,0))

        
   
        #Display high score

        self.highscore = OkDialog(dialogName="highscoreDialog", 
                                  text="Your High Score:\n\nName: " + name + " " + "Score: " + str(self.score),
                                  command=self.showDialog)


    def showDialog(self, arg):
        # cleanup highscore dialog
        self.highscore.cleanup()
        # display restart or exit dialog
        self.dialog = YesNoDialog(dialogName="endDialog",
                                   text="Would you like to continue?", 
                                   command=self.endResult)
    
    # Handle the dialog result
    def endResult(self, arg):
        if (arg):
            # cleanup the dialog box
            self.dialog.cleanup()
            # restart the game
            self.restart()
        else:
            sys.exit()
Exemplo n.º 51
0
class World(DirectObject):
    def __init__(self):
        # This code puts the standard title and instruction text on screen
        self.title = OnscreenText(text="Ball in Maze",
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  pos=(0.7, -0.95),
                                  scale=.07)
        self.instructions = OnscreenText(text="Press Esc to exit.",
                                         pos=(-1.3, .95),
                                         fg=(1, 1, 1, 1),
                                         align=TextNode.ALeft,
                                         scale=.05)

        base.setBackgroundColor(0, 0, 0)

        self.central_msg = OnscreenText(text="",
                                        pos=(0, 0),
                                        fg=(1, 1, 0, 1),
                                        scale=.1)
        self.central_msg.hide()

        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):
        # 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 mouse position and tilt the maze accordingly
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()  # get the mouse position
            self.maze.setP(mpos.getY() * -10)
            self.maze.setR(mpos.getX() * 10)

        # 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

    def show_message(self, message=''):
        if message:
            self.central_msg.setText(message)
            self.central_msg.show()
        else:
            self.central_msg.hide()

    # 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)), Func(self.show_message, "Try Again!"),
            Wait(1), Func(self.show_message, ""), Func(self.start)).start()
Exemplo n.º 52
0
class Game(DirectObject):
    def __init__(self, model):
        self.model = model
        base.setBackgroundColor(0.1, 0.1, 0.8, 1)
        base.setFrameRateMeter(True)

        base.cam.setPos(0, -20, 4)
        base.cam.lookAt(0, 0, 0)

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
        alightNP = render.attachNewNode(alight)

        dlight = DirectionalLight('directionalLight')
        dlight.setDirection(Vec3(1, 1, -1))
        dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        render.setLight(dlightNP)

        # Input
        self.accept('escape', self.doExit)
        self.accept('r', self.doReset)
        self.accept('f1', self.toggleWireframe)
        self.accept('f2', self.toggleTexture)
        self.accept('f3', self.toggleDebug)
        self.accept('f5', self.doScreenshot)

        inputState.watchWithModifiers('forward', 'w')
        inputState.watchWithModifiers('left', 'a')
        inputState.watchWithModifiers('reverse', 's')
        inputState.watchWithModifiers('right', 'd')
        inputState.watchWithModifiers('turnLeft', 'q')
        inputState.watchWithModifiers('turnRight', 'e')

        # Task
        taskMgr.add(self.update, 'updateWorld')

        # Physics
        self.setup()

    # _____HANDLER_____

    def doExit(self):
        self.cleanup()
        sys.exit(1)

    def doReset(self):
        self.cleanup()
        self.setup()

    def toggleWireframe(self):
        base.toggleWireframe()

    def toggleTexture(self):
        base.toggleTexture()

    def toggleDebug(self):
        if self.debugNP.isHidden():
            self.debugNP.show()
        else:
            self.debugNP.hide()

    def doScreenshot(self):
        base.screenshot('Bullet')

    # ____TASK___

    def calculate_moves(self):
        self.y = self.model.predict(self.x)
        self.moves = self.y > 0  # 0.5

    def processInput(self, dt):
        engineForce = 0.0
        brakeForce = 0.0
        if self.moves[0]:  #inputState.isSet('forward'):
            engineForce = 1000.0
            brakeForce = 0.0

        if not self.moves[0]:  #inputState.isSet('reverse'):
            engineForce = 0.0
            brakeForce = 100.0

        if self.moves[1]:  #inputState.isSet('turnLeft'):
            self.steering += dt * self.steeringIncrement
            self.steering = min(self.steering, self.steeringClamp)

        if not self.moves[1]:  #inputState.isSet('turnRight'):
            self.steering -= dt * self.steeringIncrement
            self.steering = max(self.steering, -self.steeringClamp)
        """
    if inputState.isSet('forward'):
      engineForce = 1000.0
      brakeForce = 0.0

    if inputState.isSet('reverse'):
      engineForce = 0.0
      brakeForce = 100.0

    if inputState.isSet('turnLeft'):
      self.steering += dt * self.steeringIncrement
      self.steering = min(self.steering, self.steeringClamp)

    if inputState.isSet('turnRight'):
      self.steering -= dt * self.steeringIncrement
      self.steering = max(self.steering, -self.steeringClamp)
    """
        # Apply steering to front wheels
        self.vehicle.setSteeringValue(self.steering, 0)
        self.vehicle.setSteeringValue(self.steering, 1)

        # Apply engine and brake to rear wheels
        self.vehicle.applyEngineForce(engineForce, 2)
        self.vehicle.applyEngineForce(engineForce, 3)
        self.vehicle.setBrake(brakeForce, 2)
        self.vehicle.setBrake(brakeForce, 3)

    def raycast(self):
        """pFrom = render.getRelativePoint(self.yugoNP,Point3(0,0,0))#Point3(0,0,0)
      pFrom -= Point3(0,0,pFrom[2])
      pRel = render.getRelativePoint(base.cam,self.yugoNP.getPos())  # FIXME THIS IS IT!! get rid of z component
      pRel -= Point3(0,0,pRel[2])
      p45 = Point3(pRel[0] - pRel[1], pRel[1] + pRel[0],0)
      pn45 = Point3(pRel[0] + pRel[1], pRel[1] - pRel[0],0)
      #print(render.getRelativePoint(self.yugoNP,Point3(0,0,0)))
      #print(dir(self.yugoNP))
      pTo = [pFrom + pn45, pFrom + pRel, pFrom + p45]#[pFrom + Vec3(-10,10,0)*999,pFrom + Vec3(0,10,0)*999,pFrom + Vec3(10,10,0)*999]# FIXME should be relative to front of car, getting cloe! #self.yugoNP.getPosDelta()*99999]#[Point3(-10,10,0) * 99999,Point3(0,10,0) * 99999,Point3(10,10,0) * 99999]
      #self.ray = CollisionRay(0,0,0,100,0,0)
      result = [self.world.rayTestClosest(pFrom,pt) for pt in pTo]
      #print(dir(self.yugoNP))
      #print(result.getHitPos())
      return tuple([res.getHitPos().length() for res in result])
      """#queue = CollisionHandlerQueue()
        #traverser.addCollider(fromObject, queue)
        #traverser.traverse(render)
        #queue.sortEntries()
        #for entry in queue.getEntries():
        #print(entry)
        #print(result.getHitPos())
        #if result.getNode() != None:
        #print(self.yugoNP.getPos(result.getNode()))
        #print(self.cTrav)
        self.cTrav.traverse(render)
        entries = list(self.colHandler.getEntries())
        entries.sort(key=lambda y: y.getSurfacePoint(render).getY())
        #for entry in entries:      print(entry.getFromNodePath().getName())
        if entries:  # and len(result) > 1:
            for r in entries:
                if r.getIntoNodePath().getName(
                ) == 'Box' and r.getFromNodePath().getName() in [
                        'ray%d' % i for i in range(3)
                ]:
                    self.ray_col_vec_dict[
                        r.getFromNodePath().getName()].append(
                            numpy.linalg.norm(
                                list(r.getSurfacePoint(
                                    r.getFromNodePath()))[:-1]))
        self.ray_col_vec_dict = {
            k: (min(self.ray_col_vec_dict[k])
                if len(self.ray_col_vec_dict[k]) >= 1 else 10000)
            for k in self.ray_col_vec_dict
        }
        self.x = numpy.array(list(self.ray_col_vec_dict.values()))
        #return entries

    def update(self, task):

        dt = globalClock.getDt()

        self.raycast()
        self.calculate_moves()
        self.ray_col_vec_dict = {k: [] for k in self.ray_col_vec_dict}
        self.processInput(dt)
        self.world.doPhysics(dt, 10, 0.008)

        #print(dir(result[1]))
        #print(numpy.linalg.norm(list(result[1].getSurfacePoint(result[1].getFromNodePath()))[:-1]))
        #base.camera.setPos(0,-40,10)
        #print self.vehicle.getWheel(0).getRaycastInfo().isInContact()
        #print self.vehicle.getWheel(0).getRaycastInfo().getContactPointWs()

        #print self.vehicle.getChassis().isKinematic()

        return task.cont

    def cleanup(self):
        self.world = None
        self.worldNP.removeNode()

    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        #terrain = GeoMipTerrain("mySimpleTerrain")
        #terrain.setHeightfield("./models/heightfield_2.png")
        #terrain.getRoot().reparentTo(self.worldNP)#render)
        #terrain.generate()

        # Plane
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
        np.node().addShape(shape)
        np.setPos(0, 0, -1)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Track'))
        np.node().setMass(5000.0)
        np.setPos(3, 0, 10)
        np.setCollideMask(BitMask32.allOn())  #(0x0f))
        #self.track = BulletVehicle(self.world, np.node())
        #self.track.setCoordinateSystem(ZUp)
        self.track_np = loader.loadModel('models/race_track.egg')
        self.track_np.setScale(100)
        self.track_np.reparentTo(np)

        self.track_np.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(np.node())
        self.track_np = np
        #self.track_np.show()

        # Chassis
        shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5))
        ts = TransformState.makePos(Point3(0, 0, 0.5))

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle'))
        np.node().addShape(shape, ts)
        np.setPos(0, 0, 1)
        np.node().setMass(800.0)
        np.node().setDeactivationEnabled(False)

        self.world.attachRigidBody(np.node())

        #np.node().setCcdSweptSphereRadius(1.0)
        #np.node().setCcdMotionThreshold(1e-7)
        self.cTrav = CollisionTraverser()
        # Vehicle
        self.vehicle = BulletVehicle(self.world, np.node())
        self.vehicle.setCoordinateSystem(ZUp)
        self.yugoNP = loader.loadModel('models/yugo/yugo.egg')
        self.yugoNP.reparentTo(np)
        self.colHandler = CollisionHandlerQueue()
        self.ray_col_np = {}
        self.ray_col_vec_dict = {}
        for ray_dir in range(-1, 2):  # populate collision rays
            self.ray = CollisionRay()
            self.ray.setOrigin(ray_dir, 0.5, 0.5)
            self.ray.setDirection(ray_dir, 1, 0)
            self.ray_col = CollisionNode('ray%d' % (ray_dir + 1))
            self.ray_col.addSolid(self.ray)
            self.ray_col.setFromCollideMask(
                BitMask32.allOn())  #(0x0f))#CollideMask.bit(0)
            #self.ray_col.setIntoCollideMask(CollideMask.allOff())
            self.ray_col_np['ray%d' %
                            (ray_dir + 1)] = self.yugoNP.attachNewNode(
                                self.ray_col)
            self.cTrav.addCollider(self.ray_col_np['ray%d' % (ray_dir + 1)],
                                   self.colHandler)
            self.ray_col_np['ray%d' % (ray_dir + 1)].show()
            self.ray_col_vec_dict['ray%d' % (ray_dir + 1)] = []
        self.world.attachVehicle(self.vehicle)
        self.cTrav.showCollisions(render)

        # FIXME
        base.camera.reparentTo(self.yugoNP)

        # Right front wheel
        np = loader.loadModel('models/yugo/yugotireR.egg')
        np.reparentTo(self.worldNP)
        self.addWheel(Point3(0.70, 1.05, 0.3), True, np)

        # Left front wheel
        np = loader.loadModel('models/yugo/yugotireL.egg')
        np.reparentTo(self.worldNP)
        self.addWheel(Point3(-0.70, 1.05, 0.3), True, np)

        # Right rear wheel
        np = loader.loadModel('models/yugo/yugotireR.egg')
        np.reparentTo(self.worldNP)
        self.addWheel(Point3(0.70, -1.05, 0.3), False, np)

        # Left rear wheel
        np = loader.loadModel('models/yugo/yugotireL.egg')
        np.reparentTo(self.worldNP)
        self.addWheel(Point3(-0.70, -1.05, 0.3), False, np)

        # Steering info
        self.steering = 0.0  # degree
        self.steeringClamp = 45.0  # degree
        self.steeringIncrement = 120.0  # degree per second

        # Box
        for i, j in [(0, 8), (-3, 5), (6, -5), (8, 3), (-4, -4)]:
            shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))
            # https://discourse.panda3d.org/t/wall-collision-help/23606
            np = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
            np.node().setMass(1.0)
            np.node().addShape(shape)
            np.setPos(i, j, 2)
            np.setCollideMask(BitMask32.allOn())  #(0x0f))

            self.world.attachRigidBody(np.node())
            self.boxNP = np
            #self.colHandler2 = CollisionHandlerQueue()

            visualNP = loader.loadModel('models/box.egg')
            visualNP.reparentTo(self.boxNP)
        #self.cTrav.addCollider(self.boxNP,self.colHandler)
        """
    aNode = CollisionNode("TheRay")

    self.ray = CollisionRay()
    self.ray.setOrigin( self.yugoNP.getPos() )
    self.ray.setDirection( Vec3(0, 10, 0) )
    #self.ray.show()


    aNodePath = self.yugoNP.attachNewNode( CollisionNode("TheRay") )
    aNodePath.node().addSolid(self.ray)
    aNodePath.show()
    """
        #aNode.addSolid(self.ray)
        #self.ray = CollisionRay(0,0,0,10,0,0)
        #self.ray.reparentTo(self.yugoNP)
        #self.rayColl = CollisionNode('PlayerRay')
        #self.rayColl.addSolid(self.ray)

        #self.playerRayNode = self.yugoNP.attachNewNode( self.rayColl )
        #self.playerRayNode.show()

        #base.myTraverser.addCollider (self.playerRayNode, base.floor)
        #base.floor.addCollider( self.playerRayNode, self.yugoNP)
        """
    MyEvent=CollisionHandlerFloor()
    MyEvent.setReach(100)
    MyEvent.setOffset(15.0)

    aNode = CollisionNode("TheRay")
    ray = CollisionRay()
    ray.setOrigin( self.boxNP.getPos() )
    ray.setDirection( Vec3(10, 0, 0) )

    aNode.addSolid(ray)
    aNodePath = MyModel.attachNewNode( aNode )

    Collision = ( aNode, "TheRay" )
    Collision[0].setFromCollideMask( BitMask32.bit( 1 ) )
    """

    def addWheel(self, pos, front, np):
        wheel = self.vehicle.createWheel()

        wheel.setNode(np.node())
        wheel.setChassisConnectionPointCs(pos)
        wheel.setFrontWheel(front)

        wheel.setWheelDirectionCs(Vec3(0, 0, -1))
        wheel.setWheelAxleCs(Vec3(1, 0, 0))
        wheel.setWheelRadius(0.25)
        wheel.setMaxSuspensionTravelCm(40.0)

        wheel.setSuspensionStiffness(40.0)
        wheel.setWheelsDampingRelaxation(2.3)
        wheel.setWheelsDampingCompression(4.4)
        wheel.setFrictionSlip(100.0)
        wheel.setRollInfluence(0.1)
Exemplo n.º 53
0
class World(ShowBase):
    def skyBoxLoad(self):
        self.spaceSkyBox = load_model('skybox1.egg')
        self.spaceSkyBox.setScale(150)
        self.spaceSkyBox.setLightOff()
        self.spaceSkyBox.reparentTo(render)
        self.spaceSkyBox.setPos(0,0,-200)
        self.spaceSkyBox.setHpr(0,0,0)        

    def loadEnviron(self):
        self.environ = load_model("secondWorld.egg")
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)

    def Hooh(self):
        """ hooh """
        self.hoohActor = Actor("anim2hooh.egg",
                           {"wing":"anim-Anim0.egg"})
        self.hoohActor.reparentTo(render)
        self.hoohActor.loop("wing")
        self.hoohActor.setPos(self.ralphStartPos[0],
                              self.ralphStartPos[1]+100,
                              self.ralphStartPos[2]+100)
        self.hoohActor.setPlayRate(4.0,"wing")
        self.hoohActor.setHpr(180,90,0)

        start = Point3(self.ralphStartPos[0], self.ralphStartPos[1]+95,
                       self.ralphStartPos[2]+100)
        end = Point3(self.ralphStartPos[0], self.ralphStartPos[1]-100,
                     self.ralphStartPos[2]+100)
        turnHpr1 = Point3(180,90,0)
        turnHpr2 = Point3(0,90,0) 
        hoohPosInt1 = self.hoohActor.posInterval(5.0, start, startPos = end)
        hoohPosInt2 = self.hoohActor.posInterval(5.0, end, startPos = start)
        hoohHprInt1 = self.hoohActor.hprInterval(1.0, turnHpr2,
                                                 startHpr=turnHpr1)
        hoohHprInt2 = self.hoohActor.hprInterval(1.0, turnHpr1,
                                                 startHpr=turnHpr2)        
        self.hoohFly = Sequence(hoohPosInt1,
                                hoohHprInt1,
                                hoohPosInt2,
                                hoohHprInt2,
                                name="hoohFly")
        self.hoohFly.loop()        

    def gold(self, task):
        _GOLD_PARTICLES.setPos(self.hoohActor.getPos())
        return task.cont
        
    def loadPokemon(self):
        """ Pikachu """
        self.pikachu = load_model("pikachu.egg")
        self.pikachu.reparentTo(render)
        self.pikachu.setPos(_PIKACHU_POS)
        self.pikachu.setHpr(_PIKACHU_HPR)

        """ Groudon """
        self.Groudon = load_model("Groudon.egg")
        self.Groudon.reparentTo(render)
        self.Groudon.setPos(_GROUDON_POS)
        self.Groudon.setHpr(_GROUDON_HPR)

        """ Bulbasaur """
        self.bulbasaur = load_model("bulbasaur.egg")
        self.bulbasaur.reparentTo(render)
        self.bulbasaur.setPos(_BULBASAUR_POS)
        self.bulbasaur.setHpr(_BULBASAUR_HPR)

        """ hooh """
        self.Hooh()

        """ Pichu """
        self.pichu = load_model("pichu.egg")
        self.pichu.reparentTo(render)
        self.pichu.setPos(_PICHU_POS)
        self.pichu.setHpr(_PICHU_HPR)

        """ Charmander """
        self.charmander = load_model("char.egg")
        self.charmander.reparentTo(render)
        self.charmander.setPos(_CHARMANDER_POS)
        self.charmander.setHpr(_CHARMANDER_HPR)

        """ charizard """
        self.charizard = load_model("charizard.egg")
        self.charizard.reparentTo(render)
        self.charizard.setPos(_CHARIZARD_POS)
        self.charizard.setHpr(_CHARIZARD_HPR)

        """ blastoise """
        self.blastoise = load_model("blastoise.egg")
        self.blastoise.reparentTo(render)
        self.blastoise.setPos(_BLASTOISE_POS)
        self.blastoise.setHpr(_BLASTOISE_HPR)

        """ Squirtle """
        self.squirtle = load_model("squirtle.egg")
        self.squirtle.reparentTo(render)
        self.squirtle.setPos(_SQUIRTLE_POS)
        self.squirtle.setHpr(_SQUIRTLE_HPR)

        """ Dragonite """
        self.dragonite = load_model("dragonite.egg")
        self.dragonite.reparentTo(render)
        self.dragonite.setPos(_DRAGONITE_POS)
        self.dragonite.setHpr(_DRAGONITE_HPR)
        
        _FLAME.setPos(_FLAME_POS)
        _FLAME.setScale(0.1)
        _FLAME.start(parent=render, renderParent=render)
        
        """ venusaur """
        self.venusaur = load_model("venusaur.egg")
        self.venusaur.reparentTo(render)
        self.venusaur.setPos(_VENUSAUR_POS)
        self.venusaur.setHpr(_VENUSAUR_HPR)
        
    def loadRalph(self):
        # Create the main character, Ralph
        basePath = r"../google_drive/ball/data/models/"
        self.ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor(basePath+"ralph",{"run":basePath+"ralph-run",
                                  "walk":basePath+"ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(self.ralphStartPos)
        self.ralph.hide()                    

    def loadNextMusic(self, task):
        # random load background music
        if (self.music.status()!=self.music.PLAYING):
            # not playing
            self.musicCounter += 1
            index = self.musicCounter % len(_BGMUSIC)
            self.music = load_bgmusic(_BGMUSIC[index])
            self.music.play()
        return task.cont
        
    def keyControl(self):
        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("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("w",self.setKey,["upward",1])
        self.accept("w-up",self.setKey,["upward",0])
        self.accept("s",self.setKey,["downward",1])
        self.accept("s-up",self.setKey,["downward",0])
        self.accept("t", self.toggleMusic)
        self.accept("u", self.changeVolume, ['u'])
        self.accept("d", self.changeVolume, ['d'])
        self.accept("h", self.hideInstructions)

    def changeVolume(self, direction):
        if direction == 'u' and self.volume < 1:
            self.volume += 0.05
        else: # direction == 'd'
            if self.volume > 0:
                self.volume -= 0.05
        self.music.setVolume(self.volume)
            
    def toggleMusic(self):
        self.music.stop()
        self.musicCounter += 1 # increment the counter by 
        index = self.musicCounter % len(_BGMUSIC)
        self.music = load_bgmusic(_BGMUSIC[index])
        self.music.play()
        
    def displayInformation(self):
        self.title = addTitle("My Pokemon - Roam Mode")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Arrow Keys]: Move")
        self.inst3 = addInstructions(0.85, "[w]: look up")
        self.inst4 = addInstructions(0.80, "[s]: look down")
        self.inst5 = addInstructions(0.75, "[t]: toggle next song")
        self.inst6 = addInstructions(0.70, "[u]: volume up")
        self.inst7 = addInstructions(0.65, "[d]: volume down")
        self.inst8 = addInstructions(0.60, "[h]: hide/show instructions")
        self.insts = [self.title, self.inst1, self.inst2, self.inst3,
                      self.inst4, self.inst5, self.inst6, self.inst7,
                      self.inst8]

    def hideInstructions(self):
        if self.instStatus == "show":
            self.instStatus = "hide"
            groupHide(self.insts)
        else: # instructions are hidden
            self.instStatus = "show"
            groupShow(self.insts)
        
    def __init__(self):
        base.enableParticles()
        self.keyMap = {"left":0, "right":0, "forward":0,"backward":0,
                       "upward":0, "downward":0, "leftward":0,"rightward":0,
                       "cam-left":0, "cam-right":0}
        _GOLD_PARTICLES.start(parent=render, renderParent=render)
        _GOLD_PARTICLES.setScale(200)
        self.instStatus = "show"
        self.musicCounter = 0
        self.music = load_bgmusic(_BGMUSIC[0])
        # self.music.play()
        self.volume = 0
        self.music.setVolume(self.volume)
        base.win.setClearColor(Vec4(0,0,0,1))
        self.above = 3.0
        # load environment
        self.loadEnviron()
        # load ralph
        self.loadRalph()
        # load sky box
        self.skyBoxLoad()
        # load pokemon
        self.loadPokemon()

        self.displayInformation()
        self.keyControl()
        # 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)
        taskMgr.add(self.move,"moveTask")
        taskMgr.add(self.setAbove,"setAbove")
        taskMgr.add(self.loadNextMusic, "loadRandomMusic")
        taskMgr.add(self.gold, "gold")
        # Game state variables
        self.isMoving = False
        # Set up the camera
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY(),2)
        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))

    def setAbove(self,task):
        if self.keyMap["upward"] == 1:
            self.above += 0.1
        if self.keyMap["downward"] == 1:
            self.above -= 0.1
        return task.cont
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # 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() + 113 * globalClock.getDt())
            base.camera.setX(base.camera, +20 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 113 * globalClock.getDt())
            base.camera.setX(base.camera, -20 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -75 * globalClock.getDt())
        if (self.keyMap["backward"] != 0):
            pass
            #self.ralph.setY(self.ralph, 75 * 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["left"]!=0) or (self.keyMap["right"]!=0):# or (self.keyMap["backward"]!=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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.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)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        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() + self.above)#self.above)
        
        base.camera.lookAt(self.floater)
        return task.cont
class World(DirectObject):
  def __init__(self):
    # This code puts the standard title and instruction text on screen
    self.title = OnscreenText(text="Panda3D: Tutorial - Collision Detection",
                              style=1, fg=(1,1,1,1),
                              pos=(0.7,-0.95), scale = .07)
    self.instructions = OnscreenText(text="Mouse pointer 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):
    # 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 mouse position and tilt the maze accordingly
    if base.mouseWatcherNode.hasMouse():
      mpos = base.mouseWatcherNode.getMouse() # get the mouse position
      self.maze.setP(mpos.getY() * -10)
      self.maze.setR(mpos.getX() * 10)

    # 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()
Exemplo n.º 55
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # 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,
            "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.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.36, "[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)

        # 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, 0.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("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("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)

        # 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, 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.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((.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))

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

        # 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"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -25 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap[
                "right"]:
            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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #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 = list(self.ralphGroundHandler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        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 = 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.ralph.getZ() + 2.0:
            self.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.camera.lookAt(self.floater)

        return task.cont
Exemplo n.º 56
0
class MyApp(ShowBase):
    def insertTile(self, node, submap_center, xel: Xel.Xel, tile_z, terrain):
        dx, dy = submap_center
        (q, r) = xel.exa.x, xel.exa.e
        v_center = VBase2(s3 * q, v3s * 2 * (q / 2 + r))

        tile_color = "rock"  #TODO
        #if abs(q) == Map.radius or abs(r) == Map.radius or abs(xel.exa.a) == Map.radius:
        #    tile_color = "yellow"
        #else:  #temporary
        if terrain == "water":
            tile_z = 0
        tile_color = terrain

        return self.model.loadExaTile(node, v_center[0] + dx, v_center[1] + dy,
                                      tile_z, tile_color)

    def drawTriangle(self, node, submap_center, submap_xel, triangle_index,
                     nodes_ZTH, open_simplex):
        global god
        center_map = submap_xel
        for d in range(1, Map.radius +
                       1):  # distance from center moving along triangle side t
            center_map = center_map.link[dirs[triangle_index]]
            tmp_map = center_map
            for n in range(
                    0, d
            ):  # each cell from triangle_index triangle edge (included) to next triangle edge (excluded)
                if d == Map.radius and n == 0:
                    cell_z = nodes_ZTH[0][triangle_index]
                    cell_t = nodes_ZTH[1][triangle_index]
                    cell_h = nodes_ZTH[2][triangle_index]
                else:
                    interna = ((nodes_ZTH[0][6], nodes_ZTH[0][triangle_index],
                                nodes_ZTH[0][(triangle_index + 1) % 6]),
                               (nodes_ZTH[1][6], nodes_ZTH[1][triangle_index],
                                nodes_ZTH[1][(triangle_index + 1) % 6]),
                               (nodes_ZTH[2][6], nodes_ZTH[2][triangle_index],
                                nodes_ZTH[2][(triangle_index + 1) % 6]))
                    res = ExaRandom.interpolate(
                        self, interna, Map.radius,
                        (tmp_map.exa.e, tmp_map.exa.x, tmp_map.exa.a))

                    (cell_z, cell_t, cell_h) = res
                cell_z += open_simplex.noise2d(tmp_map.exa.x,
                                               tmp_map.exa.e) / 5

                esterna = god.creation(
                    submap_center,
                    (tmp_map.exa.e, tmp_map.exa.x, tmp_map.exa.a), cell_t,
                    cell_h)  #animale, vegetale, terreno

                #load models

                dx, dy = submap_center
                (q, r) = tmp_map.exa.x, tmp_map.exa.e
                v_center = VBase2(s3 * q, v3s * 2 * (q / 2 + r))

                if esterna[0] != None:
                    self.model.loadAnimal(node, v_center[0] + dx,
                                          v_center[1] + dy, cell_z,
                                          esterna[0].nome)
                if esterna[1] != None:
                    self.model.loadPlant(node, v_center[0] - side + dx,
                                         v_center[1] + dy, cell_z,
                                         esterna[1].nome)

                if esterna[2] != None:
                    terrain_name = esterna[2].nome
                else:
                    terrain_name = "rock"

                self.insertTile(node, submap_center, tmp_map, cell_z,
                                terrain_name)

                tmp_map = tmp_map.link[dirs[(triangle_index + 2) % 6]]

    def drawSubmap(self, submap):
        l_map = Map.l_map  # TODO: chose if letting this way or pass l_map as parameter

        open_s = OpenSimplex(submap.noise_seed)

        #Center
        global god
        esterna = god.creation(submap.centerXY, (0, 0, 0), submap.array_T[6],
                               submap.array_H[6])  #animale, vegetale, terreno

        if esterna[2] != None:
            terrain_name = esterna[2].nome
        else:
            terrain_name = "rock"

        self.insertTile(submap.node, submap.centerXY, l_map, submap.array_Z[6],
                        terrain_name)

        ### Graphic map construction, triangle-by-triangle way
        center_map = l_map
        for t in range(6):  # scan each triangle
            interna = (submap.array_Z, submap.array_T, submap.array_H)
            self.drawTriangle(submap.node, submap.centerXY, center_map, t,
                              interna, open_s)
        ###
        return submap

    def drawMap(self, submap):
        global current_submap
        global stored_submaps_list
        global rendered_submaps

        new_seven_centers = []
        for d, v in coords.items():
            temp_c = ((v[0] + submap.centerXY[0]), (v[1] + submap.centerXY[1]))
            #print("-----------------------",v, submap.centerXY, temp_c) #BUGGONE
            new_seven_centers.append(temp_c)
        new_seven_centers.append(submap.centerXY)

        if len(rendered_submaps) == 0:  # Starting case
            submap.node = SubmapNode("0")
            submap.node.reparentTo(self.render)
            center = self.drawSubmap(submap)
            rendered_submaps.append(center)
            tmp_rendered_submaps = [None, None, None, None, None, None, center]
        else:
            tmp_rendered_submaps = [None, None, None, None, None, None, None]

        useful_values = []

        for i in range(7):
            draw = True  #check if a sub_map in new_seven_centers has to be drawn.
            #print all rendenew_seven_centersred maps
            """print("Rendered:")
            for s in rendered_submaps:
                print(s, end='')
            print("")"""
            c = new_seven_centers[i]
            for s in rendered_submaps:
                #diff = (abs(c[0] - s.centerXY[0]), abs(c[1] - s.centerXY[1]))
                print("_--------------", c, s)
                print(
                    "DIFF= ",
                    math.isclose(c[0], s.centerXY[0], abs_tol=0.1)
                    and math.isclose(c[1], s.centerXY[1], abs_tol=0.1))
                if math.isclose(c[0], s.centerXY[0],
                                abs_tol=0.1) and math.isclose(
                                    c[1], s.centerXY[1], abs_tol=0.1):
                    draw = False  #if a map in new_seven_centers is already in rendered_submaps set draw to false
                    tmp_rendered_submaps[i] = s
                    # prova
                    useful_values.append(s)
                    break
            if draw == True:  #if draw is still True, then draw the map in new_seven_centers
                if c in stored_submaps_list.keys():
                    s_map = stored_submaps_list[c]
                else:
                    s_map = ExaRandom().create_submap(c)
                    stored_submaps_list[c] = s_map
                s_map.node = SubmapNode("1")
                s_map.node.reparentTo(self.render)
                tmp_rendered_submaps[i] = self.drawSubmap(s_map)
                #rendered_submaps.append(self.drawSubmap(self.render, s_map))
                print(c, "drawn\n")
            else:
                print(c, "NOT drawn\n")
        # identify no-longer loaded submaps and clear their nodes
        for s in rendered_submaps:
            if s not in tmp_rendered_submaps:
                self.clear_node(s.node)
                s.node.removeNode()  # needs to be tested (TODO)
                s.node = None  # if previous line doesn't remove it automatically

        rendered_submaps = tmp_rendered_submaps
        current_submap = submap
        print("Rendered:")
        for s in rendered_submaps:
            print(s, end='')
        print("")

    def clear_node(self, nodepath):
        if not nodepath.isEmpty():
            for model in nodepath.getChildren():
                model.removeNode()

    def clear_all_nodes(self):
        self.clear_node(rendered_submaps[random.randint(
            0, 5)].node)  # temporary madness
        #for n in all_nodes:
        #    self.clear_node(n)
        #    n.remove_node()

    def print_all_nodes(self):
        string = ""
        for n in all_nodes:
            string += str(n) + "; "
        print(string)

    def __init__(self):
        ShowBase.__init__(self)

        # Load Lights
        self.light = LoadLight.Light
        self.light.setupLight(self)

        # Load Environment
        self.model = LoadModel.Model()
        self.model.initialize(self)

        Map.init()
        map_center = (0, 0)
        subprova = Submap.Submap(map_center)
        global stored_submaps_list
        global current_submap
        stored_submaps_list[map_center] = subprova
        current_submap = subprova
        print("stored in init:", stored_submaps_list)
        self.drawMap(subprova)
        """
        self.model.loadAnimal(5,6,0, "bear")
        self.model.loadAnimal(12,-6,0, "cow")
        self.model.loadAnimal(7,-9,0, "panther")
        self.model.loadAnimal(-17,5,0, "rabbit")
        self.model.loadAnimal(-7,5,0, "wolf")
        
        self.model.loadPlant(8,-2,0, "fir")
        self.model.loadPlant(-3,-2,0, "grass")
        self.model.loadPlant(-4,2,0, "oak")
        self.model.loadPlant(-1,17,0, "berry_bush")
        """

        # Text on screen
        self.text_char_pos = None
        self.text_submap = None
        self.text_lock = None

        # Create the main character
        self.char = self.model.loadCharacter(0, 0, 0)

        # 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 char'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.charGroundRay = CollisionRay()
        self.charGroundRay.setOrigin(0, 0, 9)
        self.charGroundRay.setDirection(0, 0, -1)
        self.charGroundCol = CollisionNode('charRay')
        self.charGroundCol.addSolid(self.charGroundRay)
        self.charGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.charGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.charGroundColNp = self.char.attachNewNode(self.charGroundCol)
        self.charGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.charGroundColNp, self.charGroundHandler)

        # Uncomment this line to see the collision rays
        #self.charGroundColNp.show()

        # Uncomment this line to show a visual representation of the
        # collisions occuring
        #self.cTrav.showCollisions(render)

        # This is used to store which keys are currently pressed.
        self.keyMap = {
            "restart": 0,
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-q": 0,
            "cam-w": 0,
            "cam-e": 0,
            "cam-d": 0,
            "cam-s": 0,
            "cam-a": 0
        }

        # Post the instructions
        self.title = addTitle("Isometric HexaMap test")
        self.inst1 = addInstructions(0.06, "[ESC]: Quit")
        self.inst2 = addInstructions(0.12, "[Arrow Keys]: Move char")
        self.inst3 = addInstructions(
            0.18, "[Q,W,E,D,S,A]: Change camera's angle of view")
        #self.inst8 = addInstructions(0.48, "[R]: Restart")

        # Accept the control keys for movement and rotation
        self.accept("escape", sys.exit)
        self.accept("n", self.print_all_nodes)
        self.accept("k", self.clear_all_nodes)
        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("q", self.setKey, ["cam-q", True])
        self.accept("w", self.setKey, ["cam-w", True])
        self.accept("e", self.setKey, ["cam-e", True])
        self.accept("d", self.setKey, ["cam-d", True])
        self.accept("s", self.setKey, ["cam-s", True])
        self.accept("a", self.setKey, ["cam-a", 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("q-up", self.setKey, ["cam-q", False])
        self.accept("w-up", self.setKey, ["cam-w", False])
        self.accept("e-up", self.setKey, ["cam-e", False])
        self.accept("d-up", self.setKey, ["cam-d", False])
        self.accept("s-up", self.setKey, ["cam-s", False])
        self.accept("a-up", self.setKey, ["cam-a", False])
        # self.accept("restart", self.char.setPos(0,0,0))

        self.taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera with isometric perspective
        self.disableMouse()
        lens = OrthographicLens()
        lens.setFilmSize(20, 11.25)
        lens.setNear(-20)
        self.cam.node().setLens(lens)
        self.camera.setPos(self.char.getPos() +
                           (math.sin(cam_angle[cam_view]) * cam_dist,
                            -math.cos(cam_angle[cam_view]) * cam_dist, cam_dz))
        self.camera.lookAt(self.char)

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    def move(self, task):
        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.
        global cam_view
        temp_cam = cam_view
        if self.keyMap["cam-q"]:
            cam_view = 'q'
        if self.keyMap["cam-w"]:
            cam_view = 'w'
        if self.keyMap["cam-e"]:
            cam_view = 'e'
        if self.keyMap["cam-d"]:
            cam_view = 'd'
        if self.keyMap["cam-s"]:
            cam_view = 's'
        if self.keyMap["cam-a"]:
            cam_view = 'a'

        global cam_rotating
        final_angle = int(round((cam_angle[cam_view] * RAD_DEG))) % 360
        current_angle = int(round(self.camera.getH())) % 360

        # Camera rotation task is triggered when a different angle of view is selected.
        # The direction of rotation is chosen by comparing the two angles
        # and changing the sign of the camera rotation angle: cam_delta_angle
        if final_angle != current_angle:
            if not self.taskMgr.hasTaskNamed("SpinCameraTask"):
                global cam_delta_angle
                diff = final_angle - current_angle
                cam_delta_angle = math.copysign(cam_delta_angle, diff)
                if diff > 180:
                    cam_delta_angle = math.copysign(cam_delta_angle, -1)
                elif diff < -180:
                    cam_delta_angle = math.copysign(cam_delta_angle, 1)
                self.taskMgr.doMethodLater(cam_task_time, self.spinCameraTask,
                                           "SpinCameraTask")
            cam_rotating = True

        if not cam_rotating:
            # save char's initial position so that we can restore it,
            # in case he falls off the map or runs into something.
            startpos = self.char.getPos()
            # If a move-key is pressed, turn and move char in the relative direction.
            # The pressure of multiple keys at the same time is handled by the v_rot vector
            # Movements in 2D plane depend on camera's position & orientation
            v_rot = VBase3(0, 0, 0)

            if self.keyMap["forward"]:
                v_rot += (0, 1, 0)
            if self.keyMap["backward"]:
                v_rot += (0, -1, 0)
            if self.keyMap["left"]:
                v_rot += (-v3, 0, 0)
            if self.keyMap["right"]:
                v_rot += (v3, 0, 0)

            if v_rot.normalize():
                self.char.lookAt(self.char.getPos() + v_rot)
                self.char.setH(self.char.getH() + self.camera.getH())
                self.char.setY(self.char, step * dt)

            # Normally, we would have to call traverse() to check for collisions.
            # However, the class ShowBase that we inherit from has a task to do
            # this for us, if we assign a CollisionTraverser to self.cTrav.
            self.cTrav.traverse(render)

            # Adjust char's Z coordinate.  If char'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 = list(self.charGroundHandler.getEntries())
            entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
            if (len(entries) > 0
                    and entries[0].getIntoNode().getName() == "ExaTile"
                    and entries[0].getSurfacePoint(render).getZ() -
                    self.char.getZ() <= CHAR_MAX_ZGAP):
                self.char.setZ(entries[0].getSurfacePoint(render).getZ())
            else:
                self.char.setPos(startpos)

            # Put on screen the lock's value
            #if self.text_lock != None:
            #    self.text_lock.destroy()
            #self.text_lock = addInfo(0.15, "Lock: "+str(Map.new_dir_lock))

            #QUIIIIIII+
            global pix_pos_tmp
            pix_pos = self.char.getPos()

            exa_pos = None

            #if (math.isclose(abs(pix_pos[0])%(apo+0.05), apo, rel_tol=0.05) or math.isclose(abs(pix_pos[1])%(apo+0.05), apo,rel_tol=0.05)):

            exa_pos = -1 / 3 * pix_pos[0] + math.sqrt(
                3) / 3 * pix_pos[1], 2 / 3 * pix_pos[0]

            pix_pos = VBase3(round(exa_pos[0]), round(exa_pos[1]), 0)
            pix_pos += VBase3(0, 0, round(-pix_pos[0] - pix_pos[1]))

            pix_pos_diff = VBase3(abs(pix_pos[0] - exa_pos[0]),
                                  abs(pix_pos[1] - exa_pos[1]),
                                  abs(pix_pos[2] - (-exa_pos[0] - exa_pos[1])))

            if pix_pos_diff[0] > pix_pos_diff[1] and pix_pos_diff[
                    0] > pix_pos_diff[2]:
                pix_pos[0] = -pix_pos[1] - pix_pos[2]
            elif pix_pos_diff[1] > pix_pos_diff[2]:
                pix_pos[1] = -pix_pos[0] - pix_pos[2]
            else:
                pix_pos[2] = -pix_pos[0] - pix_pos[1]

            if pix_pos_tmp != pix_pos:
                direc = pix_pos - pix_pos_tmp
                directions = {
                    VBase3(1, -1, 0): 'q',
                    VBase3(1, 0, -1): 'w',
                    VBase3(0, 1, -1): 'e',
                    VBase3(-1, 1, 0): 'd',
                    VBase3(-1, 0, 1): 's',
                    VBase3(0, -1, 1): 'a'
                }
                Map.menu(directions.get(direc))
                print(Map.position)
                #print(self.char.getPos())
                if self.text_char_pos != None:
                    self.text_char_pos.destroy()
                self.text_char_pos = addInfo(
                    0, "Char position: (" + str(round(self.char.getX(), 2)) +
                    " , " + str(round(self.char.getY(), 2)) + ")")

                #Map.new_dir_lock=False
                # New submap check
                if Map.new_dir != None:
                    global current_submap
                    global new_submap
                    #Map.new_dir_lock=True
                    d = Map.new_dir
                    Map.new_dir = None
                    new_center = (current_submap.centerXY[0] + coords[d][0],
                                  current_submap.centerXY[1] + coords[d][1])
                    for c, s in stored_submaps_list.items():
                        if math.isclose(c[0], new_center[0],
                                        abs_tol=0.1) and math.isclose(
                                            c[1], new_center[1], abs_tol=0.1):
                            new_submap = s
                            break
                    self.drawMap(
                        new_submap
                    )  # TODO: maybe we can give direction as parameter
                    global rendered_submaps
                    print("Rendered.length = " + str(len(rendered_submaps)))

            pix_pos_tmp = pix_pos

            #Map.position= l_map.findXel()

            #print(Exa.Exa(pix_pos[0], pix_pos[1], -pix_pos[2]))

            # Camera position handling: it depends on char's position
            self.camera.setX(self.char.getX() +
                             math.sin(current_angle * DEG_RAD) * cam_dist)
            self.camera.setY(self.char.getY() -
                             math.cos(current_angle * DEG_RAD) * cam_dist)
            self.camera.setZ(self.char.getZ() + cam_dz)

            self.camera.lookAt(self.char)

        else:  # cam is rotating
            if final_angle == current_angle:
                print("CAM IN PLACE!")
                self.taskMgr.remove("SpinCameraTask")
                cam_rotating = False
        #print("curr: ", self.camera.getH())
        #print("dest: ", cam_angle[cam_view]*RAD_DEG)
        return task.cont

    # Task to animate the camera when user changes the angle of view.
    # Make the camera rotate counterclockwise around the character in x,y plane
    def spinCameraTask(self, task):
        angle_deg = int(round(self.camera.getH())) + cam_delta_angle
        angle_rad = angle_deg * DEG_RAD
        delta_v = VBase3(self.char.getX() + cam_dist * math.sin(angle_rad),
                         self.char.getY() - cam_dist * math.cos(angle_rad),
                         self.camera.getZ())
        self.camera.setPos(delta_v)
        self.camera.lookAt(self.char)
        return task.done

    def restartGame(self):
        pass
Exemplo n.º 57
0
class World(DirectObject):
    def __init__(self):
        #create Queue to hold the incoming chat
        #request the heartbeat so that the caht interface is being refreshed in order to get the message from other player

        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "cam-left": 0,
            "cam-right": 0,
            "charge": 0
        }
        base.win.setClearColor(Vec4(0, 0, 0, 1))

        self.cManager = ConnectionManager()
        self.cManager.startConnection()
        #------------------------------
        #Chat
        Chat(self.cManager)

        #send dummy login info of the particular client
        #send first chat info
        #---------------------------------------
        self.userName = username
        dummy_login = {
            'user_id': self.userName,
            'factionId': faction,
            'password': '******'
        }
        self.cManager.sendRequest(Constants.RAND_STRING, dummy_login)

        chat = {
            'userName': self.userName,  #username
            'message': '-------Login------'
        }
        self.cManager.sendRequest(Constants.CMSG_CHAT, chat)

        #--------------------------------------
        #self.minimap = OnscreenImage(image="images/minimap.png", scale=(0.2,1,0.2), pos=(-1.1,0,0.8))

        #frame = DirectFrame(text="Resource Bar", scale=0.001)

        resource_bar = DirectWaitBar(text="",
                                     value=35,
                                     range=100,
                                     pos=(0, 0, 0.9),
                                     barColor=(255, 255, 0, 1),
                                     frameSize=(-0.3, 0.3, 0, 0.03))
        cp_bar = DirectWaitBar(text="",
                               value=70,
                               range=100,
                               pos=(1.0, 0, 0.9),
                               barColor=(0, 0, 255, 1),
                               frameSize=(-0.3, 0.3, 0, 0.03),
                               frameColor=(255, 0, 0, 1))

        # 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)
        self.environ.setPos(0, 0, 0)

        # 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)

        nameplate = TextNode('textNode username_' + str(self.userName))
        nameplate.setText(self.userName)
        npNodePath = self.ralph.attachNewNode(nameplate)
        npNodePath.setScale(0.8)
        npNodePath.setBillboardPointEye()
        #npNodePath.setPos(1.0,0,6.0)
        npNodePath.setZ(6.5)

        bar = DirectWaitBar(value=100, scale=1.0)
        bar.setColor(255, 0, 0)
        #bar.setBarRelief()
        bar.setZ(6.0)
        bar.setBillboardPointEye()
        bar.reparentTo(self.ralph)

        # 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("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("a", self.setKey, ["cam-left", 1])
        self.accept("s", self.setKey, ["cam-right", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("a-up", self.setKey, ["cam-left", 0])
        self.accept("s-up", self.setKey, ["cam-right", 0])
        self.accept("c", self.setKey, ["charge", 1])
        self.accept("c-up", self.setKey, ["charge", 0])

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera

        base.disableMouse()
        base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)

        # 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

    # 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())
        if (self.keyMap["right"] != 0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"] != 0):
            self.ralph.setY(self.ralph, -25 * globalClock.getDt())
        if (self.keyMap["charge"] != 0):
            self.ralph.setY(self.ralph, -250 * globalClock.getDt())
            #ribbon = Ribbon(self.ralph, Vec4(1,1,1,1), 3, 10, 0.3)
            #ribbon.getRoot().setZ(2.0)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"] != 0) or (self.keyMap["charge"] != 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)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        if (len(entries) > 0) and (entries[0].getIntoNode().getName()
                                   == "terrain"):
            self.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)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))
        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
Exemplo n.º 58
0
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