def generateToonMoveTrack(self, toon):
     node = NodePath('tempNode')
     displacement = Vec3(toon.getPos(render) - self.getPos(render))
     displacement.setZ(0)
     displacement.normalize()
     movieDistance = self.movieNode.getDistance(self.rotateNode)
     displacement *= movieDistance
     node.reparentTo(render)
     node.setPos(displacement + self.getPos(render))
     node.lookAt(self)
     heading = PythonUtil.fitDestAngle2Src(toon.getH(render),
                                           node.getH(render))
     hpr = toon.getHpr(render)
     hpr.setX(heading)
     finalX = node.getX(render)
     finalY = node.getY(render)
     finalZ = node.getZ(render)
     node.removeNode()
     toonTrack = Sequence(
         Parallel(
             ActorInterval(toon, 'walk', loop=True, duration=1),
             Parallel(
                 LerpPosInterval(toon,
                                 1.0,
                                 Point3(finalX, finalY, toon.getZ(render)),
                                 fluid=True,
                                 bakeInStart=False)),
             LerpHprInterval(toon, 1.0, hpr=hpr)),
         Func(toon.loop, 'neutral'))
     return toonTrack
Exemple #2
0
 def loadImageAsPlane(filepath, yresolution = 600):
     tex = loader.loadTexture(filepath)
     tex.setBorderColor(Vec4(0,0,0,0))
     tex.setWrapU(Texture.WMBorderColor)
     tex.setWrapV(Texture.WMBorderColor)
     cm = CardMaker(filepath + ' card')
     cm.setFrame(-tex.getOrigFileXSize(), tex.getOrigFileXSize(), -tex.getOrigFileYSize(), tex.getOrigFileYSize())
     card = NodePath(cm.generate())
     card.setTransparency(TransparencyAttrib.MAlpha)
     card.setTexture(tex)
     card.setZ(card.getZ()+0.018)
     card.setScale(card.getScale()/ yresolution)
     card.flattenLight() # apply scale
     return card
Exemple #3
0
class Ship:
    def __init__(self, game):

        self.game = game

        self.shipPoint = NodePath(PandaNode("shipFloaterPoint"))
        self.shipPoint.reparentTo(render)

        self.x_pos = 0
        self.z_pos = 0

        self.x_speed = 0
        self.z_speed = 0

        self.x_pid = PID(3.0, 5.0, 1.0)
        self.z_pid = PID(3.0, 5.0, 1.0)

        self.model = Actor("data/ship.egg")

        self.model.setPos(0, 0, 0)
        self.model.setHpr(0, 0, 0)

        self.normal_speed = 3.5
        self.low_speed = 2

        self.speed = self.normal_speed

        self.cool_down = 0.1
        self.last_shoot = 0

        self.keyMap = {
            "up": 0,
            "down": 0,
            "left": 0,
            "right": 0,
            "brake": 0,
            "attack": 0,
        }

        # This list will stored fired bullets.
        self.bullets = []

        self.game.accept("mouse1", self.setKey, ["attack", 1])
        self.game.accept("mouse1-up", self.setKey, ["attack", 0])

        self.game.accept("shift-mouse1", self.setKey, ["attack", 1])
        self.game.accept("shift-mouse1-up", self.setKey, ["attack", 0])

        self.game.accept("x", self.setKey, ["attack", 1])
        self.game.accept("x-up", self.setKey, ["attack", 0])

        self.game.accept("c", self.setKey, ["brake", 1])
        self.game.accept("c-up", self.setKey, ["brake", 0])

        self.game.accept("arrow_up", self.setKey, ["up", 1])
        self.game.accept("arrow_up-up", self.setKey, ["up", 0])

        self.game.accept("arrow_down", self.setKey, ["down", 1])
        self.game.accept("arrow_down-up", self.setKey, ["down", 0])

        self.game.accept("arrow_left", self.setKey, ["left", 1])
        self.game.accept("arrow_left-up", self.setKey, ["left", 0])

        self.game.accept("arrow_right", self.setKey, ["right", 1])
        self.game.accept("arrow_right-up", self.setKey, ["right", 0])

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

    def draw(self):
        self.model.reparentTo(render)

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

        # Movement

        if self.keyMap["brake"]:
            self.speed = self.low_speed
        else:
            self.speed = self.normal_speed

        if self.game.ship_control_type == 0:

            if self.keyMap["up"]:
                self.model.setZ(self.model, self.speed * dt)

            elif self.keyMap["down"]:
                self.model.setZ(self.model, -self.speed * dt)

            if self.keyMap["left"]:
                self.model.setX(self.model, -self.speed * dt)

            elif self.keyMap["right"]:
                self.model.setX(self.model, self.speed * dt)

        elif self.game.ship_control_type == 1:

            self.x_pos = self.shipPoint.getX()
            self.z_pos = self.shipPoint.getZ()

            self.x_pid.setPoint(self.x_pos)
            self.z_pid.setPoint(self.z_pos)

            pid_x = self.x_pid.update(self.model.getX())
            pid_z = self.z_pid.update(self.model.getZ())

            self.x_speed_ = pid_x
            self.z_speed = pid_z

            self.x_speed_ = min(self.speed, self.x_speed_)
            self.x_speed_ = max(-self.speed, self.x_speed_)

            self.z_speed = min(self.speed, self.z_speed)
            self.z_speed = max(-self.speed, self.z_speed)

            self.model.setX(self.model, self.x_speed_ * dt)
            self.model.setZ(self.model, self.z_speed * dt)

        # Shoot

        if self.keyMap["attack"]:
            current_shoot_time = task.time
            if current_shoot_time - self.last_shoot >= self.cool_down:

                self.last_shoot = current_shoot_time

                self.bullet = Bullet(self)

        return task.cont
Exemple #4
0
 def generateNode(self):        
     self.destroy()
     
     self.node = NodePath('gameobjectnode')
     self.node.setTwoSided(True)
     self.node.reparentTo(self.parent.node)
     
     if self.properties['avoidable'] == True:
         self.node.setTag("avoidable", 'true')
     else:
         self.node.setTag("avoidable", 'false')
     
     #setting scripting part
     self.node.setTag("onWalked", self.onWalked)
     self.node.setTag("onPicked", self.onPicked)
     #set unique id
     self.node.setTag("id", self.properties['id'])
     
     tex = loader.loadTexture(resourceManager.getResource(self.properties['url'])+'.png')
     tex.setWrapV(Texture.WM_clamp)
     tex.setWrapU(Texture.WM_clamp)
     
     #this is true pixel art
     #change to FTLinear for linear interpolation between pixel colors
     tex.setMagfilter(Texture.FTNearest)
     tex.setMinfilter(Texture.FTNearest)
     
     xorig = tex.getOrigFileXSize() / self.baseDimension
     yorig = tex.getOrigFileYSize() / self.baseDimension
     xscaled = (tex.getOrigFileXSize() / self.baseDimension) * self.properties['scale']
     yscaled = (tex.getOrigFileYSize() / self.baseDimension) * self.properties['scale']
     
     self.node.setTag("xscaled", str(xscaled))
     self.node.setTag("yscaled", str(yscaled))
     
     cm = CardMaker("tileobject")
     cm.setFrame(0,xorig,0,yorig)
     
     ts = TextureStage('ts')
     ts.setMode(TextureStage.MDecal)
     
     # distinguish between 3d collisions (for objects with an height and sensible self.properties['inclination'])
     # and 2d collisions for plain sprites
     if self.properties['walkable'] == 'false':
         if self.properties['collisionmode'] == "3d":
             #must handle differently objects which are small and big
             if xscaled < 1:
                 self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
                 
             if xscaled >= 1:
                 self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
             
             self.collisionNode = CollisionNode('objectSphere')
             self.collisionNode.addSolid(self.collisionTube)
             self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
             self.collisionNodeNp.setX(self.properties['offsethorizontal'])
             self.collisionNodeNp.setZ(self.properties['offsetvertical'])
             self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
             self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
             if main.editormode:
                 self.collisionNodeNp.show()
             
         elif self.properties['collisionmode'] == "2d":
             #must handle differently objects which are small and big
             if xscaled < 1:
                 self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3))
                 
             if xscaled >= 1:
                 self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3))
             
             self.collisionNode = CollisionNode('objectSphere')
             self.collisionNode.addSolid(self.collisionTube)
             self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
             self.collisionNodeNp.setP(-(270-int(self.properties['inclination'])))
             self.collisionNodeNp.setX(self.properties['offsethorizontal'])
             self.collisionNodeNp.setZ(self.properties['offsetvertical'])
             self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
             self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
             if main.editormode:
                 self.collisionNodeNp.show()
     
     geomnode = NodePath(cm.generate())
     if geomnode.node().isGeomNode():
         vdata = geomnode.node().modifyGeom(0).modifyVertexData()
         writer = GeomVertexWriter(vdata, 'vertex')
         reader = GeomVertexReader(vdata, 'vertex')
         
         '''
         this part apply rotation flattening to the perspective view
         by modifying directly structure vertices
         '''
         i = 0 #counter
         while not reader.isAtEnd():
             v = reader.getData3f()
             x = v[0]
             y = v[1]
             z = v[2]
             newx = x
             newy = y
             newz = z
             if self.properties['rotation'] == -90.0:
                 if i == 0:
                     newx = math.fabs(math.cos(math.radians(self.properties['inclination']))) * z
                     newz = 0
                     ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z
                     sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen
                     spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen
                     newy -= spercos
                     newz += sparsen
                 if i == 2:
                     newx += math.fabs(math.cos(math.radians(self.properties['inclination']))) * z
                     newz = 0
                     ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z
                     sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen
                     spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen
                     newy -= spercos
                     newz += sparsen
                 writer.setData3f(newx, newy, newz)
             i += 1 #increase vertex counter
     if xscaled >= 1:
         geomnode.setX(0)
     if xscaled < 1:
         geomnode.setX(0.5 - xscaled/2)
     geomnode.setScale(self.properties['scale'])
     geomnode.setX(geomnode.getX()+self.properties['offsethorizontal'])
     geomnode.setZ(geomnode.getZ()+self.properties['offsetvertical'])
     geomnode.setY(-self.properties['elevation'])
     geomnode.setP(int(self.properties['inclination'])-360)
     geomnode.setTexture(tex)
     geomnode.setTransparency(TransparencyAttrib.MAlpha)
     geomnode.reparentTo(self.node)
     self.node.setR(self.properties['rotation'])
Exemple #5
0
class Vehicle(ActorNode):
    def __init__(self, parent=None):
        '''
        Create a new Vehicle node. Physics should be initialized before any
        instances of Vehicle are created.

        arguments:
          parent -- A PandaNode for the vehicle to attach to. Default is None,
                    in which case the Vehicle should be added to the scene
                    graph via NodePath.attachNewNode().

        '''
        ActorNode.__init__(self, 'VehiclePhysics')
        base.physicsMgr.attachPhysicalNode(self)

        self.getPhysicsObject().setMass(MASS)
        if parent:
            self.myPath = parent.attachNewNode(self)
        else:
            self.myPath = NodePath(self)

        # Load vehicle model and place in the transparent bin.
        vehicleModel = loader.loadModel(MODEL_PATH)
        hull = vehicleModel.find('**/Hull')
        hull.setBin('transparent', 30)
        pwnsEnclosure = vehicleModel.find('**/Pwns_Enclosure')
        pwnsEnclosure.setBin('transparent', 30)
        self.myPath.setPos(0, 0, -0.0)
        selectable = self.myPath.attachNewNode(SelectableNode('vehicle sel'))
        vehicleModel.reparentTo(selectable)

        # ==== Initialize Physics ==== #
        thrusterForceNode = ForceNode('ThrusterForce')
        self.myPath.attachNewNode(thrusterForceNode)

        self.linearForce = LinearVectorForce(0, 0, 0)
        self.linearForce.setMassDependent(1)
        self.angularForce = AngularVectorForce(0, 0, 0)

        thrusterForceNode.addForce(self.linearForce)
        thrusterForceNode.addForce(self.angularForce)

        self.getPhysical(0).addLinearForce(self.linearForce)
        self.getPhysical(0).addAngularForce(self.angularForce)

        self.previousXY = (self.myPath.getX(), self.myPath.getY())

        self.tm = ThrusterManager()

        # Add self.updatePhysics to the task manager and run this task as
        # frequently as possible.
        self.updatePhysicsTask = taskMgr.add(self.updatePhysics,
                                             'UpdatePhysics')

        # ==== Initialize Cameras ==== #
        lens = PerspectiveLens()
        lens.setNearFar(0.05, 100.0)
        #Use either FocalLength or Fov. Fov ~40 is about what actual forward cameras are
        #lens.setFocalLength(0.8)
        lens.setFov(70, 70)
        camera = Camera("Forward_left", lens).getPath()
        camera.reparentTo(vehicleModel.find('**/Forward_Camera'))
        camera.setX(camera.getX() - 0.1)  # Forward cameras 20cm apart
        camera.setY(
            camera.getY() +
            0.05)  # Move in front of torpedo tubes to avoid abstruction
        camera.setHpr(0, 0, 0)

        camera = Camera("Forward_right", lens).getPath()
        camera.reparentTo(vehicleModel.find('**/Forward_Camera'))
        camera.setX(camera.getX() + 0.1)  # Forward cameras 20cm apart
        camera.setY(
            camera.getY() +
            0.05)  # Move in front of torpedo tubes to avoid abstruction
        camera.setHpr(0, 0, 0)

        lens = PerspectiveLens()
        lens.setNearFar(0.05, 100.0)
        lens.setFocalLength(0.8)
        camera = Camera("Downward", lens).getPath()
        camera.reparentTo(vehicleModel.find('**/Downward_Camera'))
        camera.setHpr(0, -90, 0)

        #Layout link (to access hydrophone information)
        self.layout = None

        #Hydrophone variables
        self.start_time = time()
        self.last_hydro_update = time()

    def setLayout(self, layout):
        #Add a link to the layout to allow for referencing other objects
        #This is necessary for the hydrophone addition
        self.layout = layout

    def getDepth(self):
        ''' Returns the depth of the vehicle, in meters. '''
        return -0.15 - self.myPath.getZ()

    def getHeading(self):
        ''' Returns the heading of the vehicle, in clockwise degrees. '''
        # Panda uses counter-clockwise degrees, with the range (-180, 180].
        heading = self.myPath.getH()
        if heading < 0:
            return -heading
        elif heading > 0:
            return 360 - heading
        else:
            return 0

    def updatePhysics(self, task):
        '''
        Use the motor PWM values calculated by the controller to apply forces
        to the simulated vehicle.

        This runs at every frame, so it needs to complete quickly.

        '''
        outputs = shm.kalman.get()
        self.tm.update(outputs)
        passive_wrench = vehicle.passive_forces(outputs, self.tm)
        passive_forces, passive_torques = passive_wrench[:3], \
                                          passive_wrench[3:]

        # Get motor thrusts
        thrusts = np.array(self.tm.get_thrusts())

        # Add passive forces and torques to that produced by thrusters,
        # converting them to sub space first.
        force = self.tm.total_thrust(thrusts) + \
                self.tm.orientation.conjugate() * passive_forces
        torque = self.tm.total_torque(thrusts) + \
                self.tm.orientation.conjugate() * passive_torques

        # Finally apply forces and torques to the model
        # we also need to account for panda3d's strange coordinate system
        # (x and y are flipped and z points up (instead of down))
        self.linearForce.setVector(force_subspace[1], \
                                   force_subspace[0], \
                                  -force_subspace[2])

        # We're supposed to use axis angle here, but I'm being sneaky
        # and using the torque vector directly, i.e. non normalized axis angle
        # with the hopes that this LRotationf constructor will figure it out
        self.angularForce.setQuat(\
            LRotationf(LVector3f(torque_subspace[1], \
                                 torque_subspace[0], \
                                -torque_subspace[2]), 1))

        # Update shared variables for controller
        outputs.heading = self.getHeading()
        outputs.pitch = self.myPath.getP()
        outputs.roll = self.myPath.getR()

        # This velocity is in world space
        # We need to put it into THRUST CONVENTION SPACE
        # which we assume kalman outputs in...
        velocity = self.getPhysicsObject().getVelocity()

        # Bring the velocity into THRUST CONVENTION SPACE
        # Don't forget to account for panda's coordinate system
        velocity = self.tm.heading_quat.conjugate() * \
                  np.array((velocity.getY(), velocity.getX(), -velocity.getZ()))

        outputs.velx = velocity[0]
        outputs.vely = velocity[1]
        outputs.depth_rate = velocity[2]

        outputs.depth = self.getDepth()
        outputs.north = self.myPath.getY()
        outputs.east = self.myPath.getX()

        dX = self.myPath.getX() - self.previousXY[0]
        dY = self.myPath.getY() - self.previousXY[1]

        # Forward and sway are in THRUST CONVENTION SPACE
        # don't forget to account for panda's coordinate system
        dF, dS, dD = self.tm.heading_quat.conjugate() * np.array((dY, dX, 0.0))

        outputs.forward += dF
        outputs.sway += dS

        # Output some quaternions, accounting for Panda's coordinate system
        outputs.q0, outputs.q2, outputs.q1, outputs.q3 = self.myPath.getQuat()
        outputs.q3 *= -1.0

        shm.kalman.set(outputs)

        svHeadingInt.set(self.getHeading())
        svDepth.set(self.getDepth())
        #XXX: Approximate altitude assuming that the pool is 12 feet deep
        svAltitude.set(3.6 - self.getDepth())
        svDvlDmgNorth.set(self.myPath.getY())
        svDvlDmgEast.set(self.myPath.getX())

        self.previousXY = (self.myPath.getX(), self.myPath.getY())  #update

        self.output_hydro_data()

        return Task.cont

    def output_hydro_data(self):
        #Update simulated hydrophone values
        pingers = []  #Get all pingers from the layout
        for element in self.layout.elements:
            if element.getTypeName() == "Pinger":
                pingers.append(element)

        HYDRO_TICK_PERIOD = 1

        if time() - self.last_hydro_update > HYDRO_TICK_PERIOD:
            dt = time() - self.last_hydro_update
            self.last_hydro_update = time()

            if shm.hydrophones_settings.dsp_mode.get() == 1:  #Search mode
                #Incr search count
                shm.hydrophones_results.search_count.set(
                    shm.hydrophones_results.search_count.get() + 1)

                #Generate proper "hydrophone bins" marks
                sb = 0
                for p in pingers:
                    f = p.pinger_frequency
                    dc = (f - (shm.hydrophones_settings.searchCenter.get() -
                               shm.hydrophones_settings.searchDelta.get())
                          ) / shm.hydrophones_settings.searchStep.get() + 0.5
                    sb |= 1 << int(dc)
                shm.hydrophones_results.search_bins.set(sb)

            else:  #Track Mode
                #Incr ping count
                shm.hydrophones_results.ping_count.set(
                    shm.hydrophones_results.ping_count.get() + 1)

                #Determine which pinger we are actively tracking (within 0.7khz of target)
                targetp = None
                for p in pingers:
                    if abs(shm.hydrophones_settings.trackFrequency.get() -
                           p.pinger_frequency) < 700:
                        targetp = p

                if targetp is not None:
                    shm.hydrophones_results.intensity.set(
                        int(shm.hydrophones_settings.trackMagThresh.get() +
                            1e4 * random()))
                    shm.hydrophones_results.ping_time.set(int(dt * 1000))

                    pp = targetp.path.getPos()

                    vv = vector.Vector(self.myPath.getY(), self.myPath.getX())
                    pv = vector.Vector(pp.getY(), pp.getX())

                    #heading
                    dv = pv - vv
                    ang = vector.GetAuvAngle(dv)
                    hdiff = helpers.heading_diff(self.getHeading(), ang)

                    shm.hydrophones_results.heading.set(hdiff)

                    #elevation
                    dh = self.myPath.getZ() - pp.getZ()
                    dist = vector.Length(dv)
                    elev = math.degrees(math.atan2(dist, dh))
                    elev = min(elev, 90)

                    shm.hydrophones_results.elevation.set(elev)

                    #phase calculations
                    dy = self.myPath.getY() - pp.getY()
                    dx = self.myPath.getX() - pp.getX()
                    yang = math.degrees(math.atan2(dist, dy))
                    xang = math.degrees(math.atan2(dist, dx))

                    shm.hydrophones_results.phaseX.set((90.0 - xang) / 90.0)
                    shm.hydrophones_results.phaseY.set((90.0 - yang) / 90.0)
                    shm.hydrophones_results.phaseZ.set((90.0 - elev) / 90.0)

                else:
                    shm.hydrophones_results.heading.set(0)
                    shm.hydrophones_results.elevation.set(0)
                    shm.hydrophones_results.intensity.set(0)
                    shm.hydrophones_results.ping_time.set(0)

            shm.hydrophones_results.uptime.set(int(time() - self.start_time))

    def __del__(self):
        ''' Remove update tasks from the panda task manager. '''
        taskMgr.remove(self.updatePhysicsTask)
        ActorNode.__del__(self)
Exemple #6
0
class CameraHandler():
    """Hold the different cameras"""

    def __init__(self, _engine, _mode):
        self.mode = _mode
    	self.engine = _engine
        self.camDummy = None
    	player = self.engine.GameObjects["player"].bulletBody
        if self.mode == "TPA":
            self.initTPAMode(player)
        else:
            self.initTPSMode(player)

    def update(self, dt):
        if self.mode == "TPA":
            self.followPlayerTPA(dt)
        else:
            self.followPlayerTPS(dt)

    def stop(self):
        base.camera.reparentTo(render)
        base.camera.setPos(0,0,0)

    #
    # Third person shooter mode
    #
    def initTPSMode(self, player):
        """Sets the cam mode to a third person shooter mode, so the
        cam will be up and behind the player as well as always look
        in the direction the player faces"""
        # Setup the camera so that its on the player
        self.camDummy = NodePath(PandaNode("camDummy"))
        self.camDummy.reparentTo(player.movementParent)
        self.camDummy.setPos(0, 0, 1.8)
        base.camera.reparentTo(self.camDummy)
        base.camera.setPos(0, -8, 2)

    def followPlayerTPS(self, dt):
    	player = self.engine.GameObjects["player"].bulletBody
        ih = self.engine.inputHandler
        if base.win.movePointer(0, ih.winXhalf, ih.winYhalf) \
               and base.mouseWatcherNode.hasMouse():
            cam = self.camDummy.getP() - (ih.mouseY - ih.winYhalf) * ih.mouseSpeedY
            if cam <-80:
                cam = -80
            elif cam > 90:
                cam = 90
            self.camDummy.setP(cam)
    	base.camera.lookAt(self.camDummy)

    #
    # Third person adventure mode
    #
    def initTPAMode(self, player):
        """Sets the cam mode to a third person adventure mode, so the
        cam will be up and behind the player and will be lazily move
        behind the player."""
        # create a new dummy node that the cam will look at
        self.camDummy = NodePath(PandaNode("camDummy"))
        self.camDummy.reparentTo(render)
        # Setup the camera so that its on the player
        base.camera.reparentTo(self.camDummy)
        base.camera.setPos(player.getX(), player.getY() - 6.0, player.getZ() + 4.0)

    def followPlayerTPA(self, dt):
    	player = self.engine.GameObjects["player"].bulletBody
        base.camera.lookAt(player.getPos())

        ih = self.engine.inputHandler
        if base.win.movePointer(0, ih.winXhalf, ih.winYhalf) \
               and base.mouseWatcherNode.hasMouse():
            omega = (ih.mouseX - ih.winXhalf)*-ih.mouseSpeedX * dt * 0.25
            if omega != 0.0:
                base.camera.setX(base.camera, omega)

        camvec = player.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        minCamDist = 2.0
        maxCamDist = 8.0
        if camdist > maxCamDist:
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-maxCamDist))
            camdist = maxCamDist
        if camdist < minCamDist:
            base.camera.setPos(base.camera.getPos() - camvec*(minCamDist-camdist))
            camdist = minCamDist

        if base.camera.getZ() > self.camDummy.getZ() + 2:
            base.camera.setZ(self.camDummy.getZ() + 2)
        elif base.camera.getZ() < self.camDummy.getZ() + 1:
            base.camera.setZ(self.camDummy.getZ() + 1)

        self.camDummy.setPos(player.getPos())
        self.camDummy.setZ(player.getZ() + 2.0)
        base.camera.lookAt(self.camDummy)
Exemple #7
0
 def generateNode(self):
     self.destroy()
     
     self.node = NodePath('gameobjectnode')
     self.node.setTwoSided(True)
     self.node.reparentTo(self.parent.node)
     
     if self.properties['avoidable'] == True:
         self.node.setTag("avoidable", 'true')
     else:
         self.node.setTag("avoidable", 'false')
     
     #setting scripting part
     self.node.setTag("onWalked", self.onWalked)
     self.node.setTag("onPicked", self.onPicked)
     #set unique id
     self.node.setTag("id", self.properties['id'])
     
     tex = loader.loadTexture(resourceManager.getResource(self.properties['url'])+'.png')
     tex.setWrapV(Texture.WM_clamp)
     tex.setWrapU(Texture.WM_clamp)
     
     #this is true pixel art
     #change to FTLinear for linear interpolation between pixel colors
     tex.setMagfilter(Texture.FTNearest)
     tex.setMinfilter(Texture.FTNearest)
     
     xorig = tex.getOrigFileXSize() / self.baseDimension
     yorig = tex.getOrigFileYSize() / self.baseDimension
     xscaled = (tex.getOrigFileXSize() / self.baseDimension) * self.properties['scale']
     yscaled = (tex.getOrigFileYSize() / self.baseDimension) * self.properties['scale']
     
     self.node.setTag("xscaled", str(xscaled))
     self.node.setTag("yscaled", str(yscaled))
     
     cm = CardMaker("tileobject")
     cm.setFrame(0,xorig,0,yorig)
     
     ts = TextureStage('ts')
     ts.setMode(TextureStage.MDecal)
     
     # distinguish between 3d collisions (for objects with an height and sensible self.properties['inclination'])
     # and 2d collisions for plain sprites
     if self.properties['walkable'] == 'false':
         if self.properties['collisionmode'] == "3d":
             #must handle differently objects which are small and big
             if xscaled < 1:
                 self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
                 
             if xscaled >= 1:
                 self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
             
             self.collisionNode = CollisionNode('objectSphere')
             self.collisionNode.addSolid(self.collisionTube)
             self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
             self.collisionNodeNp.setX(self.properties['offsethorizontal'])
             self.collisionNodeNp.setZ(self.properties['offsetvertical'])
             self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
             self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
             if main.editormode:
                 self.collisionNodeNp.show()
             
         elif self.properties['collisionmode'] == "2d":
             #must handle differently objects which are small and big
             if xscaled < 1:
                 self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2,0,0),LPoint3f(0.5 + xscaled/2,yscaled,0.3))
                 
             if xscaled >= 1:
                 self.collisionTube = CollisionBox(LPoint3f(0,0,0),LPoint3f(xscaled,yscaled,0.3))
             
             self.collisionNode = CollisionNode('objectSphere')
             self.collisionNode.addSolid(self.collisionTube)
             self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
             self.collisionNodeNp.setP(-(270-int(self.properties['inclination'])))
             self.collisionNodeNp.setX(self.properties['offsethorizontal'])
             self.collisionNodeNp.setZ(self.properties['offsetvertical'])
             self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
             self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
             if main.editormode:
                 self.collisionNodeNp.show()
     
     geomnode = NodePath(cm.generate())
     if xscaled >= 1:
         geomnode.setX(0)
     if xscaled < 1:
         geomnode.setX(0.5 - xscaled/2)
     geomnode.setScale(self.properties['scale'])
     geomnode.setX(geomnode.getX()+self.properties['offsethorizontal'])
     geomnode.setZ(geomnode.getZ()+self.properties['offsetvertical'])
     geomnode.setY(-self.properties['elevation'])
     geomnode.setP(-(360-int(self.properties['inclination'])))
     geomnode.setTexture(tex)
     geomnode.setTransparency(TransparencyAttrib.MAlpha)
     geomnode.reparentTo(self.node)
Exemple #8
0
class Player():
	def __init__(self, game, hp, mana, strength, dexterity, vigor, magic):

		self.game = game

		self.ori = 0.0
		self.lastori = -1
		self.zoomLevel = 0.0
		self.nextAttack = 0.0

		self.attacked = False

		# Atributes

		self.hp = hp
		self.mana = mana

		self.strength = strength
		self.dexterity = dexterity
		self.vigor = vigor
		self.magic = magic

		# Atributes calculated

		self.attackDamage = random(1, 7) + self.strength/100				# physical dmg = weapon damage * %str
		self.magicDamage = random(3, 12) + self.magic/100					# magic dmg = skill damage * %magic
		self.speed = 15 + 0													# speed = base speed + item
		self.runSpeed = 25 + 0												# run speed = base speed + item
		self.lateralSpeed = 10												# speed when moving sidewards
		self.lateralRunSpeed = 20											# run speed when moving sidewards
		self.backwardsSpeed = 10											# speed when moving backwards
		self.backwardsRunSpeed = 20											# run speed when moving backwards
		self.defense = 5 + self.vigor/2										# defense = armour + 1/2 vigor
		self.criticalChance = 10 + 0										# crit chance = base item + skill
		self.criticalMultiplier = self.attackDamage*1.5						# crit mult = base item + skill
		self.magicDefense = 2 + self.magic/2								# magic def = base item + 1/2 magic
		self.attackSpeed = (0.2 * self.dexterity) / 60						# attack speed = base * dex / 60


		self.keyMap = {
						"left":0,
						"right":0,
						"forward":0,
						"backward":0,

						"cam-left":0,
						"cam-right":0,

						"jump":0,
						"attack":0,
						"run":0
						}

		# Player Parts

		parts = ["head", "larm", "rarm", "lboot", "rboot", "lleg", "rleg", "lhand", "rhand", "torso"]

		self.previousPart = { name: None for name in parts }

		# Player Models & Animations

		models = { name: "models/hero/%s" % name for name in parts }

		animations = { name:{
								"standby":"models/hero/%s-standby" % name,
								"walk":"models/hero/%s-walk" % name,
								"walk-back":"models/hero/%s-walk-back" % name,
								"walk-side":"models/hero/%s-walk-side" % name,
								"slash-front": "models/hero/%s-slash-front" % name
							} for name in parts
						}

		for itemClass, items in self.game.items["items"].iteritems():
			if itemClass == "armours":
				for itemType, value in items["lightarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["midarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["heavyarmours"].iteritems():
					modelName = value["model"]

					models["torso-%s" % modelName] = "models/hero/torso-%s" % modelName

					animations["torso-%s" % modelName] = {
															"standby":"models/hero/torso-%s-standby" % modelName,
															"walk":"models/hero/torso-%s-walk" % modelName,
															"walk-back":"models/hero/torso-%s-walk-back" % modelName,
															"walk-side":"models/hero/torso-%s-walk-side" % modelName,
															"slash-front":"models/hero/torso-%s-slash-front" % modelName
														}

				for itemType, value in items["helmets"].iteritems():
					modelName = value["model"]

					models["head-%s" % modelName] = "models/hero/head-%s" % modelName

					animations["head-%s" % modelName] = {
															"standby":"models/hero/head-%s-standby" % modelName,
															"walk":"models/hero/head-%s-walk" % modelName,
															"walk-back":"models/hero/head-%s-walk-back" % modelName,
															"walk-side":"models/hero/head-%s-walk-side" % modelName,
															"slash-front":"models/hero/head-%s-slash-front" % modelName
														}



		# Init Actor

		self.playerActor = Actor(models, animations)



		# Hide All Player Parts

		for itemClass, items in self.game.items["items"].iteritems():
			if itemClass == "armours":
				for itemType, value in items["lightarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["midarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["heavyarmours"].iteritems():
					modelName = value["model"]
					self.playerActor.hidePart("torso-%s" % modelName)

				for itemType, value in items["helmets"].iteritems():
					modelName = value["model"]
					self.playerActor.hidePart("head-%s" % modelName)



		#self.playerActor.ls()

		# Shaders

		self.shader = Shader.load("shaders/testShader.sha", Shader.SL_Cg)
		#self.playerActor.setShader(self.shader)

		# End shaders

		self.moveFloater = NodePath(PandaNode("moveFloater"))
		self.moveFloater.reparentTo(render)
		self.moveFloater.setPos(self.game.playerStartPos)

		self.floater = NodePath(PandaNode("floater"))
		self.floater.reparentTo(render)
		#self.floater.setZ(8.0)

		self.playerActor.setHpr(0,0,0)
		self.playerActor.setScale(0.5)

		self.playerActor.reparentTo(self.moveFloater)

		#self.playerHand = self.playerActor.exposeJoint(None, 'body', 'manod')
		#self.playerHead = self.playerActor.controlJoint(None, 'body', 'cabeza')
		#self.playerHead.setScale(10,10,10)

		self.inventory = [["0" for x in range(10)] for x in range(5)]

		#			COLS-ROWS		#			COLS-ROWS
		self.inventory[0][3] = self.game.items["items"]["armours"]["heavyarmours"]["ironplate"]
		self.inventory[0][4] = self.game.items["items"]["armours"]["heavyarmours"]["steelplate"]
		self.inventory[0][5] = self.game.items["items"]["armours"]["heavyarmours"]["cuirass"]
		self.inventory[3][3] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[0][0] = self.game.items["items"]["weapons"]["swords"]["longsword"]
		self.inventory[1][0] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[0][8] = self.game.items["items"]["weapons"]["swords"]["longsword"]
		self.inventory[0][7] = self.game.items["items"]["weapons"]["spears"]["ironspear"]
		self.inventory[3][9] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[1][9] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[1][8] = self.game.items["items"]["armours"]["boots"]["leatherboots"]
		self.inventory[1][7] = self.game.items["items"]["armours"]["helmets"]["woolchaco"]
		self.inventory[0][6] = self.game.items["items"]["armours"]["helmets"]["goldencrown"]
		self.inventory[0][8] = self.game.items["items"]["armours"]["helmets"]["ironhelmet"]
		self.inventory[1][6] = self.game.items["items"]["armours"]["cloacks"]["woolcloack"]
		self.inventory[2][9] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[2][8] = self.game.items["items"]["armours"]["boots"]["leatherboots"]
		self.inventory[2][7] = self.game.items["items"]["armours"]["helmets"]["woolchaco"]
		self.inventory[2][6] = self.game.items["items"]["armours"]["cloacks"]["woolcloack"]
		self.inventory[2][5] = self.game.items["items"]["armours"]["gloves"]["woolgloves"]
		self.inventory[1][5] = self.game.items["items"]["armours"]["gloves"]["woolgloves"]
		self.inventory[2][4] = self.game.items["items"]["accesories"]["rings"]["simplering"]
		self.inventory[1][4] = self.game.items["items"]["accesories"]["rings"]["simplering"]
		self.inventory[2][3] = self.game.items["items"]["accesories"]["trinkets"]["rubyamulet"]
		self.inventory[1][3] = self.game.items["items"]["accesories"]["trinkets"]["rubyamulet"]
		self.inventory[2][2] = self.game.items["items"]["armours"]["shields"]["ironshield"]
		self.inventory[1][2] = self.game.items["items"]["armours"]["shields"]["ironshield"]

		self.equip = {
						"armour":None,
						"helmet":None,
						"gloves":None,
						"boots":None,

						"cloack":None,

						"ringLeft":None,
						"ringRight":None,
						"trinket":None,

						"weapon":None,
						"weaponLeft":None,
						"weaponRight":None,

						"shield":None
					}

		self.models = []                 #A list that will store our models objects
		items = [("models/sword1", (0.0, 0.6, 1.5), (0,-90,0), 0.2),
				("models/maze", (0.0, 0.6, -1.5), (0,90,0), 0.2)]
		"""
		for row in items:
			np = self.game.loader.loadModel(row[0])				#Load the model
			np.setPos(row[1][0], row[1][1], row[1][2])		#Position it
			np.setHpr(row[2][0], row[2][1], row[2][2])		#Rotate it
			np.setScale(row[3])								#Scale it
			np.reparentTo(self.playerHand)
			#weaponNP.reparentTo(self.playerHand)
			self.models.append(np)							#Add it to our models list
		"""


		self.item = 0
		
		self.isMovingForward = False
		self.isMovingBackward = False
		self.isMovingSideRight = False
		self.isMovingSideLeft = False
		
		self.isMovingForwardLeft = False
		self.isMovingForwardRight = False
		
		self.isMovingSideRightUp = False
		self.isMovingSideRightDown = False
		
		self.isMovingSideLeftUp = False
		self.isMovingSideLeftDown = False
		
		self.isMovingBackwardLeft = False
		self.isMovingBackwardRight = False
		
		self.isAttacking = False

		self.setupControls()
		self.setupCamera()

		self.playerActor.loop("standby", "head")

		self.game.taskMgr.add(self.checkEquip, "checkTorsoTask", extraArgs=["torso", "armour"], appendTask=True)
		self.game.taskMgr.add(self.checkEquip, "checkHeadTask", extraArgs=["head", "helmet"], appendTask=True)

	def update(self, task):
		self.playerActor.setShaderInput("timer", task.time)
		return task.cont

	def checkEquip(self, partName, equipPart, task):

		# Check Equiped Parts

		if self.previousPart[partName] != self.equip[equipPart]:
			if self.equip[equipPart] != None and self.previousPart[partName] == None:
				self.playerActor.hidePart(partName)
				self.playerActor.showPart("%s-%s" % (partName, self.equip[equipPart]["model"]))
				self.previousPart[partName] = self.equip[equipPart]

			elif self.equip[equipPart] != None and self.previousPart[partName] != None:
				self.playerActor.hidePart("%s-%s" % (partName, self.previousPart[partName]["model"]))
				self.playerActor.showPart("%s-%s" % (partName, self.equip[equipPart]["model"]))
				self.previousPart[partName] = self.equip[equipPart]


			elif self.equip[equipPart] == None:
				self.playerActor.hidePart("%s-%s" % (partName, self.previousPart[partName]["model"]))
				self.playerActor.showPart(partName)
				self.previousPart[partName] = None

		return task.cont

	def setupCamera(self):

		self.game.disableMouse()
		self.game.camera.setPos(self.playerActor.getPos()+50)

		self.lens = OrthographicLens()
		self.lens.setFilmSize(45+self.zoomLevel, 35+self.zoomLevel)  # Or whatever is appropriate for your scene

		self.game.cam.node().setLens(self.lens)

		self.game.camLens.setFov(120)

	def setupControls(self):

		self.game.accept("a", self.setKey, ["left",1])
		self.game.accept("shift-a", self.setKey, ["left",1])
		self.game.accept("d", self.setKey, ["right",1])
		self.game.accept("shift-d", self.setKey, ["right",1])
		self.game.accept("w", self.setKey, ["forward",1])
		self.game.accept("shift-w", self.setKey, ["forward",1])
		self.game.accept("s", self.setKey, ["backward",1])
		self.game.accept("shift-s", self.setKey, ["backward",1])

		self.game.accept("a-up", self.setKey, ["left",0])
		self.game.accept("d-up", self.setKey, ["right",0])
		self.game.accept("w-up", self.setKey, ["forward",0])
		self.game.accept("s-up", self.setKey, ["backward",0])

		self.game.accept("mouse1", self.setKey, ["attack",1])
		self.game.accept("mouse1-up", self.setKey, ["attack",0])

		self.game.accept("shift-mouse1", self.setKey, ["attack",1])
		self.game.accept("shift-mouse1-up", self.setKey, ["attack",0])

		#self.game.accept("q", self.setKey, ["cam-left",1])
		#self.game.accept("e", self.setKey, ["cam-right",1])

		#self.game.accept("q-up", self.setKey, ["cam-left",0])
		#self.game.accept("e-up", self.setKey, ["cam-right",0])

		self.game.accept("space", self.setKey, ["jump",1])
		self.game.accept("space-up", self.setKey, ["jump",0])


		self.game.accept("shift", self.setKey, ["run",1])
		self.game.accept("shift-up", self.setKey, ["run",0])

		self.game.accept("wheel_up", self.moveCam, [1])
		self.game.accept("wheel_down", self.moveCam, [0])

		self.game.accept("shift-wheel_up", self.moveCam, [1])
		self.game.accept("shift-wheel_down", self.moveCam, [0])

		self.game.accept("t", self.toggleObject)

	def moveCam(self, zoom):
		if zoom == 0:
			self.zoomLevel += 5
			#if self.zoomLevel >= 30:
				#self.zoomLevel = 30

		elif zoom == 1:
			self.zoomLevel -= 5
			if self.zoomLevel <= 0:
				self.zoomLevel = 0

		#print self.zoomLevel
		self.lens.setFilmSize(45+self.zoomLevel, 35+self.zoomLevel)
		self.game.cam.node().setLens(self.lens)

	#def checkAttack(self):
		#animControl = self.playerActor.getAnimControl('slash', "body")

		#return animControl.isPlaying()


	def attack(self):
		if self.isAttacking is False:
			self.playerActor.play("slash-front")
			self.isAttacking = True

		self.isAttacking = False


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

	def setObject(self, i):
		for np in self.models: np.hide()
		self.models[i].show()
		self.item = i

	def toggleObject(self):

		if self.item == 1:
			self.item = 0
		else:
			self.item = 1

		for np in self.models: np.hide()
		self.models[self.item].show()

	def move(self, task):

		#self.playerActor.setPos(self.moveFloater.getPos())
		#self.playerActor.setZ(self.moveFloater.getZ())

		dt = globalClock.getDt()
		speed = 0

		if (self.keyMap["left"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(2.0, 'walk-side')
			else:
				speed = self.speed
				#self.playerActor.setPlayRate(1.0, 'walk-side')

			self.moveFloater.setX(self.moveFloater, speed * dt)
			self.moveFloater.setY(self.moveFloater, -speed * dt)

		if (self.keyMap["right"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(2.0, 'walk-side')
			else:
				speed = self.lateralSpeed
				#self.playerActor.setPlayRate(1.0, 'walk-side')

			self.moveFloater.setX(self.moveFloater, -speed * dt)
			self.moveFloater.setY(self.moveFloater, speed * dt)


		if (self.keyMap["forward"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(1.5, 'walk')
			else:
				speed = self.speed
				#self.playerActor.setPlayRate(1.0, 'walk')

			self.moveFloater.setY(self.moveFloater, -speed * dt)
			self.moveFloater.setX(self.moveFloater, -speed * dt)


		if (self.keyMap["backward"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(2.0, 'walk-back')
			else:
				speed = self.speed
				#self.playerActor.setPlayRate(1.0, 'walk-back')

			self.moveFloater.setY(self.moveFloater, speed * dt)
			self.moveFloater.setX(self.moveFloater, speed * dt)

		if (self.keyMap["attack"])  and (task.time > self.nextAttack):
			self.attack()
			self.nextAttack = task.time + self.attackSpeed
		self.keyMap["attack"] = 0


		"""
		if self.lastori != self.ori :
			turn = Sequence(LerpQuatInterval(self.playerActor, duration=0.05,  hpr=Vec3(self.ori, 0, 0), blendType='easeOut')).start()
			self.lastori = self.ori
		"""

		self.playerActor.headsUp(self.game.lookPoint)
		self.playerActor.setH(self.playerActor.getH()-180)

		#print(self.playerActor.getH())

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

		if self.keyMap["forward"] and self.keyMap["right"]:

			if ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
					
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
					
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")
					
					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
					
				if self.isMovingSideLeft is False:
					
					if (self.keyMap["run"]):
						self.playerActor.setPlayRate(2.0, 'walk-side')
					else:
						self.playerActor.setPlayRate(1.0, 'walk-side')
					
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
		
		elif self.keyMap["right"] and self.keyMap["backward"]:

			if ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
		
		elif self.keyMap["backward"] and self.keyMap["left"]:

			if ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
		
		elif self.keyMap["left"] and self.keyMap["forward"]:

			if (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
					
		elif self.keyMap["forward"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

		elif self.keyMap["backward"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

		elif self.keyMap["left"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

		elif self.keyMap["right"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

		else:
			if self.isMovingForward or self.isMovingBackward or self.isMovingSideLeft or self.isMovingSideRight:
				self.playerActor.stop()
				self.playerActor.loop("standby")
				self.isMovingForward = False
				self.isMovingBackward = False
				self.isMovingSideLeft = False
				self.isMovingSideRight = False

		return task.cont


	def updateCamera(self, task):

		self.floater.setPos(self.moveFloater.getPos())
		self.floater.setZ(self.moveFloater.getZ() + 2.0)

		self.game.camera.setPos(self.floater.getPos()+50)
		# 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.game.camera.lookAt(self.floater)

		return task.cont
Exemple #9
0
class Ship:

    def __init__(self, game):

        self.game = game

        self.shipPoint = NodePath(PandaNode("shipFloaterPoint"))
        self.shipPoint.reparentTo(render)

        self.x_pos = 0
        self.z_pos = 0

        self.x_speed = 0
        self.z_speed = 0

        self.x_pid = PID(3.0, 5.0, 1.0)
        self.z_pid = PID(3.0, 5.0, 1.0)

        self.model = Actor("data/ship.egg")

        self.model.setPos(0, 0, 0)
        self.model.setHpr(0, 0, 0)

        self.normal_speed = 3.5
        self.low_speed = 2

        self.speed = self.normal_speed

        self.cool_down = 0.1
        self.last_shoot = 0

        self.keyMap = {

            "up": 0,
            "down": 0,
            "left": 0,
            "right": 0,

            "brake": 0,

            "attack": 0,
        }

        # This list will stored fired bullets.
        self.bullets = []

        self.game.accept("mouse1", self.setKey, ["attack", 1])
        self.game.accept("mouse1-up", self.setKey, ["attack", 0])

        self.game.accept("shift-mouse1", self.setKey, ["attack", 1])
        self.game.accept("shift-mouse1-up", self.setKey, ["attack", 0])

        self.game.accept("x", self.setKey, ["attack", 1])
        self.game.accept("x-up", self.setKey, ["attack", 0])

        self.game.accept("c", self.setKey, ["brake", 1])
        self.game.accept("c-up", self.setKey, ["brake", 0])

        self.game.accept("arrow_up", self.setKey, ["up", 1])
        self.game.accept("arrow_up-up", self.setKey, ["up", 0])

        self.game.accept("arrow_down", self.setKey, ["down", 1])
        self.game.accept("arrow_down-up", self.setKey, ["down", 0])

        self.game.accept("arrow_left", self.setKey, ["left", 1])
        self.game.accept("arrow_left-up", self.setKey, ["left", 0])

        self.game.accept("arrow_right", self.setKey, ["right", 1])
        self.game.accept("arrow_right-up", self.setKey, ["right", 0])

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

    def draw(self):
        self.model.reparentTo(render)

        self.p = ParticleEffect()
        self.p.loadConfig(Filename('data/particles/fireish.ptf'))

        self.p.setR(180)
        self.p.setScale(0.25)
        # Sets particles to birth relative to the teapot, but to render at
        # toplevel
        self.p.start(self.model)
        self.p.setPos(0.000, 0.000, 0.000)

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

        if self.model:

            # Movement

            if self.keyMap["brake"]:
                self.speed = self.low_speed
            else:
                self.speed = self.normal_speed

            if self.game.ship_control_type == 0:

                if self.keyMap["up"]:
                    self.model.setZ(self.model, self.speed * dt)

                elif self.keyMap["down"]:
                    self.model.setZ(self.model, -self.speed * dt)

                if self.keyMap["left"]:
                    self.model.setX(self.model, -self.speed * dt)

                elif self.keyMap["right"]:
                    self.model.setX(self.model, self.speed * dt)

            elif self.game.ship_control_type == 1:

                self.x_pos = self.shipPoint.getX()
                self.z_pos = self.shipPoint.getZ()

                self.x_pid.setPoint(self.x_pos)
                self.z_pid.setPoint(self.z_pos)

                pid_x = self.x_pid.update(self.model.getX())
                pid_z = self.z_pid.update(self.model.getZ())

                self.x_speed = pid_x
                self.z_speed = pid_z

                self.x_speed = min(self.speed, self.x_speed)
                self.x_speed = max(-self.speed, self.x_speed)

                self.z_speed = min(self.speed, self.z_speed)
                self.z_speed = max(-self.speed, self.z_speed)

                self.model.setX(self.model, self.x_speed * dt)
                self.model.setZ(self.model, self.z_speed * dt)

            self.model.setR(self.x_speed)

            # Shoot

            if self.keyMap["attack"]:
                current_shoot_time = task.time
                if current_shoot_time - self.last_shoot >= self.cool_down:

                    self.last_shoot = current_shoot_time

                    self.bullet = Bullet(self)

        return task.cont
Exemple #10
0
class Player(object):
    """
        Player is the main actor in the fps game
    """
    FORWARD = Vec3(0,2,0)
    BACK = Vec3(0,-1,0)
    LEFT = Vec3(-1,0,0)
    RIGHT = Vec3(1,0,0)
    FLYUP = Vec3(0,0,1)
    FLYDN = Vec3(0,0,-1)
    STOP = Vec3(0)
    PORTAL_CYCLE = {
        'blue' : 'orange',
        'orange' : 'blue',
        }

    def __init__(self, base, fps, osd):
        self.base = base
        self.fps = fps
        self.osd = osd
        self.speed = RUN_SPEED
        self.walk = self.STOP
        self.readyToJump = False
        self.intoPortal = None
        self.mass = Mass()
        self.origin = self.fps.level.settings.origin
        self.bporigin = (999,999,999)
        self.oporigin = (999,999,999)
        self.current_target = None
        self.canPortal = []
        self.canSetTarget = True
        self.selectedCubes = []
        self.editorTextureStage = TextureStage('editor')
        self.editorSelectedTexture = loader.loadTexture('models/tex/selected.png')
        self.selectingForMulti = False
        # Init functions
        self.loadModel()
        self.makePortals()
        self.setUpCamera()
        if self.fps.editor_mode:
            self.createMouseCollisions()
            self.speed = self.speed * 5
            self.attachEditorControls()
            self.attachEditorTasks()
        else:
            self.createCollisions()
            self.attachStandardControls()
            self.attachStandardTasks()

    def loadModel(self):
        """ make the nodepath for player """
        self.node = NodePath('player')
        self.node.reparentTo(render)
        self.node.setPos(*self.origin)
        self.node.setScale(0.05)
        self.mass.pos = VBase3(self.node.getX(), self.node.getY(), self.node.getZ())

    def makePortals(self):
        # The BLUE CUBE
        bpor = loader.loadModel("cube_nocol")
        bpor.setTag('noportals', '1')
        bpor.reparentTo(render)
        bpor.setPos(*self.bporigin)
        bpor.setScale(0.3,0.02,0.5)
        # The BLUE CUBE's camera
        bbuffer = self.base.win.makeTextureBuffer("B Buffer", 512, 512)
        bbuffer.setSort(-100)
        bcamera = self.base.makeCamera(bbuffer)
        bcamera.node().getLens().setAspectRatio(0.3/0.5)
        bcamera.node().getLens().setFov(15)
        bcamera.reparentTo(bpor)
        bcamera.node().setScene(render)

        # The ORANGE CUBE
        opor = loader.loadModel("cube_nocol")
        opor.setTag('noportals', '1')
        opor.reparentTo(render)
        opor.setPos(*self.oporigin)
        opor.setScale(0.3,0.02,0.5)
        # The ORANGE CUBE's camera
        obuffer = self.base.win.makeTextureBuffer("O Buffer", 512, 512)
        obuffer.setSort(-100)
        ocamera = self.base.makeCamera(obuffer)
        ocamera.node().getLens().setAspectRatio(0.3/0.5)
        ocamera.node().getLens().setFov(15)
        ocamera.reparentTo(opor)
        ocamera.node().setScene(render)

        # Assign the textures
        bpor.setTexture(obuffer.getTexture())
        opor.setTexture(bbuffer.getTexture())
        # Store the portals and theirs cameras
        self.bluePortal = bpor
        self.bluePortal.setHpr(0,90,0)
        self.orangePortal = opor
        self.orangePortal.setHpr(0,-90,0)
        self.bcamera = bcamera
        self.ocamera = ocamera

    def setUpCamera(self):
        """ puts camera at the players node """
        pl =  self.base.cam.node().getLens()
        pl.setFov(70)
        self.base.cam.node().setLens(pl)
        self.base.camera.reparentTo(self.node)
        self.base.camLens.setFov(100)
        if self.fps.editor_mode:
            self.node.lookAt(self.fps.level.cubes_hash.keys()[0])

    def createCollisions(self):
        self.createPlayerCollisions()
        self.createMouseCollisions()
        self.createPortalCollisions()

    def createPlayerCollisions(self):
        """ create a collision solid and ray for the player """
        cn = CollisionNode('player')
        cn.setFromCollideMask(COLLISIONMASKS['geometry'])
        cn.setIntoCollideMask(COLLISIONMASKS['portals'] | COLLISIONMASKS['exit'] | COLLISIONMASKS['lava'])
        cn.addSolid(CollisionSphere(0,0,0,3))
        solid = self.node.attachNewNode(cn)
        # TODO : find a way to remove that, it's the cause of the little
        # "push me left" effect we see sometime when exiting a portal
        self.base.cTrav.addCollider(solid,self.base.pusher)
        self.base.pusher.addCollider(solid,self.node, self.base.drive.node())
        # init players floor collisions
        ray = CollisionRay()
        ray.setOrigin(0,0,-.2)
        ray.setDirection(0,0,-1)
        cn = CollisionNode('playerRay')
        cn.setFromCollideMask(COLLISIONMASKS['player'])
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.addSolid(ray)
        solid = self.node.attachNewNode(cn)
        self.nodeGroundHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(solid, self.nodeGroundHandler)
        # init players ceil collisions
        ray = CollisionRay()
        ray.setOrigin(0,0,.2)
        ray.setDirection(0,0,1)
        cn = CollisionNode('playerUpRay')
        cn.setFromCollideMask(COLLISIONMASKS['player'])
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.addSolid(ray)
        solid = self.node.attachNewNode(cn)
        self.ceilGroundHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(solid, self.ceilGroundHandler)

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

    def createPortalCollisions(self):
        # Enter the portals
        cn = CollisionNode('bluePortal')
        cn.setFromCollideMask(COLLISIONMASKS['portals'])
        cn.setIntoCollideMask(BitMask32.allOff())
        np = self.bluePortal.attachNewNode(cn)
        cn.addSolid(CollisionSphere(0,0,0,2))
        h = CollisionHandlerEvent()
        h.addInPattern('%fn-into-%in')
        h.addOutPattern('%fn-outof-%in')
        self.base.cTrav.addCollider(np, h)
        cn = CollisionNode('orangePortal')
        cn.setFromCollideMask(COLLISIONMASKS['portals'])
        cn.setIntoCollideMask(BitMask32.allOff())
        np = self.orangePortal.attachNewNode(cn)
        cn.addSolid(CollisionSphere(0,0,0,2))
        h = CollisionHandlerEvent()
        h.addInPattern('%fn-into-%in')
        h.addOutPattern('%fn-outof-%in')
        self.base.cTrav.addCollider(np, h)

    def attachCommonControls(self):
        self.base.accept( "z" if AZERTY else "w" , self.addWalk,[self.FORWARD])
        self.base.accept( "z-up" if AZERTY else "w-up" , self.addWalk,[-self.FORWARD] )
        self.base.accept( "s" , self.addWalk,[self.BACK] )
        self.base.accept( "s-up" , self.addWalk,[-self.BACK] )
        self.base.accept( "q" if AZERTY else "a" , self.addWalk,[self.LEFT])
        self.base.accept( "q-up" if AZERTY else "a-up" , self.addWalk,[-self.LEFT] )
        self.base.accept( "d" , self.addWalk,[self.RIGHT] )
        self.base.accept( "d-up" , self.addWalk,[-self.RIGHT] )
        self.base.accept( "r-up" , self.resetPosition )
        self.base.accept( "p-up" , self.showPosition )
        self.base.accept( "b-up" , self.deBug )

    def attachStandardControls(self):
        self.attachCommonControls()
        self.base.accept( "space" , self.__setattr__,["readyToJump",True])
        self.base.accept( "space-up" , self.__setattr__,["readyToJump",False])
        self.base.accept( "c-up" , self.__setattr__,["intoPortal",None] )
        self.base.accept( "e-up" , self.erasePortals )
        self.base.accept( "mouse1" , self.fireBlue )
        self.base.accept( "mouse3" , self.fireOrange )
        # Events
        self.base.accept( "bluePortal-into-player" , self.enterPortal, ["blue"] )
        self.base.accept( "orangePortal-into-player" , self.enterPortal, ["orange"] )
        self.base.accept( "bluePortal-outof-player" , self.exitPortal, ["blue"] )
        self.base.accept( "orangePortal-outof-player" , self.exitPortal, ["orange"] )
        self.base.accept( "levelExit-into-player" , self.levelExit)
        self.base.accept( "lava-into-player" , self.fallIntoLava)

    def attachStandardTasks(self):
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveUpdate, 'move-task')
        taskMgr.add(self.jumpUpdate, 'jump-task')

    def attachEditorControls(self):
        self.attachCommonControls()
        self.base.accept( "space" , self.__setattr__, ['selectingForMulti', 1])
        self.base.accept( "space-up" , self.__setattr__, ['selectingForMulti', 0])
        self.base.accept( "shift-space" , self.__setattr__, ['selectingForMulti', 2])
        self.base.accept( "shift-space-up" , self.__setattr__, ['selectingForMulti', 0])
        self.base.accept( "c-up" , self.clearMultiSelectedCubes)
        self.base.accept( "mouse1" , self.selectCubeForCopy, [1])
        self.base.accept( "wheel_up" , self.selectCubeForChange, [1] )
        self.base.accept( "wheel_down" , self.selectCubeForChange, [-1] )
        self.base.accept( "mouse3" , self.selectCubeForDelete )
        self.base.accept("f11", self.saveLevel)
        self.base.accept("x", self.selectCubeForRectangle)
        self.base.accept("shift-x", self.selectCubeForRectangle, [True])
        self.base.accept("l", self.addLightHere)
        self.base.accept("u", self.fps.level.undo, [1])
        for i in range(1,10):
            self.base.accept( "%i-up" % (i,), self.selectCubeForCopy, [i])
        for key, vec in [("a" if AZERTY else "q", self.FLYUP),("w" if AZERTY else "z", self.FLYDN)]:
            self.base.accept(key, self.addWalk, [vec])
            self.base.accept(key + "-up", self.addWalk, [-vec])

    def attachEditorTasks(self):
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveInEditor, 'move-task')

    def deBug(self):
        import pdb
        pdb.set_trace()
    def showPosition(self):
        print self.node.getPos()
        print self.mass
    def fallIntoLava(self, *args, **kwargs):
        # TODO : sound and message + little delay
        self.erasePortals()
        self.resetPosition()
    def resetPosition(self, *args, **kwargs):
        self.node.setHpr(VBase3(0,0,0))
        self.mass.pos = VBase3(*self.origin)
        self.mass.vel = VBase3(0,0,0)
        self.mass.force = VBase3(0,0,0)
        self.node.setPos(self.mass.pos)
    def erasePortals(self):
        self.bluePortal.setPos(*self.bporigin)
        self.orangePortal.setPos(*self.oporigin)
        self.bluePortal.detachNode()
        self.orangePortal.detachNode()
        self.intoPortal = None
        self.canPortal = []
    #@oldpostracker
    def mouseUpdate(self,task):
        """ this task updates the mouse """
        md = self.base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if self.base.win.movePointer(0, self.base.win.getXSize()/2, self.base.win.getYSize()/2):
            self.node.setH(self.node.getH() -  (x - self.base.win.getXSize()/2)*0.1)
            if self.fps.editor_mode:
                self.node.setP(self.node.getP() - (y - self.base.win.getYSize()/2)*0.1)
            else:
                self.base.camera.setP(self.base.camera.getP() - (y - self.base.win.getYSize()/2)*0.1)
            self.canSetTarget = True
            self.bcamera.lookAt(self.bluePortal, self.node.getPos(self.orangePortal))
            self.ocamera.lookAt(self.orangePortal, self.node.getPos(self.bluePortal))
            #self.canPortal = ['blue','orange']
            if self.fps.editor_mode:
                cube, point, normal = self.selectCube()
                self.osd.updateTargetPosition(cube)
        if self.selectingForMulti:
            self.selectCubeForMulti()
        return task.cont

    def addWalk(self, vec):
        self.walk += vec

    def moveUpdate(self,task):
        """ this task makes the player move """
        # move where the keys set it
        self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed)
        return task.cont

    #@oldpostracker
    def jumpUpdate(self,task):
        """ this task simulates gravity and makes the player jump """
        # get the highest Z from the down casting ray
        highestZ = -100
        lowestZ = 100
        for i in range(self.nodeGroundHandler.getNumEntries()):
            entry = self.nodeGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z > highestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ):
                highestZ = z
        for i in range(self.ceilGroundHandler.getNumEntries()):
            entry = self.ceilGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z < lowestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ):
                lowestZ = z
        # gravity effects and jumps
        self.mass.simulate(globalClock.getDt())
        self.node.setZ(self.mass.pos.getZ())
        if highestZ > self.node.getZ()-PLAYER_TO_FLOOR_TOLERANCE:
            self.mass.zero()
            self.mass.pos.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE)
            self.node.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE)
        if lowestZ < self.node.getZ()+PLAYER_TO_FLOOR_TOLERANCE:
            self.mass.zero()
            self.mass.pos.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE)
            self.node.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE)
        if self.readyToJump and self.node.getZ() < highestZ + PLAYER_TO_FLOOR_TOLERANCE_FOR_REJUMP:
            self.mass.jump(JUMP_FORCE)
        return task.cont

    def firePortal(self, name, node):
        def hasTagValue(node, tag, value):
            if node.getTag(tag) == value:
                return True
            for pnum in range(node.getNumParents()):
                return hasTagValue(node.getParent(pnum), tag, value)
            return False
        self.firingHandler.sortEntries()
        if self.firingHandler.getNumEntries() > 0:
            closest = self.firingHandler.getEntry(0)
            if hasTagValue(closest.getIntoNode(), 'noportals', '1'):
                return
            point = closest.getSurfacePoint(render)
            normal = closest.getSurfaceNormal(render)
            node.setPos(point)
            node.lookAt(point + normal)
            node.reparentTo(render)
            dest = self.PORTAL_CYCLE[name]
            if dest not in self.canPortal:
                self.canPortal.append(dest)

    def fireBlue(self, *arg, **kwargs):
        self.firePortal("blue", self.bluePortal)

    def fireOrange(self, *arg, **kwargs):
        self.firePortal("orange", self.orangePortal)

    #@oldpostracker
    def enterPortal(self, color, collision):
        if self.intoPortal is None and color in self.canPortal:
            self.intoPortal = color
            portal = {"orange": self.bluePortal, "blue": self.orangePortal}.get(color)
            otherportal = {"orange": self.orangePortal, "blue": self.bluePortal}.get(color)
            # Handle horizontal portals :
            if portal.getH() == 0:
                self.node.setP(0)
                self.node.setR(0)
            elif otherportal.getH() == 0:
                self.node.setH(portal.getH())
                self.node.setP(0)
                self.node.setR(0)
            else:
                # New HPR is relative to 'new' portal but it the 'same' value
                # as the old HPR seen from the 'other' portal
                oldh_fromportal = self.node.getH(otherportal)
                self.node.setHpr(Vec3(0,0,0))
                self.node.setH(portal, 180-oldh_fromportal)
                newh_fromportal = self.node.getH(portal)
            self.node.setPos(portal, self.walk * 10.)
            self.mass.pos = self.node.getPos()
            # Make half a turn (only if we straffing without walking)
            if self.walk.getY() == 0 and self.walk.getX() != 0:
                self.node.setH(self.node, 180)
                self.node.setPos(self.node, self.walk * 10)
    #@oldpostracker
    def exitPortal(self, color, collision):
        # When you entered the blue portal, you have to exit the orange one
        if self.intoPortal != color:
            self.intoPortal = None

    def levelExit(self, event):
        if self.fps.level.settings.next_level:
            self.fps.level.loadlevel(self.fps.level.settings.next_level)
            self.origin = self.fps.level.settings.origin
            self.resetPosition()
            self.erasePortals()
            self.walk = self.STOP
        else:
            print "You won !"
            sys.exit(0)

    # EDITOR MODE
    def selectCube(self):
        self.firingHandler.sortEntries()
        if self.firingHandler.getNumEntries() > 0:
            closest = self.firingHandler.getEntry(0)
            return closest.getIntoNodePath().getParent().getParent(), closest.getSurfacePoint(render), closest.getSurfaceNormal(render) # render/cube.egg/-PandaNode/-GeomNode
        else:
            return None, None, None

    def clearMultiSelectedCubes(self):
        for c in self.selectedCubes:
            c.clearTexture(self.editorTextureStage)
        self.selectedCubes = []

    def selectCubeForMulti(self):
        cube, point, normal = self.selectCube()
        if cube:
            if self.selectingForMulti == 1:
                cube.setTexture(self.editorTextureStage, self.editorSelectedTexture)
                if cube not in self.selectedCubes:
                    self.selectedCubes.append(cube)
            elif cube in self.selectedCubes:
                cube.clearTexture(self.editorTextureStage)
                self.selectedCubes.remove(cube)

    def selectCubeForCopy(self, qty = 1):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.copyCube(c, normal, qty)
            self.clearMultiSelectedCubes()
        else:
            self.fps.level.copyCube(cube, normal, qty)

    def selectCubeForDelete(self):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.deleteCube(c)
            self.clearMultiSelectedCubes()
        else:
            self.fps.level.deleteCube(cube)

    def selectCubeForChange(self, step = 1):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.changeCube(c, step)
        else:
            self.fps.level.changeCube(cube, step)

    def selectCubeForRectangle(self, makeRoom = False):
        cube, point, normal = self.selectCube()
        if makeRoom:
            self.fps.level.createRoom(cube, self.node) # creates a room from the selected cube to the player(camera) position
        else:
            self.fps.level.createRectangle(cube, self.node) # creates a rectangle from the selected cube to the player(camera) position

    def saveLevel(self):
        camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()]
        levelname = self.fps.levelname
        self.fps.level.savelevel(levelname, camerapos)

    def addLightHere(self):
        camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()]
        self.fps.level.addLightHere(camerapos)

    def moveInEditor(self,task):
        self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed)
        self.osd.updatePosition(self.node)
        return task.cont
Exemple #11
0
class Main(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.key = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam_left": 0,
            "cam_right": 0,
            "cam_down": 0,
            "cam_up": 0,
            "up": 0,
            "down": 0
        }

        #####################
        #
        #   Simply testing procedural cave generation
        #
        #####################
        self.start = PlatformSeg(LVector3(0, 0, 0))
        self.start.generateAllParts(render)
        self.lostWood = LostWood(
            LVector3(self.start.pos.x + 750,
                     self.start.parts[0].pos.y + self.start.parts[0].wid,
                     self.start.pos.z))
        self.lostWood.generateAllParts(render)
        self.cave = Cave(
            LVector3(self.lostWood.pos.x + 1100,
                     self.lostWood.parts[6].pos.y + self.lostWood.parts[6].wid,
                     self.lostWood.pos.z))
        self.cave.generateAllParts(render)
        self.end = End(
            LVector3(
                self.cave.thirdRoomParts[8].pos.x - 200,
                self.cave.thirdRoomParts[8].pos.y +
                self.cave.thirdRoomParts[8].wid,
                self.cave.thirdRoomParts[8].pos.z))
        self.end.generate(render)

        ####################
        #
        #   Setting light so that we could see the definition in the walls
        #
        ####################

        render.setShaderAuto()
        self.dlight = DirectionalLight('dlight')
        self.dlight.setColor(LVector4(0.3, 0.1, 0.7, 1))
        dlnp = render.attachNewNode(self.dlight)
        dlnp.setHpr(90, 20, 0)
        render.setLight(dlnp)

        self.alight = render.attachNewNode(AmbientLight("Ambient"))
        self.alight.node().setColor(LVector4(0.5, 0.5, 1, .1))
        render.setLight(self.alight)

        base.disableMouse()
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)
        base.camera.reparentTo(self.floater)
        base.camera.setPos(0, -20, 500)
        base.camera.setP(-50)
        self.bindKeys()

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

    def bindKeys(self):
        self.accept("escape", sys.exit)
        self.accept("a", self.setKey, ["left", True])
        self.accept("a-up", self.setKey, ["left", False])
        self.accept("d", self.setKey, ["right", True])
        self.accept("d-up", self.setKey, ["right", False])
        self.accept("w", self.setKey, ["forward", True])
        self.accept("w-up", self.setKey, ["forward", False])
        self.accept("s", self.setKey, ["backward", True])
        self.accept("s-up", self.setKey, ["backward", False])
        self.accept("space", self.setKey, ["down", True])
        self.accept("space-up", self.setKey, ["down", False])
        self.accept("shift", self.setKey, ["up", True])
        self.accept("shift-up", self.setKey, ["up", False])
        self.accept("arrow_up", self.setKey, ["cam_up", True])
        self.accept("arrow_up-up", self.setKey, ["cam_up", False])
        self.accept("arrow_down", self.setKey, ["cam_down", True])
        self.accept("arrow_down-up", self.setKey, ["cam_down", False])
        self.accept("arrow_left", self.setKey, ["cam_left", True])
        self.accept("arrow_left-up", self.setKey, ["cam_left", False])
        self.accept("arrow_right", self.setKey, ["cam_right", True])
        self.accept("arrow_right-up", self.setKey, ["cam_right", False])

        taskMgr.add(self.update, "update")

    def update(self, task):
        delta = globalClock.getDt()
        WALKSPEED = 300
        SPEED = 100
        if self.key["left"]:
            self.floater.setX(self.floater.getX() - WALKSPEED * delta)
        if self.key["right"]:
            self.floater.setX(self.floater.getX() + WALKSPEED * delta)
        if self.key["forward"]:
            self.floater.setY(self.floater.getY() + WALKSPEED * delta)
        if self.key["backward"]:
            self.floater.setY(self.floater.getY() - WALKSPEED * delta)
        if self.key["up"]:
            self.floater.setZ(self.floater.getZ() + WALKSPEED * delta)
        if self.key["down"]:
            self.floater.setZ(self.floater.getZ() - WALKSPEED * delta)

        if self.key["cam_left"]:
            base.camera.setH(base.camera.getH() + SPEED * delta)
        if self.key["cam_right"]:
            base.camera.setH(base.camera.getH() - SPEED * delta)
        if self.key["cam_up"]:
            base.camera.setP(base.camera.getP() + SPEED * delta)
        if self.key["cam_down"]:
            base.camera.setP(base.camera.getP() - SPEED * delta)

        ######################
        #
        # SIMPLE OCCLUSION FOR START AREA
        #
        ######################

        for p in self.start.parts:
            if p.type == 'IceCube':
                if math.fabs(
                    (math.sqrt((p.model.getX() * p.model.getX()) +
                               (p.model.getY() * p.model.getY())) -
                     math.sqrt(
                         (self.floater.getX() * self.floater.getX()) +
                         (self.floater.getY() * self.floater.getY())))) <= 400:
                    p.show()
                    #Ice cube movement
                    p.bob(delta)
                else:
                    p.hide()

            if p.type == 'Prism':
                if p.type == 'Prism':
                    if math.fabs(
                        (math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y)) -
                         math.sqrt(
                             (self.floater.getX() * self.floater.getX()) +
                             (self.floater.getY() * self.floater.getY()))
                         )) <= 1000:
                        p.show()
                    else:
                        p.hide()

        ######################
        #
        # SIMPLE OCCLUSION FOR CAVE PARTS
        #
        ######################
        for p in self.cave.parts:
            if p.type == 'Prism':
                if math.fabs(
                    (math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y)) -
                     math.sqrt((self.floater.getX() * self.floater.getX()) +
                               (self.floater.getY() * self.floater.getY()))
                     )) <= 2200:
                    p.show()
                else:
                    p.hide()

            if p.type == 'IceCube':
                if math.fabs(
                    (math.sqrt((p.model.getX() * p.model.getX()) +
                               (p.model.getY() * p.model.getY())) -
                     math.sqrt((self.floater.getX() * self.floater.getX()) +
                               (self.floater.getY() * self.floater.getY()))
                     )) <= 1250:
                    p.show()

                    #Ice cube movement
                    self.cave.moveIceCubes(delta / 25)
                    for p in self.cave.iceCubesThirdRoom:
                        p.bob(delta / 25)
                    for p in self.cave.iceCubesSecondRoom:
                        p.bob(delta / 25)
                    self.cave.bigCube.bob(delta / 25)

                    for p in self.start.iceCubes:
                        p.bob(delta)
                else:
                    p.hide()

        return task.cont
class KVProjectile(DirectObject):
    
    #Property stuff
    creaTime = time.clock()
    dur = 1
    vec = 0
    delta = .5
    prevtime = 0
    flag = False
    
    #defining the thing fired by whatever gun we have
    def __init__(self, camera, look, id):
        
        #nodepath of the projectile, give it a trajectory
        self.projectileNode = NodePath('projectile'+str(id))
        self.projectileNode.reparentTo(render)
        
        #by passing the camera node form the camMov object, all projectiles are spawned 5 units in front of the camera
        self.projectileNode.setHpr(look, 0, 0, 0)
        self.projectileNode.setPos(camera,0,3, 3)
        
        #fix z position to line up with gun
        self.projectileNode.setScale(.1)
        self.projectileModel = loader.loadModel("./resources/beam.egg")
        self.projectileModel.reparentTo(self.projectileNode)
    	
        #must calculate unit vector based on direction
        dir = render.getRelativeVector(look, Vec3(0, 1, 0))
    	
        #speed up or slow down projectiles here
        dir = dir*5
        self.vec = dir
        
        #base.cTrav = CollisionTraverser()
        cs = CollisionSphere(0, 0, 0, 2.5)
        cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode'))
        cnodepath.node().addSolid(cs)
        self.collHand = CollisionHandlerEvent()
        self.collHand.addInPattern('into'+str(id))
        self.collHand.addOutPattern('outof')
        
        #cTrav has the distinction of global colider handler
        base.cTrav.addCollider(cnodepath, self.collHand)
        self.acceptOnce('into'+str(id), self.hit)
      
	    #deal with colliding or special effects here.
	    #wanted projectiles to be short lived
	    #so i will make them delete themselves after impact or time expired
        #writing a task that will rek the projectiles at the end of time
        self.damage = 5
    def moveTask(self, task):
        
        #curtime = time.clock()
        #self.delta = curtime-self.prevtime
        
        if self.flag:
            return task.done
        
        velx = self.vec.x*self.delta
        vely = self.vec.y*self.delta
        velz = self.vec.z*self.delta
        x = self.projectileNode.getX()
        y = self.projectileNode.getY()
        z = self.projectileNode.getZ()
        self.projectileNode.setPos(x+velx, y+vely, z+velz)
        #prevtime = time.clock()
            
        
        if task.time < self.dur:
        
            return task.cont
        else:
            
            self.flag = True
            return task.done
        

    def hit(self, collEntry):
        
        #throw out a custom message for what hit
        if collEntry.getIntoNodePath().getName() != 'projNode':
           
            temp = collEntry.getIntoNodePath().getName()
            messenger.send(temp, [self.damage]) 
            #remove the impacting projectile
            collEntry.getFromNodePath().getParent().getParent().removeNode()
            self.flag =  True
            del self
class ChargeProjectile(DirectObject):
    
    dur = 2
    delta = .15
    flag = False
    
    def __init__(self, spawn, taregt, id):
        
        self.projectileNode = NodePath('projectile'+str(id))
        self.projectileNode.reparentTo(render)

        self.projectileNode.setPos(spawn,0,-10, 0)
        self.projectileNode.setScale(1.5)
        self.projectileModel = Actor("./resources/sphereShot",{"grow":"./resources/sphereShot-grow"})
        self.projectileModel.setColorScale(200, 0, 255, 100)
        self.projectileModel.reparentTo(self.projectileNode)
        self.projectileNode.setHpr(spawn, 0, 0, 0)


        dir = render.getRelativeVector(spawn, Vec3(0, 1, 0))
        self.vec = dir*-100
        cs = CollisionSphere(0, 0, 0, 2.5)
        cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode'))
        cnodepath.node().addSolid(cs)
        self.collHand = CollisionHandlerEvent()
        self.collHand.addInPattern('bossProjectileinto'+str(id))
        self.collHand.addOutPattern('outof')
        base.cTrav.addCollider(cnodepath, self.collHand)
        self.acceptOnce('bossProjectileinto'+str(id), self.hit)
        self.damage = 15


    def moveTask(self, task):    
        
        if self.flag:
            return task.done
        
        velx = self.vec.x*self.delta
        vely = self.vec.y*self.delta
        velz = self.vec.z*self.delta
        x = self.projectileNode.getX()
        y = self.projectileNode.getY()
        z = self.projectileNode.getZ()
        self.projectileNode.setPos(x+velx, y+vely, z+velz)

        if task.time < self.dur:
        
            return task.cont
        else:
            
            self.flag = True
            return task.done

    def hit(self, collEntry):
        
        #throw out a custom message for what hit
        if collEntry.getIntoNodePath().getName() != 'projNode':
           
            temp = collEntry.getIntoNodePath().getName()
            print temp
            messenger.send(temp, [self.damage]) 
            
            #remove the impacting projectile
            collEntry.getFromNodePath().getParent().getParent().removeNode()
            self.flag =  True
            del self

    def wait(self, task):

        if task.time > 2.24:
            return task.done
	    
        return task.cont
Exemple #14
0
class Ship: 
    set = 0
    fuel = 1
    air = 1
    current = 0
    acceleration = 0.002
    max = 0.25
    fall = 0.001
    gravity = 0.3
    steer = 0
    steerspeed = 0.05
    slide = 0
    jumpheight = 0.2
    jump = True
    control = True
    dead = False
    under = None

    def __init__(self, root, model):
        self.root = root
        self.node = NodePath("ship")
        self.model = model
        self.model.reparentTo(self.node)
        self.node.reparentTo(render)
        self.setColliders()

        self.explosion = loader.loadModel("assets/models/explosion.bam")
        self.explosion.reparentTo(render)
        self.explosion.hide()
        self.explosion.setLightOff()

        self.loadAudio()

    def loadAudio(self): # each ship has their own set of sounds
        folder = "assets/audio/sfx/"
        self.audio = {
            "bounce":loader.loadSfx(folder+"bounce.wav"),
            "engine":loader.loadSfx(folder+"engine.wav"),
            "explode":loader.loadSfx(folder+"explode.wav"),
            "land":loader.loadSfx(folder+"land.wav"),
            "pickup":loader.loadSfx(folder+"pickup.wav"),
            "shave":loader.loadSfx(folder+"shave.wav"),
        }
        
    def setColliders(self):
        self.handlers = []
        for i in range(3):
            if i == 1: y = 0.2
            else: y = -0.2
            h = colRay(self.node, ((-1+i)/4, y, .1))
            self.handlers.append(h)
        self.colNose = colSpheres(self.node, 
            [((0,.1,.1),.02)])
        self.colLeft = colSpheres(self.node, 
            [((-.15,-.1,.2), .1)])
        self.colRight = colSpheres(self.node, 
            [((.15,-.1,.2), .1)])
        self.colTop = colSpheres(self.node,
            [((0,0.2,0.4), .1)])

    def update(self):
        self.control = True
        self.air -= (1/5000)*self.o2drain
        self.fuel -= (self.speed/1000)*self.fueldrain
        if self.air <= 0.01 or self.fuel <= 0.01:
            self.control = False
        
        if not self.dead:
            self.collide()
            self.specialFloor()
            # Set fw/bw speed
            self.speed = clamp(self.speed, 0, self.max)
            self.audio["engine"].setPlayRate((self.speed*7))
            # Update node position
            x = self.node.getX()+((self.steer+self.slide)*self.steerspeed)
            y = self.node.getY()+self.speed
            z = self.node.getZ()-self.fall
            self.node.setFluidPos(x, y, z)
            # Point nose to fall speed
            self.model.setP(-(self.fall*300))
            # Set flame color to speed
            cc = (self.speed*7)-uniform(0,0.3)
            self.model.getChild(0).setColorScale(cc*2,cc,cc,1)
            # Respawn if fallen off.
            if z < -20:
                self.respawn()
            self.setMeters()

    def specialFloor(self):
        f = self.under
        if f:
            if f == 1:
                self.root.road.playNextMap()
                self.respawn()
            elif f == 2:
                self.explode()
            elif f == 3:
                self.speed += self.acceleration*2
            elif f == 4:
                self.fuel = 0.99
                self.air = 0.99
            elif f == 5:
                self.control = False
            elif f == 6:
                self.speed -= self.acceleration*2
    
    def collide(self):
        if self.colNose.getNumEntries() > 0:
            if self.speed > 0.1: # full frontal crash
                self.explode()
            else: # full frontal bump
                self.audio["shave"].play()
                self.speed = 0
                self.node.setY(self.node.getY()-0.2)
        # bounce left and right
        if self.colLeft.getNumEntries() > 0:
            self.steer = 1
            self.audio["shave"].play()
        elif self.colRight.getNumEntries() > 0:
            self.steer = -1
            self.audio["shave"].play()
        # connect to floor
        self.grounded = False
        self.under = under = None
        self.root.cTrav.traverse(render)
        hits = [0,0,0]
        for h, handler in enumerate(self.handlers):
            if len(list(handler.entries)) > 0:
                handler.sortEntries()
                entry = list(handler.entries)[0]
                hitPos = entry.getSurfacePoint(render)
                distToGround =  self.node.getZ() - hitPos.getZ()
                if distToGround < 0.03:
                    hits[h] = 1
                if distToGround < self.fall+0.05:
                    if self.fall > 0.05: #go bounce
                        self.fall = -0.05
                        self.jump = True
                        self.audio["bounce"].play()
                    elif self.fall > 0: #land
                        self.fall = 0
                        self.jump = True
                        self.audio["land"].play()
                    if self.colTop.getNumEntries() >  0:
                        self.fall = 0
                    self.grounded = True
                    under = entry.getSurfacePoint(render)
                    self.node.setZ(hitPos.getZ()+0.01)
        s = self.getSteerVal()
        if hits == [1,0,0]:
            self.slide += 0.01
        elif hits == [0,0,1]:
            self.slide -= 0.01
        elif not hits == [0,0,0]:
            self.slide = 0
        # fall if not on floor
        if not self.grounded:
            self.fall += (self.gravity)/550
            if self.colTop.getNumEntries() > 0:
                if self.fall < 0:
                    self.fall = -self.fall
        # else see what color the floor is
        elif under:
            x, y, z = under
            x = round(x)
            y = round(y/2)
            z = round(z*2)-1
            try:
                color = self.root.road.map[y][x][z][1]
                if color <= 8 :
                    self.under = color
            except:
                pass

    def setMeters(self):
        self.root.hud.setSpeed(self.speed*114)
        self.root.hud.setAir(self.air*14)
        self.root.hud.setFuel(self.fuel*14)
        self.root.hud.setMiles(self.node.getY(), len(self.root.road.map))
        self.root.hud.setGravity(self.gravity)

    def explode(self):
        Explosion(self, self.explosion)
        self.audio["engine"].stop()
        self.audio["explode"].play()
        self.node.hide()
        self.dead = True

    def accelerate(self):
        if not self.dead and self.control:
            self.speed += self.acceleration

    def decelerate(self):
        if not self.dead and self.control:
            self.speed -= self.acceleration

    def getSteerVal(self):
        return ((self.speed*4)+0.1)

    def goLeft(self):
        if not self.dead and self.control:
            if self.grounded or self.fall < -0.07:
                if self.colLeft.getNumEntries() == 0:
                    self.steer = -self.getSteerVal()
                    self.slide = 0

    def goRight(self):
        if not self.dead and self.control:
            if self.grounded or self.fall < -0.07:
                if self.colRight.getNumEntries() == 0:
                    self.steer = self.getSteerVal()
                    self.slide = 0.01

    def jumpUp(self):
        if self.gravity < 8:
            if not self.dead and self.control:
                if self.colTop.getNumEntries() == 0:
                    if self.jump and self.fall < 0.05:
                        self.fall = -0.1
                        self.jump = False

    def respawn(self):
        self.audio["engine"].setLoop(True)
        self.audio["engine"].setVolume(1)
        self.audio["engine"].play()
        self.node.show()
        self.node.setPos(4,0,0.7)
        self.fall = 0
        self.speed = 0
        self.jump = True
        self.control = True
        self.dead = False
        self.air = 1
        self.fuel = 1
        self.gravity = self.root.road.gravity
        self.fueldrain = self.root.road.fueldrain
        self.o2drain = self.root.road.o2drain
        self.setMeters()
Exemple #15
0
class Maleficium(ShowBase):
    def __init__(self):
        compressedTextures = ConfigVariableString('compressed-textures','1') # Compresses Textures on load (increases loadtime / framerate)
        ShowBase.__init__(self)
        
        ## Debug Values (True/False)
        self.fpsMeter = True
        
        debug.checkDebugSettings(self)

        self.KeyBindings()

        ## Load World
        world.load('prisonCrater')

        ## Add Player to World
        self.playerBox = NodePath('player')
        self.player = Actor("data/models/hm.bam",
                            {"run":"data/models/hm-run.bam",
                             "idle":"data/models/hm.bam"})
        self.player.reparentTo(self.playerBox)
        self.player.setScale(.01)
        self.playerBox.reparentTo(render)
        self.isMoving = False

        ## Create Camera
        base.disableMouse()
        self.cameratarget = self.render.attachNewNode('Camera Target')
        base.camera.setPos(self.playerBox.getX(),self.playerBox.getY()+20,self.playerBox.getZ()+5)
        self.cameratarget.setPos(self.playerBox.getX(),self.playerBox.getY(),self.playerBox.getZ()+6)
        self.radius = 10
        self.XYAngle = .028
        self.ZAngle = .01

        ## Set Up Ground Collisions
        ## Player Collision
        base.cTrav = CollisionTraverser()
        self.ColHandler = CollisionHandlerFloor()       
        self.colGroundRay = CollisionNode('colGroundRay')
        self.colGroundRay.addSolid(CollisionRay(0,0,2,0,0,-1))
        self.playerCol = self.playerBox.attachNewNode(self.colGroundRay)
        base.cTrav.addCollider(self.playerCol,self.ColHandler)
        self.ColHandler.addCollider(self.playerCol,self.playerBox)
                                       
        ## Add main Game Loop to taskmanager
        taskMgr.add(self.gameLoop,'mainLoop')


    ### Input Structure; Coded by Darren Kent (Modeled after Roaming-Ralph by Ryan Myers)
    def KeyBindings(self):
        ## Setup Map
        self.startRightClick = True
        
        self.keyMap = {
            "forward":0,
            "backward":0,
            "turn_left":0,
            "turn_right":0,
            "strafe_left":0,
            "strafe_right":0,
            "cam_up":0,
            "cam_down":0,
            "cam_right":0,
            "cam_left":0,
            "zoom_in":0,
            "zoom_out":0,
            "right_click":0,
            "wheel_zoom_in":0,
            "wheel_zoom_out":0,
            }

        ## Accept Keys
        self.accept('escape',sys.exit)
        self.accept('w', self.setKey, ['forward',1])
        self.accept('w-up', self.setKey, ['forward',0])
        self.accept('s', self.setKey, ['backward',1])
        self.accept('s-up', self.setKey, ['backward',0])
        self.accept('a', self.setKey, ['turn_left',1])
        self.accept('a-up', self.setKey, ['turn_left',0])
        self.accept('d', self.setKey, ['turn_right',1])
        self.accept('d-up', self.setKey, ['turn_right',0])
        self.accept('q', self.setKey, ['strafe_left',1])
        self.accept('q-up', self.setKey, ['strafe_left',0])
        self.accept('e', self.setKey, ['strafe_right',1])
        self.accept('e-up', self.setKey, ['strafe_right',0])
        self.accept('arrow_up', self.setKey, ['cam_down',1])
        self.accept('arrow_up-up', self.setKey, ['cam_down',0])
        self.accept('arrow_down', self.setKey, ['cam_up',1])
        self.accept('arrow_down-up', self.setKey, ['cam_up',0])
        self.accept('arrow_right', self.setKey, ['cam_right',1])
        self.accept('arrow_right-up', self.setKey, ['cam_right',0])
        self.accept('arrow_left', self.setKey, ['cam_left',1])
        self.accept('arrow_left-up', self.setKey, ['cam_left',0])
        self.accept('[', self.setKey, ['zoom_in',1])
        self.accept('[-up', self.setKey, ['zoom_in',0])
        self.accept(']', self.setKey, ['zoom_out',1])
        self.accept(']-up', self.setKey, ['zoom_out',0])

        ## Accept Mouse
        self.accept('mouse3',self.setKey, ['right_click',1])
        self.accept('mouse3-up',self.setKey, ['right_click',0])
        self.accept('wheel_up',self.setKey, ['wheel_zoom_in',1])
        self.accept('wheel_down',self.setKey, ['wheel_zoom_out',1])

    ### Set Key Presses; Coded by Darren Kent (Modeled after Roaming-Ralph by Ryan Myers)
    def setKey(self,key,value):
        self.keyMap[key] = value        
            


    ### Main Game Loop; Coded by Darren Kent
    def gameLoop(self,task):

        ## Keyboard Camera Controls
        if (self.keyMap["cam_left"]!=0):
            self.XYAngle += .002
        if (self.keyMap["cam_right"]!=0):
            self.XYAngle -= .002
        if (self.keyMap["cam_up"] != 0):
            if self.ZAngle <= .045:
                self.ZAngle += .001
        if (self.keyMap["cam_down"] != 0):
            if self.ZAngle >= .002:
                self.ZAngle -= .001
        if (self.keyMap["zoom_in"] != 0):
            if self.radius >= 4:
                self.radius -= 1
                self.setRadius = self.radius
        if (self.keyMap["zoom_out"] != 0):
            if self.radius <= 40:
                self.radius += 1
                self.setRadius = self.radius
                
        ## Mouse Camera Controls
        if (self.keyMap["right_click"]!=0):
            if self.startRightClick == True:
                self.startRightClick = False
                self.tempMouseX = base.mouseWatcherNode.getMouseX()
                self.tempMouseY = base.mouseWatcherNode.getMouseY()
                self.tempXAngle = self.XYAngle
                self.tempZAngle = self.ZAngle
                self.tempPlayerH = self.playerBox.getH()
            elif self.startRightClick == False:
                Ztemp = self.tempZAngle + (base.mouseWatcherNode.getMouseY() - self.tempMouseY) / 20
                self.XYAngle = self.tempXAngle - (base.mouseWatcherNode.getMouseX() - self.tempMouseX) / 20
                if Ztemp >= .045:
                    Ztemp = .045
                if Ztemp <= 0.002:
                    Ztemp = 0.002
                self.ZAngle = Ztemp
        else:
            self.startRightClick = True
       
        if (self.keyMap["wheel_zoom_in"] != 0):
            if self.radius >= 7:
                self.radius -= 3
                self.setRadius = self.radius
        if (self.keyMap["wheel_zoom_out"] != 0):
            if self.radius <= 38:
                self.radius += 2
                self.setRadius = self.radius
        self.setKey("wheel_zoom_out",0)
        self.setKey("wheel_zoom_in", 0)

        ## Reposition Camera
        x = self.cameratarget.getX() + self.radius * math.sin(math.degrees(self.ZAngle)) * math.cos(math.degrees(self.XYAngle))
        y = self.cameratarget.getY() + self.radius * math.sin(math.degrees(self.ZAngle)) * math.sin(math.degrees(self.XYAngle))
        z = self.cameratarget.getZ() + self.radius * math.cos(math.degrees(self.ZAngle))
        base.camera.setPos(x,y,z)
        base.camera.lookAt(self.cameratarget)
        self.cameratarget.setPos(self.playerBox.getX(),self.playerBox.getY(),self.playerBox.getZ()+6)


        ## Keyboard Movement Controls
        if (self.keyMap["turn_left"]!=0):
            self.playerBox.setH(self.playerBox.getH() + 200 * globalClock.getDt())
        if (self.keyMap["turn_right"]!=0):
            self.playerBox.setH(self.playerBox.getH() - 200 * globalClock.getDt())
        if (self.keyMap["strafe_left"]!=0):
            self.playerBox.setX(self.playerBox, +20 * globalClock.getDt())
        if (self.keyMap["strafe_right"]!=0):
            self.playerBox.setX(self.playerBox, -20 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.playerBox.setY(self.playerBox, -25 * globalClock.getDt())
        if (self.keyMap["backward"] != 0):
            self.playerBox.setY(self.playerBox, +15 * globalClock.getDt())

        if (self.keyMap["forward"]!=0):
            if self.isMoving == False:
                self.player.setPlayRate(2.5,'run')
                self.player.loop('run')
                self.isMoving = True
        else:
            if self.isMoving:
                self.player.setPlayRate(1,'idle')
                self.player.loop('idle')
                self.isMoving = False

        ## Check Collisions
            

        return task.cont
Exemple #16
0
class PartyCog(FSM):
    notify = directNotify.newCategory('PartyCog')
    HpTextGenerator = TextNode('HpTextGenerator')
    hpText = None
    height = 7

    def __init__(self,
                 parentNode,
                 id,
                 bounceSpeed=3,
                 bounceHeight=1,
                 rotateSpeed=1,
                 heightShift=1,
                 xMoveSpeed=0,
                 xMoveDistance=0,
                 bounceOffset=0):
        self.id = id
        FSM.__init__(self, 'PartyCogFSM-%d' % self.id)
        self.showFacingStatus = False
        self.xMoveSpeed = xMoveSpeed
        self.xMoveDistance = xMoveDistance
        self.heightShift = heightShift
        self.bounceSpeed = bounceSpeed
        self.bounceHeight = bounceHeight
        self.rotateSpeed = rotateSpeed
        self.parentNode = parentNode
        self.bounceOffset = bounceOffset
        self.hitInterval = None
        self.kaboomTrack = None
        self.resetRollIval = None
        self.netTimeSentToStartByHit = 0
        self.load()
        self.request('Down')
        return

    def load(self):
        self.root = NodePath('PartyCog-%d' % self.id)
        self.root.reparentTo(self.parentNode)
        path = 'phase_13/models/parties/cogPinata_'
        self.actor = Actor(
            path + 'actor', {
                'idle': path + 'idle_anim',
                'down': path + 'down_anim',
                'up': path + 'up_anim',
                'bodyHitBack': path + 'bodyHitBack_anim',
                'bodyHitFront': path + 'bodyHitFront_anim',
                'headHitBack': path + 'headHitBack_anim',
                'headHitFront': path + 'headHitFront_anim'
            })
        self.actor.reparentTo(self.root)
        self.temp_transform = Mat4()
        self.head_locator = self.actor.attachNewNode('temphead')
        self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75)
        self.bodyColl.setTangible(1)
        self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' %
                                          self.id)
        self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.bodyCollNode.addSolid(self.bodyColl)
        self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode)
        self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5)
        self.headColl.setTangible(1)
        self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' %
                                          self.id)
        self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.headCollNode.addSolid(self.headColl)
        self.headCollNodePath = self.root.attachNewNode(self.headCollNode)
        self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0)
        self.arm1Coll.setTangible(1)
        self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' %
                                          self.id)
        self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.arm1CollNode.addSolid(self.arm1Coll)
        self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode)
        self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0)
        self.arm2Coll.setTangible(1)
        self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' %
                                          self.id)
        self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.arm2CollNode.addSolid(self.arm2Coll)
        self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode)
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splatType = globalPropPool.getPropType(splatName)
        self.pieHitSound = globalBattleSoundCache.getSound(
            'AA_wholepie_only.ogg')
        self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg')
        self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole')
        self.hole.setTransparency(True)
        self.hole.setP(-90.0)
        self.hole.setScale(3)
        self.hole.setBin('ground', 3)
        self.hole.reparentTo(self.parentNode)

    def unload(self):
        self.request('Off')
        self.clearHitInterval()
        if self.hole is not None:
            self.hole.removeNode()
            self.hole = None
        if self.actor is not None:
            self.actor.cleanup()
            self.actor.removeNode()
            self.actor = None
        if self.root is not None:
            self.root.removeNode()
            self.root = None
        if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.kaboomTrack = None
        if self.resetRollIval is not None and self.resetRollIval.isPlaying():
            self.resetRollIval.finish()
        self.resetRollIval = None
        if self.hitInterval is not None and self.hitInterval.isPlaying():
            self.hitInterval.finish()
        self.hitInterval = None
        del self.upSound
        del self.pieHitSound
        return

    def enterStatic(self):
        pass

    def exitStatic(self):
        pass

    def enterActive(self, startTime):
        self.root.setR(0.0)
        updateTask = Task.Task(self.updateTask)
        updateTask.startTime = startTime
        taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id)

    def exitActive(self):
        taskMgr.remove('PartyCog.update-%d' % self.id)
        taskMgr.remove('PartyCog.bounceTask-%d' % self.id)
        self.clearHitInterval()
        self.resetRollIval = self.root.hprInterval(0.5,
                                                   Point3(
                                                       self.root.getH(), 0.0,
                                                       0.0),
                                                   blendType='easeInOut')
        self.resetRollIval.start()
        self.actor.stop()

    def enterDown(self):
        if self.oldState == 'Off':
            downAnimControl = self.actor.getAnimControl('down')
            self.actor.pose('down', downAnimControl.getNumFrames() - 1)
            return
        self.clearHitInterval()
        startScale = self.hole.getScale()
        endScale = Point3(5, 5, 5)
        self.hitInterval = Sequence(
            LerpFunc(self.setAlongSpline,
                     duration=1.0,
                     fromData=self.currentT,
                     toData=0.0),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=endScale,
                              startScale=startScale,
                              blendType='easeIn'),
            Parallel(
                SoundInterval(self.upSound,
                              volume=0.6,
                              node=self.actor,
                              cutOff=PartyGlobals.PARTY_COG_CUTOFF),
                ActorInterval(self.actor, 'down', loop=0)),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=Point3(3, 3, 3),
                              startScale=endScale,
                              blendType='easeOut'))
        self.hitInterval.start()

    def exitDown(self):
        self.root.setR(0.0)
        self.root.setH(0.0)
        self.targetDistance = 0.0
        self.targetFacing = 0.0
        self.currentT = 0.0
        self.setAlongSpline(0.0)
        self.clearHitInterval()
        startScale = self.hole.getScale()
        endScale = Point3(5, 5, 5)
        self.hitInterval = Sequence(
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=endScale,
                              startScale=startScale,
                              blendType='easeIn'),
            Parallel(
                SoundInterval(self.upSound,
                              volume=0.6,
                              node=self.actor,
                              cutOff=PartyGlobals.PARTY_COG_CUTOFF),
                ActorInterval(self.actor, 'up', loop=0)),
            Func(self.actor.loop, 'idle'),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=Point3(3, 3, 3),
                              startScale=endScale,
                              blendType='easeOut'))
        self.hitInterval.start()

    def filterDown(self, request, args):
        if request == 'Down':
            return None
        else:
            return self.defaultFilter(request, args)
        return None

    def setEndPoints(self, start, end, amplitude=1.7):
        self.sinAmplitude = amplitude
        self.sinPeriod = (end.getX() - start.getX()) / 2
        self.sinDisplacement = start.getY()
        self.startPoint = start
        self.endPoint = end
        self.currentT = 0.0
        self.targetDistance = 0.0
        self.currentFacing = 0.0
        self.targetFacing = 0.0
        self.setAlongSpline(self.currentT)
        self.hole.setPos(self.root.getPos())
        self.hole.setZ(0.02)

    def rockBackAndForth(self, task):
        t = task.startTime + task.time
        angle = math.sin(t) * 20.0
        self.root.setR(angle)
        return task.cont

    def updateDistance(self, distance):
        self.targetDistance = clamp(distance, -1.0, 1.0)

    def updateTask(self, task):
        self.rockBackAndForth(task)
        if self.targetDistance > self.currentT:
            self.currentT += min(0.01, self.targetDistance - self.currentT)
            self.setAlongSpline(self.currentT)
        elif self.targetDistance < self.currentT:
            self.currentT += max(-0.01, self.targetDistance - self.currentT)
            self.setAlongSpline(self.currentT)
        if self.currentT < 0.0:
            self.targetFacing = -90.0
        elif self.currentT > 0.0:
            self.targetFacing = 90.0
        else:
            self.targetFacing = 0.0
        if self.targetFacing > self.currentFacing:
            self.currentFacing += min(10,
                                      self.targetFacing - self.currentFacing)
        elif self.targetFacing < self.currentFacing:
            self.currentFacing += max(-10,
                                      self.targetFacing - self.currentFacing)
        self.root.setH(self.currentFacing)
        return task.cont

    def setAlongSpline(self, t):
        t = t + 1.0
        dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0
        x = self.startPoint.getX() + t * dist
        y = self.startPoint.getY() - math.sin(
            t * 2 * math.pi) * self.sinAmplitude
        self.root.setPos(x, y, 0)

    def startBounce(self):
        taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id)

    def bounce(self, task):
        self.root.setZ(
            math.sin((self.bounceOffset + task.time) * self.bounceSpeed) *
            self.bounceHeight + self.heightShift)
        return task.cont

    def setPos(self, position):
        self.root.setPos(position)

    def respondToPieHit(self, timestamp, position, hot=False, direction=1.0):
        if self.netTimeSentToStartByHit < timestamp:
            self.__showSplat(position, direction, hot)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
        else:
            self.notify.debug(
                'respondToPieHit self.netTimeSentToStartByHit = %s' %
                self.netTimeSentToStartByHit)

    def clearHitInterval(self):
        if self.hitInterval is not None and self.hitInterval.isPlaying():
            self.hitInterval.clearToInitial()
        return

    def __showSplat(self, position, direction, hot=False):
        if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.clearHitInterval()
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splat.reparentTo(render)
        self.splat.setPos(self.root, position)
        self.splat.setAlphaScale(1.0)
        if not direction == 1.0:
            self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0])
            if self.currentFacing > 0.0:
                facing = 'HitFront'
            else:
                facing = 'HitBack'
        else:
            self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1])
            if self.currentFacing > 0.0:
                facing = 'HitBack'
            else:
                facing = 'HitFront'
        if hot:
            targetscale = 0.75
            part = 'head'
        else:
            targetscale = 0.5
            part = 'body'

        def setSplatAlpha(amount):
            self.splat.setAlphaScale(amount)

        self.hitInterval = Sequence(
            ActorInterval(self.actor, part + facing, loop=0),
            Func(self.actor.loop, 'idle'))
        self.hitInterval.start()
        self.kaboomTrack = Parallel(
            SoundInterval(self.pieHitSound,
                          volume=1.0,
                          node=self.actor,
                          cutOff=PartyGlobals.PARTY_COG_CUTOFF),
            Sequence(
                Func(self.splat.showThrough),
                Parallel(
                    Sequence(
                        LerpScaleInterval(self.splat,
                                          duration=0.175,
                                          scale=targetscale,
                                          startScale=Point3(0.1, 0.1, 0.1),
                                          blendType='easeOut'), Wait(0.175)),
                    Sequence(
                        Wait(0.1),
                        LerpFunc(setSplatAlpha,
                                 duration=1.0,
                                 fromData=1.0,
                                 toData=0.0,
                                 blendType='easeOut'))),
                Func(self.splat.cleanup), Func(self.splat.removeNode)))
        self.kaboomTrack.start()
        return

    def showHitScore(self, number, scale=1):
        if number <= 0:
            return
        if self.hpText:
            self.hideHitScore()
        self.HpTextGenerator.setFont(ToontownGlobals.getSignFont())
        if number < 0:
            self.HpTextGenerator.setText(str(number))
        else:
            self.HpTextGenerator.setText('+' + str(number))
        self.HpTextGenerator.clearShadow()
        self.HpTextGenerator.setAlign(TextNode.ACenter)
        r = 1
        g = 1
        b = 0
        a = 1
        self.HpTextGenerator.setTextColor(r, g, b, a)
        self.hpTextNode = self.HpTextGenerator.generate()
        self.hpText = render.attachNewNode(self.hpTextNode)
        self.hpText.setScale(scale)
        self.hpText.setBillboardPointEye()
        self.hpText.setBin('fixed', 100)
        self.hpText.setPos(self.root, 0, 0, self.height / 2)
        seq = Sequence(
            self.hpText.posInterval(
                0.25,
                Point3(self.root.getX(render), self.root.getY(render),
                       self.root.getZ(render) + self.height + 1.0),
                blendType='easeOut'), Wait(0.25),
            self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)),
            Func(self.hideHitScore))
        seq.start()

    def hideHitScore(self):
        if self.hpText:
            taskMgr.remove('PartyCogHpText' + str(self.id))
            self.hpText.removeNode()
            self.hpText = None
        return

    def getHeadLocation(self):
        self.actor.getJoints(jointName='head')[0].getNetTransform(
            self.temp_transform)
        self.head_locator.setMat(self.temp_transform)
        return self.head_locator.getZ(self.root)
Exemple #17
0
class TextHistory(SogalForm):
    '''
    Text history form
    '''


    def __init__(self):
        '''
        Constructor
        '''
        SogalForm.__init__(self, fading = True, fading_duration = 0.3, enableMask = True,backgroundColor = (0,0,0,0.6))
        self.reparentTo(aspect2d,sort = 101)
        

        self.frame = DirectScrolledFrame(parent = self, canvasSize = CANVASSIZE, 
                                         frameSize = FRAMESIZE, 
                                         autoHideScrollBars = AUTO_HIDE_SCROLLBARS,
                                         )
        
        self.reloadTheme()
        
        self.height = TOP
        self.shiftedHeight = 0
        self.shifter = NodePath('text_history_shifter')
        self.shifter.reparentTo(self.frame.getCanvas())
        
        if not prop_set_up:
            nameprops = TextProperties()  # @UndefinedVariable
            nameprops.setTextScale(0.75)
            TextPropertiesManager.getGlobalPtr().setProperties("th_name", nameprops)  # @UndefinedVariable
 
        self.labels = []
        
    def destroy(self):
        self.labels = []
        self.shifter.removeNode()
        SogalForm.destroy(self)
        
    def append(self,text,speaker,voiceName):
        if len(self.labels) >= MAXENTITIES:
            self.removeHead()
            
        label = TextHistoryLabel(text, speaker, voiceName, parent = self.shifter, height=self.height)
        self.height += label.getLabelHeight() + SPACING
        
        self.labels.append(label)
        self.resetCanvasSize()
            
    def removeHead(self):
        removing = self.labels.pop(0)
        
        h = removing.getLabelHeight() + SPACING
        self.shiftedHeight += h
        self.shifter.setZ(self.shifter.getZ() + h)
        #shift the parent NodePath to move all labels up
        
        removing.destroy()
        
        self.frame.verticalScroll.setValue(1)
        
    def resetCanvasSize(self):
        self.frame['canvasSize'] = (CANVASSIZE[0],CANVASSIZE[1],- TOP - self.height + self.shiftedHeight, 0)
        self.frame.verticalScroll.setValue(1)
        
    def roll(self,value):
        if self.labels:
            self.frame.verticalScroll.setValue(self.frame.verticalScroll.getValue() + value*2.0/len(self.labels))
        
    def focused(self):
        self.accept('mouse1', self.hide)
        self.accept('mouse2', self.hide)
        self.accept('mouse3', self.hide)
        self.accept('escape', self.hide)
        self.accept('wheel_up', self.roll, [-1.0])
        #self.accept('wheel_down', self.wheeldown)
        self.accept('wheel_down', self.roll, [1.0])
        self.accept('arrow_up-repeat', self.roll, [-1.0])
        self.accept('arrow_down-repeat', self.roll, [1.0])
        self.accept('arrow_up', self.roll, [-1.0])
        self.accept('arrow_down', self.roll, [1.0])
        self.accept('w-repeat', self.roll, [-1.0])
        self.accept('s-repeat', self.roll, [1.0])
        self.accept('w', self.roll, [-1.0])
        self.accept('s', self.roll, [1.0])
        SogalForm.focused(self)
        
    def defocused(self):
        self.ignore('mouse1')
        self.ignore('mouse2')
        self.ignore('mouse3')
        self.ignore('escape')
        self.ignore('wheel_up')
        self.ignore('wheel_down')
        self.ignore('arrow_up-repeat')
        self.ignore('arrow_down-repeat')
        self.ignore('arrow_up')
        self.ignore('arrow_down')
        self.ignore('w-repeat')
        self.ignore('s-repeat')
        self.ignore('w')
        self.ignore('s')
        SogalForm.defocused(self)
        
    def hide(self):
        self.removeFocus()
        SogalForm.hide(self)
        
    def wheeldown(self):
        if self.frame.verticalScroll.getValue() < 1:
            self.roll(1.0)
        else: self.hide()
        
    def reloadTheme(self):
        di = base.getStyle('frame')
        for key in di:
            self.frame[key] = di[key]
Exemple #18
0
class Player():
    def __init__(self, game, hp, mana, strength, dexterity, vigor, magic):

        self.game = game

        self.ori = 0.0
        self.lastori = -1
        self.zoomLevel = 0.0
        self.nextAttack = 0.0

        self.attacked = False

        # Atributes

        self.hp = hp
        self.mana = mana

        self.strength = strength
        self.dexterity = dexterity
        self.vigor = vigor
        self.magic = magic

        # Atributes calculated

        self.attackDamage = random(
            1, 7) + self.strength / 100  # physical dmg = weapon damage * %str
        self.magicDamage = random(
            3, 12) + self.magic / 100  # magic dmg = skill damage * %magic
        self.speed = 15 + 0  # speed = base speed + item
        self.runSpeed = 25 + 0  # run speed = base speed + item
        self.lateralSpeed = 10  # speed when moving sidewards
        self.lateralRunSpeed = 20  # run speed when moving sidewards
        self.backwardsSpeed = 10  # speed when moving backwards
        self.backwardsRunSpeed = 20  # run speed when moving backwards
        self.defense = 5 + self.vigor / 2  # defense = armour + 1/2 vigor
        self.criticalChance = 10 + 0  # crit chance = base item + skill
        self.criticalMultiplier = self.attackDamage * 1.5  # crit mult = base item + skill
        self.magicDefense = 2 + self.magic / 2  # magic def = base item + 1/2 magic
        self.attackSpeed = (
            0.2 * self.dexterity) / 60  # attack speed = base * dex / 60

        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-left": 0,
            "cam-right": 0,
            "jump": 0,
            "attack": 0,
            "run": 0
        }

        # Player Parts

        parts = [
            "head", "larm", "rarm", "lboot", "rboot", "lleg", "rleg", "lhand",
            "rhand", "torso"
        ]

        self.previousPart = {name: None for name in parts}

        # Player Models & Animations

        models = {name: "models/hero/%s" % name for name in parts}

        animations = {
            name: {
                "standby": "models/hero/%s-standby" % name,
                "walk": "models/hero/%s-walk" % name,
                "walk-back": "models/hero/%s-walk-back" % name,
                "walk-side": "models/hero/%s-walk-side" % name,
                "slash-front": "models/hero/%s-slash-front" % name
            }
            for name in parts
        }

        for itemClass, items in self.game.items["items"].items():
            if itemClass == "armours":
                for itemType, value in items["lightarmours"].items():
                    modelName = value["model"]

                for itemType, value in items["midarmours"].items():
                    modelName = value["model"]

                for itemType, value in items["heavyarmours"].items():
                    modelName = value["model"]

                    models["torso-%s" %
                           modelName] = "models/hero/torso-%s" % modelName

                    animations["torso-%s" % modelName] = {
                        "standby":
                        "models/hero/torso-%s-standby" % modelName,
                        "walk":
                        "models/hero/torso-%s-walk" % modelName,
                        "walk-back":
                        "models/hero/torso-%s-walk-back" % modelName,
                        "walk-side":
                        "models/hero/torso-%s-walk-side" % modelName,
                        "slash-front":
                        "models/hero/torso-%s-slash-front" % modelName
                    }

                for itemType, value in items["helmets"].items():
                    modelName = value["model"]

                    models["head-%s" %
                           modelName] = "models/hero/head-%s" % modelName

                    animations["head-%s" % modelName] = {
                        "standby":
                        "models/hero/head-%s-standby" % modelName,
                        "walk":
                        "models/hero/head-%s-walk" % modelName,
                        "walk-back":
                        "models/hero/head-%s-walk-back" % modelName,
                        "walk-side":
                        "models/hero/head-%s-walk-side" % modelName,
                        "slash-front":
                        "models/hero/head-%s-slash-front" % modelName
                    }

        # Init Actor

        self.playerActor = Actor(models, animations)

        # Hide All Player Parts

        for itemClass, items in self.game.items["items"].items():
            if itemClass == "armours":
                for itemType, value in items["lightarmours"].items():
                    modelName = value["model"]

                for itemType, value in items["midarmours"].items():
                    modelName = value["model"]

                for itemType, value in items["heavyarmours"].items():
                    modelName = value["model"]
                    self.playerActor.hidePart("torso-%s" % modelName)

                for itemType, value in items["helmets"].items():
                    modelName = value["model"]
                    self.playerActor.hidePart("head-%s" % modelName)

        #self.playerActor.ls()

        # Shaders

        self.shader = Shader.load("shaders/testShader.sha", Shader.SL_Cg)
        #self.playerActor.setShader(self.shader)

        # End shaders

        self.moveFloater = NodePath(PandaNode("moveFloater"))
        self.moveFloater.reparentTo(render)
        self.moveFloater.setPos(self.game.playerStartPos)

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)
        #self.floater.setZ(8.0)

        self.playerActor.setHpr(0, 0, 0)
        self.playerActor.setScale(0.5)

        self.playerActor.reparentTo(self.moveFloater)

        #self.playerHand = self.playerActor.exposeJoint(None, 'body', 'manod')
        #self.playerHead = self.playerActor.controlJoint(None, 'body', 'cabeza')
        #self.playerHead.setScale(10,10,10)

        self.inventory = [["0" for x in range(10)] for x in range(5)]

        #			COLS-ROWS		#			COLS-ROWS
        self.inventory[0][3] = self.game.items["items"]["armours"][
            "heavyarmours"]["ironplate"]
        self.inventory[0][4] = self.game.items["items"]["armours"][
            "heavyarmours"]["steelplate"]
        self.inventory[0][5] = self.game.items["items"]["armours"][
            "heavyarmours"]["cuirass"]
        self.inventory[3][3] = self.game.items["items"]["armours"][
            "midarmours"]["leatherarmour"]
        self.inventory[0][0] = self.game.items["items"]["weapons"]["swords"][
            "longsword"]
        self.inventory[1][0] = self.game.items["items"]["armours"][
            "midarmours"]["leatherarmour"]
        self.inventory[0][8] = self.game.items["items"]["weapons"]["swords"][
            "longsword"]
        self.inventory[0][7] = self.game.items["items"]["weapons"]["spears"][
            "ironspear"]
        self.inventory[3][9] = self.game.items["items"]["armours"][
            "midarmours"]["leatherarmour"]
        self.inventory[1][9] = self.game.items["items"]["armours"][
            "midarmours"]["leatherarmour"]
        self.inventory[1][8] = self.game.items["items"]["armours"]["boots"][
            "leatherboots"]
        self.inventory[1][7] = self.game.items["items"]["armours"]["helmets"][
            "woolchaco"]
        self.inventory[0][6] = self.game.items["items"]["armours"]["helmets"][
            "goldencrown"]
        self.inventory[0][8] = self.game.items["items"]["armours"]["helmets"][
            "ironhelmet"]
        self.inventory[1][6] = self.game.items["items"]["armours"]["cloacks"][
            "woolcloack"]
        self.inventory[2][9] = self.game.items["items"]["armours"][
            "midarmours"]["leatherarmour"]
        self.inventory[2][8] = self.game.items["items"]["armours"]["boots"][
            "leatherboots"]
        self.inventory[2][7] = self.game.items["items"]["armours"]["helmets"][
            "woolchaco"]
        self.inventory[2][6] = self.game.items["items"]["armours"]["cloacks"][
            "woolcloack"]
        self.inventory[2][5] = self.game.items["items"]["armours"]["gloves"][
            "woolgloves"]
        self.inventory[1][5] = self.game.items["items"]["armours"]["gloves"][
            "woolgloves"]
        self.inventory[2][4] = self.game.items["items"]["accesories"]["rings"][
            "simplering"]
        self.inventory[1][4] = self.game.items["items"]["accesories"]["rings"][
            "simplering"]
        self.inventory[2][3] = self.game.items["items"]["accesories"][
            "trinkets"]["rubyamulet"]
        self.inventory[1][3] = self.game.items["items"]["accesories"][
            "trinkets"]["rubyamulet"]
        self.inventory[2][2] = self.game.items["items"]["armours"]["shields"][
            "ironshield"]
        self.inventory[1][2] = self.game.items["items"]["armours"]["shields"][
            "ironshield"]

        self.equip = {
            "armour": None,
            "helmet": None,
            "gloves": None,
            "boots": None,
            "cloack": None,
            "ringLeft": None,
            "ringRight": None,
            "trinket": None,
            "weapon": None,
            "weaponLeft": None,
            "weaponRight": None,
            "shield": None
        }

        self.models = []  #A list that will store our models objects
        items = [("models/sword1", (0.0, 0.6, 1.5), (0, -90, 0), 0.2),
                 ("models/maze", (0.0, 0.6, -1.5), (0, 90, 0), 0.2)]
        """
		for row in items:
			np = self.game.loader.loadModel(row[0])				#Load the model
			np.setPos(row[1][0], row[1][1], row[1][2])		#Position it
			np.setHpr(row[2][0], row[2][1], row[2][2])		#Rotate it
			np.setScale(row[3])								#Scale it
			np.reparentTo(self.playerHand)
			#weaponNP.reparentTo(self.playerHand)
			self.models.append(np)							#Add it to our models list
		"""

        self.item = 0

        self.isMovingForward = False
        self.isMovingBackward = False
        self.isMovingSideRight = False
        self.isMovingSideLeft = False

        self.isMovingForwardLeft = False
        self.isMovingForwardRight = False

        self.isMovingSideRightUp = False
        self.isMovingSideRightDown = False

        self.isMovingSideLeftUp = False
        self.isMovingSideLeftDown = False

        self.isMovingBackwardLeft = False
        self.isMovingBackwardRight = False

        self.isAttacking = False

        self.setupControls()
        self.setupCamera()

        self.playerActor.loop("standby", "head")

        self.game.taskMgr.add(self.checkEquip,
                              "checkTorsoTask",
                              extraArgs=["torso", "armour"],
                              appendTask=True)
        self.game.taskMgr.add(self.checkEquip,
                              "checkHeadTask",
                              extraArgs=["head", "helmet"],
                              appendTask=True)

    def update(self, task):
        self.playerActor.setShaderInput("timer", task.time)
        return task.cont

    def checkEquip(self, partName, equipPart, task):

        # Check Equiped Parts

        if self.previousPart[partName] != self.equip[equipPart]:
            if self.equip[equipPart] != None and self.previousPart[
                    partName] == None:
                self.playerActor.hidePart(partName)
                self.playerActor.showPart(
                    "%s-%s" % (partName, self.equip[equipPart]["model"]))
                self.previousPart[partName] = self.equip[equipPart]

            elif self.equip[equipPart] != None and self.previousPart[
                    partName] != None:
                self.playerActor.hidePart(
                    "%s-%s" % (partName, self.previousPart[partName]["model"]))
                self.playerActor.showPart(
                    "%s-%s" % (partName, self.equip[equipPart]["model"]))
                self.previousPart[partName] = self.equip[equipPart]

            elif self.equip[equipPart] == None:
                self.playerActor.hidePart(
                    "%s-%s" % (partName, self.previousPart[partName]["model"]))
                self.playerActor.showPart(partName)
                self.previousPart[partName] = None

        return task.cont

    def setupCamera(self):

        self.game.disableMouse()
        self.game.camera.setPos(self.playerActor.getPos() + 50)

        self.lens = OrthographicLens()
        self.lens.setFilmSize(
            45 + self.zoomLevel,
            35 + self.zoomLevel)  # Or whatever is appropriate for your scene

        self.game.cam.node().setLens(self.lens)

        self.game.camLens.setFov(120)

    def setupControls(self):

        self.game.accept("a", self.setKey, ["left", 1])
        self.game.accept("shift-a", self.setKey, ["left", 1])
        self.game.accept("d", self.setKey, ["right", 1])
        self.game.accept("shift-d", self.setKey, ["right", 1])
        self.game.accept("w", self.setKey, ["forward", 1])
        self.game.accept("shift-w", self.setKey, ["forward", 1])
        self.game.accept("s", self.setKey, ["backward", 1])
        self.game.accept("shift-s", self.setKey, ["backward", 1])

        self.game.accept("a-up", self.setKey, ["left", 0])
        self.game.accept("d-up", self.setKey, ["right", 0])
        self.game.accept("w-up", self.setKey, ["forward", 0])
        self.game.accept("s-up", self.setKey, ["backward", 0])

        self.game.accept("mouse1", self.setKey, ["attack", 1])
        self.game.accept("mouse1-up", self.setKey, ["attack", 0])

        self.game.accept("shift-mouse1", self.setKey, ["attack", 1])
        self.game.accept("shift-mouse1-up", self.setKey, ["attack", 0])

        #self.game.accept("q", self.setKey, ["cam-left",1])
        #self.game.accept("e", self.setKey, ["cam-right",1])

        #self.game.accept("q-up", self.setKey, ["cam-left",0])
        #self.game.accept("e-up", self.setKey, ["cam-right",0])

        self.game.accept("space", self.setKey, ["jump", 1])
        self.game.accept("space-up", self.setKey, ["jump", 0])

        self.game.accept("shift", self.setKey, ["run", 1])
        self.game.accept("shift-up", self.setKey, ["run", 0])

        self.game.accept("wheel_up", self.moveCam, [1])
        self.game.accept("wheel_down", self.moveCam, [0])

        self.game.accept("shift-wheel_up", self.moveCam, [1])
        self.game.accept("shift-wheel_down", self.moveCam, [0])

        self.game.accept("t", self.toggleObject)

    def moveCam(self, zoom):
        if zoom == 0:
            self.zoomLevel += 5
            #if self.zoomLevel >= 30:
            #self.zoomLevel = 30

        elif zoom == 1:
            self.zoomLevel -= 5
            if self.zoomLevel <= 0:
                self.zoomLevel = 0

        #print self.zoomLevel
        self.lens.setFilmSize(45 + self.zoomLevel, 35 + self.zoomLevel)
        self.game.cam.node().setLens(self.lens)

    #def checkAttack(self):
    #animControl = self.playerActor.getAnimControl('slash', "body")

    #return animControl.isPlaying()

    def attack(self):
        if self.isAttacking is False:
            self.playerActor.play("slash-front")
            self.isAttacking = True

        self.isAttacking = False

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

    def setObject(self, i):
        for np in self.models:
            np.hide()
        self.models[i].show()
        self.item = i

    def toggleObject(self):

        if self.item == 1:
            self.item = 0
        else:
            self.item = 1

        for np in self.models:
            np.hide()
        self.models[self.item].show()

    def move(self, task):

        #self.playerActor.setPos(self.moveFloater.getPos())
        #self.playerActor.setZ(self.moveFloater.getZ())

        dt = globalClock.getDt()
        speed = 0

        if (self.keyMap["left"]):

            if (self.keyMap["run"]):
                speed = self.runSpeed
                #self.playerActor.setPlayRate(2.0, 'walk-side')
            else:
                speed = self.speed
                #self.playerActor.setPlayRate(1.0, 'walk-side')

            self.moveFloater.setX(self.moveFloater, speed * dt)
            self.moveFloater.setY(self.moveFloater, -speed * dt)

        if (self.keyMap["right"]):

            if (self.keyMap["run"]):
                speed = self.runSpeed
                #self.playerActor.setPlayRate(2.0, 'walk-side')
            else:
                speed = self.lateralSpeed
                #self.playerActor.setPlayRate(1.0, 'walk-side')

            self.moveFloater.setX(self.moveFloater, -speed * dt)
            self.moveFloater.setY(self.moveFloater, speed * dt)

        if (self.keyMap["forward"]):

            if (self.keyMap["run"]):
                speed = self.runSpeed
                #self.playerActor.setPlayRate(1.5, 'walk')
            else:
                speed = self.speed
                #self.playerActor.setPlayRate(1.0, 'walk')

            self.moveFloater.setY(self.moveFloater, -speed * dt)
            self.moveFloater.setX(self.moveFloater, -speed * dt)

        if (self.keyMap["backward"]):

            if (self.keyMap["run"]):
                speed = self.runSpeed
                #self.playerActor.setPlayRate(2.0, 'walk-back')
            else:
                speed = self.speed
                #self.playerActor.setPlayRate(1.0, 'walk-back')

            self.moveFloater.setY(self.moveFloater, speed * dt)
            self.moveFloater.setX(self.moveFloater, speed * dt)

        if (self.keyMap["attack"]) and (task.time > self.nextAttack):
            self.attack()
            self.nextAttack = task.time + self.attackSpeed
        self.keyMap["attack"] = 0
        """
		if self.lastori != self.ori :
			turn = Sequence(LerpQuatInterval(self.playerActor, duration=0.05,  hpr=Vec3(self.ori, 0, 0), blendType='easeOut')).start()
			self.lastori = self.ori
		"""

        self.playerActor.headsUp(self.game.lookPoint)
        self.playerActor.setH(self.playerActor.getH() - 180)

        #print(self.playerActor.getH())

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

        if self.keyMap["forward"] and self.keyMap["right"]:

            if ((self.playerActor.getH() < -45)
                    and (self.playerActor.getH() > -135)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:

                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -135)
                  and (self.playerActor.getH() > -225)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -225)
                  and (self.playerActor.getH() > -315)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif (((self.playerActor.getH() < -315) and
                   (self.playerActor.getH() < 0))
                  or ((self.playerActor.getH() < 0) and
                      (self.playerActor.getH() > -45))):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:

                    if (self.keyMap["run"]):
                        self.playerActor.setPlayRate(2.0, 'walk-side')
                    else:
                        self.playerActor.setPlayRate(1.0, 'walk-side')

                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

        elif self.keyMap["right"] and self.keyMap["backward"]:

            if ((self.playerActor.getH() < -135)
                    and (self.playerActor.getH() > -225)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -225)
                  and (self.playerActor.getH() > -315)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif (((self.playerActor.getH() < -315) and
                   (self.playerActor.getH() < 0))
                  or ((self.playerActor.getH() < 0) and
                      (self.playerActor.getH() > -45))):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif ((self.playerActor.getH() < -45)
                  and (self.playerActor.getH() > -135)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

        elif self.keyMap["backward"] and self.keyMap["left"]:

            if ((self.playerActor.getH() < -225)
                    and (self.playerActor.getH() > -315)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif (((self.playerActor.getH() < -315) and
                   (self.playerActor.getH() < 0))
                  or ((self.playerActor.getH() < 0) and
                      (self.playerActor.getH() > -45))):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -45)
                  and (self.playerActor.getH() > -135)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif ((self.playerActor.getH() < -135)
                  and (self.playerActor.getH() > -225)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

        elif self.keyMap["left"] and self.keyMap["forward"]:

            if (((self.playerActor.getH() < -315) and
                 (self.playerActor.getH() < 0))
                    or ((self.playerActor.getH() < 0) and
                        (self.playerActor.getH() > -45))):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -45)
                  and (self.playerActor.getH() > -135)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -135)
                  and (self.playerActor.getH() > -225)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif ((self.playerActor.getH() < -225)
                  and (self.playerActor.getH() > -315)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

        elif self.keyMap["forward"]:

            if ((self.playerActor.getH() < 0)
                    and (self.playerActor.getH() > -90)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -90)
                  and (self.playerActor.getH() > -180)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -180)
                  and (self.playerActor.getH() > -270)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif ((self.playerActor.getH() < -270)
                  and (self.playerActor.getH() < 0)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

        elif self.keyMap["backward"]:

            if ((self.playerActor.getH() < 0)
                    and (self.playerActor.getH() > -90)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif ((self.playerActor.getH() < -90)
                  and (self.playerActor.getH() > -180)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -180)
                  and (self.playerActor.getH() > -270)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -270)
                  and (self.playerActor.getH() < 0)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

        elif self.keyMap["left"]:

            if ((self.playerActor.getH() < 0)
                    and (self.playerActor.getH() > -90)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -90)
                  and (self.playerActor.getH() > -180)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

            elif ((self.playerActor.getH() < -180)
                  and (self.playerActor.getH() > -270)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -270)
                  and (self.playerActor.getH() < 0)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

        elif self.keyMap["right"]:

            if ((self.playerActor.getH() < 0)
                    and (self.playerActor.getH() > -90)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideLeft is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = True
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -90)
                  and (self.playerActor.getH() > -180)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk')

                if self.isMovingForward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk")

                    self.isMovingForward = True
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -180)
                  and (self.playerActor.getH() > -270)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-side')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-side')

                if self.isMovingSideRight is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-side")

                    self.isMovingForward = False
                    self.isMovingSideRight = True
                    self.isMovingSideLeft = False
                    self.isMovingBackward = False

            elif ((self.playerActor.getH() < -270)
                  and (self.playerActor.getH() < 0)):

                if (self.keyMap["run"]):
                    self.playerActor.setPlayRate(2.0, 'walk-back')
                else:
                    self.playerActor.setPlayRate(1.0, 'walk-back')

                if self.isMovingBackward is False:
                    self.playerActor.stop()
                    self.playerActor.loop("walk-back")

                    self.isMovingForward = False
                    self.isMovingSideRight = False
                    self.isMovingSideLeft = False
                    self.isMovingBackward = True

        else:
            if self.isMovingForward or self.isMovingBackward or self.isMovingSideLeft or self.isMovingSideRight:
                self.playerActor.stop()
                self.playerActor.loop("standby")
                self.isMovingForward = False
                self.isMovingBackward = False
                self.isMovingSideLeft = False
                self.isMovingSideRight = False

        return task.cont

    def updateCamera(self, task):

        self.floater.setPos(self.moveFloater.getPos())
        self.floater.setZ(self.moveFloater.getZ() + 2.0)

        self.game.camera.setPos(self.floater.getPos() + 50)
        # 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.game.camera.lookAt(self.floater)

        return task.cont
Exemple #19
0
class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        #Background sound (does not play infinitely)
        self.backgroundSound = base.loader.loadSfx("sounds/DireDireDocks.mp3")

        taskMgr.add(self.update, "moveTask")
        
        #Disable the mouse so that we may use it for our control scheme.
        self.props = WindowProperties()
        self.props.setSize(1920, 1080)
        self.props.setFullscreen(True)
        self.props.setCursorHidden(True)
        base.win.requestProperties(self.props)
        base.disableMouse()
        
        self.buildKeyMap()
        self.inMenu = True
        self.menuScreen = OnscreenImage("titlescreen.png", (0, .01, 0))
        self.menu()

    def initialize(self):
        self.timer = 0
        base.enableParticles()
        #base.setFrameRateMeter(True)

        ##########
        #
        # SETUP COLLISION HANDLERS AND FLAMIE'S MODEL
        #
        ##########
        
        #Create the collision handlers in order to build the level.
        WALL_MASK = BitMask32.bit(2)
        FLOOR_MASK = BitMask32.bit(1)
        
        #Start up the collision system
        self.cTrav = CollisionTraverser()

        #Determine how collisions with walls will be handled
        self.wallHandler = CollisionHandlerPusher()
        self.bobbing = False

        #Setup flamie's model
        self.flamieNP = base.render.attachNewNode(ActorNode('flamieNP'))
        self.flamieNP.reparentTo(base.render)
        self.flamie = loader.loadModel('models/Flame/body')
        self.flamie.setScale(.5)
        self.flamie.setTransparency(TransparencyAttrib.MAlpha)
        self.flamie.setAlphaScale(0)
        self.flamie.reparentTo(self.flamieNP)
        self.flamie.setCollideMask(BitMask32.allOff())
        flameLight = DirectionalLight("flameLight")
        fl = self.flamie.attachNewNode(flameLight)
        fl.setColor(255, 255, 255, 1)
        flameLight.setDirection((-5, -5, -5))
        self.flamie.setLight(fl)


        self.flamie2 = loader.loadModel("models/p.obj")
        self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f7.png"))
        self.flamie2.reparentTo(self.flamieNP)
        self.flamie2.setScale(4)
        self.flamie2OriZ = 2
        self.flamie2.setPos(-6.5, 0, self.flamie2OriZ) #(length, depth, height)
        self.flamie2.setLight(fl)
        self.flamie2.setTransparency(TransparencyAttrib.MAlpha)
        self.flamieFire = PointLight('fire')
        self.flamieFire.setColor(VBase4(1,1,1,1))
        self.flamieFire.setAttenuation((1,0,1))
        plnp = render.attachNewNode(self.flamieFire)
        plnp.setPos(self.flamieNP.getPos())
        self.flamielight = AmbientLight('light')
        self.flamielight.setColor(VBase4(1, 0.5, 0.6, 1))

        self.flamielight = self.flamie2.attachNewNode(self.flamielight)
        self.flamie2.setLight(self.flamielight)
        self.flamie2.setLight(plnp)
        self.mayFlamieBob = True

        #self.flamie2.setAlphaScale(0.5)

        '''self.tree = loader.loadModel("models/p2.obj")
        self.tree.setTexture(loader.loadTexture("deadTree.png"))
        self.tree.reparentTo(render)
        self.tree.setScale(4)
        self.tree.setPos(25,25,0) #(length, depth, height)
        self.tree.setLight(fl)
        self.tree.setTransparency(TransparencyAttrib.MAlpha)
        self.treelight = AmbientLight('light')
        self.treelight.setColor(VBase4(0.9, 0.9, 0.6, 1))
        self.treelight = self.tree.attachNewNode(self.treelight)
        self.tree.setLight(self.treelight)'''

        x = 150
        y = 20
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(7)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        x = 4
        y = 90
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(6)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        x = 3
        y = 120
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(4)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        x = 200
        y = 20
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(4)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        ### Something that should look like water ###
        w = loader.loadModel("models/flatP.obj")
        w.setTexture(loader.loadTexture("ice.png"))
        w.reparentTo(render)
        w.setScale(75)
        w.setTransparency(TransparencyAttrib.MAlpha)
        w.setAlphaScale(.7)
        w.setLight(treelight)
        w.setPos(-200, 0, -10)

        self.waterOrigiZ = -10
        self.waterSecZ = -95
        self.waterThirdZ = -120
        self.water = w

        ### Reskying the sky ###
        w = loader.loadModel("models/biggerFlatP.obj")
        w.setTexture(loader.loadTexture("models/n2.jpg"))
        w.reparentTo(self.flamie2)
        w.setScale(15)
        w.setLight(treelight)
        w.setPos(-200, 450, -200) #(length, depth, height)

        #Give flamie gravity
        self.floorHandler = CollisionHandlerGravity()
        self.floorHandler.setGravity(9.81+100)
        self.floorHandler.setMaxVelocity(100)
        

        ##########
        #
        # GENERATING LEVEL PARTS
        #
        ##########
        self.ice_reset = ()
        self.start = PlatformSeg(LVector3(0,0,0))
        self.start.generateAllParts(render)
        self.checkpointCreator(70, 90, self.start.pos.z, 10)
        self.floater = False
        
        for p in self.start.parts:
            if isinstance(p, Prism):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, p.dep, 'terraincollision', 'wallcollision')
            if isinstance(p, Square):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, 3,  'terraincollision', 'wallcollision')
            if isinstance(p, IceCube):
                p.model.setCollideMask(BitMask32.allOff())
                self.ice_reset += (p,)
                iceCubefloor= p.model.find("**/iceFloor")
                iceCubewall = p.model.find("**/iceWall")
                iceCubefloor.node().setIntoCollideMask(FLOOR_MASK)
                iceCubewall.node().setIntoCollideMask(WALL_MASK)

        
        self.lostWood = LostWood(LVector3(self.start.pos.x + 750, self.start.parts[0].pos.y + self.start.parts[0].wid, self.start.pos.z))
        self.lostWood.generateAllParts(render)
        self.checkpointCreator(self.lostWood.pos.x+120, self.lostWood.pos.y+150, self.lostWood.pos.z,20)
        self.checkpointCreator(self.lostWood.parts[6].pos.x + self.lostWood.parts[6].len/2, self.lostWood.parts[6].pos.y + self.lostWood.parts[6].wid/2, self.lostWood.pos.z, 40)
        
        for p in self.lostWood.parts:
            if isinstance(p, Prism):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, p.dep, 'terraincollision', 'wallcollision')
            if isinstance(p, Square):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, 3,  'terraincollision', 'wallcollision')
            if isinstance(p, IceCube):
                p.model.setCollideMask(BitMask32.allOff())
                self.ice_reset += (p,)
                iceCubefloor= p.model.find("**/iceFloor")
                iceCubewall = p.model.find("**/iceWall")
                iceCubefloor.node().setIntoCollideMask(FLOOR_MASK)
                iceCubewall.node().setIntoCollideMask(WALL_MASK)
            
        self.cave = Cave(LVector3(self.lostWood.pos.x + 1100, self.lostWood.pos.y + 2000, self.lostWood.pos.z - 50))
        self.cave.generateAllParts(render)
        self.checkpointCreator(self.cave.thirdRoomParts[5].pos.x + self.cave.thirdRoomParts[5].len/2,
                               self.cave.thirdRoomParts[5].pos.y + self.cave.thirdRoomParts[5].wid/2,
                               self.cave.thirdRoomParts[5].pos.z, 30)
        
        for p in self.cave.parts:
            if isinstance(p, Prism):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, p.dep, 'terraincollision', 'wallcollision')
            if isinstance(p, Square):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, 3,  'terraincollision', 'wallcollision')
            if isinstance(p, IceCube):
                p.model.setCollideMask(BitMask32.allOff())
                self.ice_reset += (p,)
                iceCubefloor= p.model.find("**/iceFloor")
                iceCubewall = p.model.find("**/iceWall")
                iceCubefloor.node().setIntoCollideMask(FLOOR_MASK)
                iceCubewall.node().setIntoCollideMask(WALL_MASK)

        self.end = End(LVector3(self.cave.thirdRoomParts[8].pos.x - 200,
                       self.cave.thirdRoomParts[8].pos.y + self.cave.thirdRoomParts[8].wid,
                       self.cave.thirdRoomParts[8].pos.z))
        self.end.generate(render)
        self.collisionBoxCreator(self.end.floor.pos.x, self.end.floor.pos.y, self.end.floor.pos.z,
                                 self.end.floor.len, self.end.floor.wid, self.end.floor.dep,
                                 'terraincollision', 'wallcollision')
        #########
        # DRAWING THE CABIN AND FINAL CAMPFIRE
        #########
        self.checkpointCreator(self.end.floor.pos.x + self.end.floor.len/2,
                               self.end.floor.pos.y + self.end.floor.wid/2,
                               self.end.floor.pos.z, 30)
        self.cabin = loader.loadModel("models/p2.obj")
        self.cabin.setTexture(loader.loadTexture("models/cabin.png"))
        self.cabin.setScale(50)
        self.cabin.reparentTo(render)
        self.cabin.setPos(self.end.floor.pos.x + self.end.floor.len/2,
                          self.end.floor.pos.y + self.end.floor.wid/1.1,
                          self.end.floor.pos.z)
        self.cabin.setTransparency(TransparencyAttrib.MAlpha)
        

        #Manually creating starting position. Copy and paste the first three parameters of the checkpoint you want to start at.
        self.startPos = LVector3(70, 90, self.start.pos.z)
        self.flamieNP.setPos(self.startPos)


        '''#Testing the tree model
        self.tree = loader.loadModel('models/Tree/log')
        self.tree.reparentTo(render)
        self.tree.setPos(-50,0,100)
        self.tree.setScale(2)'''

        '''#Add sky background
        self.sky = loader.loadModel('models/sphere.obj')
        self.sky.reparentTo(self.camera)
        self.sky.set_two_sided(True)
        self.skyTexture = loader.loadTexture("models/n2.jpg")
        self.sky.setTexture(self.skyTexture)
        self.sky.set_bin('background', 0)
        self.sky.set_depth_write(False)
        self.sky.set_compass()'''

        ##########
        #
        # CREATE FLAMIE'S COLLISION GEOMETRY
        #
        ##########
        
        #Give flamie a collision sphere in order to collide with walls
        flamieCollider = self.flamie.attachNewNode(CollisionNode('flamiecnode'))
        flamieCollider.node().addSolid(CollisionSphere(0,0,0,5))
        flamieCollider.node().setFromCollideMask(WALL_MASK)
        flamieCollider.node().setIntoCollideMask(BitMask32.allOff())
        self.wallHandler.addCollider(flamieCollider, self.flamieNP)
        self.cTrav.addCollider(flamieCollider, self.wallHandler)

        #Give flamie a collision ray to collide with the floor
        flamieRay = self.flamie.attachNewNode(CollisionNode('flamieRay'))
        flamieRay.node().addSolid(CollisionRay(0,0,8,0,0,-1))
        flamieRay.node().setFromCollideMask(FLOOR_MASK)
        flamieRay.node().setIntoCollideMask(BitMask32.allOff())
        self.floorHandler.addCollider(flamieRay, self.flamieNP)
        self.cTrav.addCollider(flamieRay, self.floorHandler)

        #Add a sensor that lets us melt ice cubes without standing on the cube.
        meltSensor = self.flamie.attachNewNode(CollisionNode('meltSensor'))
        cs = CollisionSphere(-2,0,10, 50)
        meltSensor.node().addSolid(cs)
        meltSensor.node().setFromCollideMask(WALL_MASK)
        meltSensor.node().setIntoCollideMask(BitMask32.allOff())
        cs.setTangible(0)
        self.wallHandler.addCollider(meltSensor, self.flamieNP)
        self.cTrav.addCollider(meltSensor, self.wallHandler)
        self.wallHandler.addInPattern('%fn-into-%in')
        self.wallHandler.addAgainPattern('%fn-again-%in')
        self.accept('meltSensor-into-iceWall', self.melt)
        self.accept('meltSensor-again-iceWall', self.melt)
        self.accept('meltSensor-into-checkpointCol', self.newstart)
        
        #Add in an event handle to prevent the jumping glitch found on the bobbing ice cubes.
        self.floorHandler.addInPattern('%fn-into-%in')
        self.floorHandler.addAgainPattern('%fn-again-%in')
        self.floorHandler.addOutPattern('%fn-out-%in')
        self.accept('flamieRay-into-iceFloor', self.jittercancel)
        self.accept('flamieRay-again-iceFloor', self.jittercancel)
        self.accept('flamieRay-out-iceFloor', self.jittercanceloff)

        
        #Uncomment these lines to see flamie's collision geometry
        #flamieCollider.show()
        #flamieRay.show()
        #meltSensor.show()

        #Uncomment this line to see the actual collisions.
        #self.cTrav.showCollisions(render)
        
        #This plane is found at the very bottom of the level and adds global gravity.
        killfloor = CollisionPlane(Plane(Vec3(0,0,1), Point3(0,0,-1000)))
        killfloorCol = CollisionNode('kfcollision')
        killfloorCol.addSolid(killfloor)
        killfloorCol.setIntoCollideMask(BitMask32.bit(1))
        killfloorColNp = self.render.attachNewNode(killfloorCol)

        ####################
        #
        #   Setting light so that we could see the definition in the walls
        #
        ####################
        
        render.setShaderAuto()
        self.dlight = DirectionalLight('dlight')
        self.dlight.setColor(LVector4(0.3, 0.1, 0.7, 1))
        dlnp = render.attachNewNode(self.dlight)
        dlnp.setHpr(90, 20, 0)
        render.setLight(dlnp)

        self.alight = render.attachNewNode(AmbientLight("Ambient"))
        self.alight.node().setColor(LVector4(0.5, 0.5, 1, .1))
        render.setLight(self.alight)

        self.snow = loader.loadTexture("models/ground.jpg")

        #Create a floater object and have it float 2 units above fireball.
        #And use this as a target for the camera to focus on.
        #This idea is taken from the roaming ralph sample that came with the
        #Panda3D SDK.
        self.camFocus = NodePath(PandaNode("floater"))
        self.camFocus.reparentTo(render)
        self.camFocusCurrZ = self.flamie.getZ() + 10

        #The camera is locked to the avatar so it always follows regardless of movement.
        self.camera.reparentTo(render)
        self.cameraTargetHeight = 8.0
        self.cameraDistance = 100
        self.cameraHeightModes = (self.start.parts[0].pos.z + 45, self.start.parts[0].pos.z + 125, self.camFocus.getZ() + 10, self.camFocus.getZ() + 150,
                                  self.end.floor.pos.z + 10)
        self.cameraHeight = self.cameraHeightModes[0]

        
    #################
    #   Changes Camera orientation depending on where the player is in the stage to compensate for the fact that
    #   the player has no direct control of the camera.
    #   Checks using the arrays from the level parts.
    ##################
    def cameraModes(self, delta):
        #Is the fireball within the platforming section between the starting area and the lost woods?
        #Is the fireball near the simple platforming sections of the LostWoods?
        #Is the fireball near the drop off point into the cave?
        #Is the fireball near the entrance to the second room in the cave?
        #If yes to any of these, bring the camera up to give a bird's eye view of the platforming
        if ((self.flamieNP.getX() > self.start.parts[1].pos.x and self.flamieNP.getY() > self.start.parts[1].pos.y - self.start.parts[1].wid
            and self.flamieNP.getX() < self.lostWood.parts[0].pos.x)
            or (self.flamieNP.getX() > self.lostWood.parts[0].pos.x + self.lostWood.parts[0].len/1.1
                and self.flamieNP.getX() < self.lostWood.parts[2].pos.x + self.lostWood.parts[0].len/11
                and self.flamieNP.getY() < self.lostWood.parts[0].pos.y + self.lostWood.parts[0].wid)
            or (self.flamieNP.getY() > self.cave.parts[0].pos.y - 20 and self.flamieNP.getY() <= self.cave.parts[0].pos.y + self.cave.parts[0].wid/2)
            or (self.flamieNP.getX() < self.cave.parts[1].pos.x + self.cave.parts[1].wid/10 and self.flamieNP.getY() >= self.cave.parts[1].pos.x)):
                camMode = 1
        #Is the fireball in the beginning of the cave area?
        #If yes, bring the camera closer
        elif self.flamieNP.getY() > self.cave.parts[1].pos.y - self.cave.parts[0].wid/2 and self.flamieNP.getY() < self.cave.thirdRoomParts[5].pos.y:
            camMode = 2
        else:
            camMode = 0

        if self.flamieNP.getY() >= self.cave.thirdRoomParts[6].pos.y:
            self.cave.thirdRoomParts[0].hide()
            camMode = 3
        if self.flamieNP.getY() >= self.cave.thirdRoomParts[8].pos.y + self.cave.thirdRoomParts[8].wid/1.5:
            camMode = 4

        self.lerpCam(camMode, delta)

    def lerpCam(self, camMode, delta):
        CAMLERPSPEED = 25
        if camMode == 0:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * delta <= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    self.cameraHeight = self.cameraHeight - CAMLERPSPEED * delta
        elif camMode == 1:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * delta >= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    if self.cameraHeight < self.cameraHeightModes[camMode]:
                        self.cameraHeight = self.cameraHeight + CAMLERPSPEED * delta
                    else:
                        self.cameraHeight = self.cameraHeight - CAMLERPSPEED * delta
        elif camMode == 2:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * delta <= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                    self.camFocusCurrZ = self.flamieNP.getZ() + 10
                else:
                    self.cameraHeight = self.cameraHeight - CAMLERPSPEED * delta
                    self.camFocusCurrZ = self.flamieNP.getZ() + 10
        elif camMode == 3:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight + CAMLERPSPEED * 3 * delta >= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    self.cameraHeight = self.cameraHeight + CAMLERPSPEED * 3 * delta
        elif camMode == 4:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * 3 * delta <= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    self.cameraHeight = self.cameraHeight - CAMLERPSPEED * 3 * delta

    def waterControl(self, delta):
        WATERLERPSPEED = .75
        if self.flamieNP.getY() <= self.lostWood.parts[6].pos.y + self.lostWood.parts[6].wid/2:
            if not self.water.getZ() == self.waterOrigiZ:
                if self.water.getZ() - WATERLERPSPEED * delta < self.waterOrigiZ and self.water.getZ() > self.waterOrigiZ:
                    self.water.setZ(self.waterOrigiZ)
                elif self.water.getZ() + WATERLERPSPEED * delta > self.waterOrigiZ and self.water.getZ() < self.waterOrigiZ:
                    self.water.setZ(self.waterOrigiZ)
                else:
                    if self.water.getZ() > self.waterOrigiZ:
                        self.water.setZ(self.water, - WATERLERPSPEED * delta)
                        if self.water.getZ() < self.waterOrigiZ:
                            self.water.setZ(self.waterOrigiZ)
                    else:
                        self.water.setZ(self.water, + WATERLERPSPEED * delta)
                        if self.water.getZ() > self.waterOrigiZ:
                            self.water.setZ(self.waterOrigiZ)
        elif self.flamieNP.getY() <= self.cave.parts[1].pos.y:
            if not self.water.getZ() == self.waterSecZ:
                if self.water.getZ() - WATERLERPSPEED * delta < self.waterSecZ:
                    self.water.setZ(self.waterSecZ)
                else:
                    self.water.setZ(self.water, - WATERLERPSPEED * delta)
        else:
            if not self.water.getZ() == self.waterThirdZ:
                if self.water.getZ() - WATERLERPSPEED * delta < self.waterThirdZ:
                    self.water.setZ(self.waterThirdZ)
                else:
                    self.water.setZ(self.water, - WATERLERPSPEED * delta)
        
        
    def reset(self):
        self.flamieNP.setPos(self.startPos)
        self.camFocusCurrZ = self.flamieNP.getZ() + 10
        for p in self.ice_reset:
            p.model.setScale(p.original_scale)
        
    def jump(self, dt):
        if self.bobbing:
            if self.floorHandler.getAirborneHeight() < 0.15:
                self.floorHandler.addVelocity(60) 
        elif self.floorHandler.isOnGround():
            self.floorHandler.addVelocity(60)

    def jittercancel(self, collEntry):
        model = collEntry.getIntoNodePath().getParent()
        modelRef = model.getPythonTag("iceRef")
        if model.getScale()[0] > 1.2:
            model.setScale(model.getScale()- modelRef.meltspeed)

        self.bobbing = True

    def jittercanceloff(self, collEntry):
        self.bobbing = False

    def melt(self, collEntry):
        model = collEntry.getIntoNodePath().getParent()
        modelRef = model.getPythonTag("iceRef")
        if model.getScale()[0] > 1.2 and self.bobbing != True:
            model.setScale(model.getScale()- modelRef.meltspeed)

    def newstart(self, collEntry):
        entry = collEntry.getInto().getCenter()
        self.startPos = (entry[0]+10, entry[1]+10, entry[2] +10)
        cp = loader.loadModel('models/Campfire/fire')
        cp.setPos(entry[0],entry[1], entry[2])
        cp.reparentTo(render)
            
    def buildKeyMap(self):
        self.keyMap = {"left": 0, "right": 0, "forward": 0, "back": 0, "down": 0, "up": 0, "lookUp": 0, "lookDown": 0, "lookLeft": 0, "lookRight": 0}

        #I changed the control scheme let me know if you would like me to try something else.
        #WASD for movement, space for jump
        self.accept("escape", sys.exit)
        self.accept("a", self.setKey, ["left", True])
        self.accept("a-up", self.setKey, ["left", False])
        self.accept("d", self.setKey, ["right", True])
        self.accept("d-up", self.setKey, ["right", False])
        self.accept("w", self.setKey, ["forward", True])
        self.accept("w-up", self.setKey, ["forward", False])
        self.accept("s", self.setKey, ["back", True])
        self.accept("s-up", self.setKey, ["back", False])
        self.accept("space", self.setKey, ["down", True])
        self.accept("space-up", self.setKey, ["down", False])
        self.accept("shift", self.setKey, ["up", True])
        self.accept("shift-up", self.setKey, ["up", False])

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

    def update(self, task):
        delta = globalClock.getDt()
        if not self.inMenu:
            SPEED = 125
            #Variable that holds what direction the player is inputting
            fblr = 0
            self.timer += delta * 25

            self.killPlane = self.water.getZ() - 25
            if self.flamieNP.getZ() < self.killPlane:
                self.reset()
                
            if self.keyMap["left"]:
                fblr = 1
                old_fblr = fblr
                self.flamieNP.setX(self.flamie, - SPEED * delta)
            if self.keyMap["right"]:
                fblr = 2
                old_fblr = fblr
                self.flamieNP.setX(self.flamie, + SPEED * delta)
            if self.keyMap["forward"]:
                fblr = 3
                old_fblr = fblr
                self.flamieNP.setY(self.flamie, + SPEED * delta)
            if self.keyMap["back"]:
                fblr = 4
                old_fblr = fblr
                self.flamieNP.setY(self.flamie, - SPEED * delta)
            if self.keyMap["up"]:
                #self.flamieNP.setZ(self.flamie, - SPEED * dt)
                self.reset()
                #self.cameraDistance = 20+self.cameraDistance
            if self.keyMap["down"] and self.timer > 1:
                #self.flamieNP.setZ(self.flamie, + SPEED * dt)
                self.timer = 0
                self.jump(delta)
                
            if fblr == 1:
                self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f8.png"))
            elif fblr == 2:
                self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f6.png"))
            elif fblr == 3:
                if old_fblr == 1:
                    self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f1.png"))
                elif old_fblr == 2:
                    self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f4.png"))
                else:
                    self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f3.png"))
            else:
                self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f7.png"))

            if self.floorHandler.isOnGround:
                self.flamieBob(delta)

            #The camera control is borrowed from Kristina's Tech Demo
            #This is also a demo found at: http://www.panda3d.org/forums/viewtopic.php?t=8452

            '''# mouse-controlled camera begins

            # Use mouse input to turn both the Character and the Camera
            if base.mouseWatcherNode.hasMouse():
                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)
                # alter flamie's yaw by an amount proportionate to deltaX
                self.flamie.setH(self.flamie.getH() - 0.3* 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 ralph's middle
                # 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())

            # mouse-controlled camera ends'''

            self.waterControl(delta)
            self.water.setX(self.flamieNP.getX() - 250)
            self.water.setY(self.flamieNP.getY() - 250)
            self.cameraModes(delta)
            base.camera.setPos(self.flamieNP.getX(), self.flamieNP.getY() - self.cameraDistance, self.cameraHeight)
            self.camFocus.setPos(self.flamieNP.getX(), self.flamieNP.getY(), self.camFocusCurrZ)
            base.camera.lookAt(self.camFocus)


            '''
            ######################
            #
            # SIMPLE OCCLUSION FOR START AREA
            #
            ######################

            for p in self.start.parts:
                if p.type == 'IceCube':
                    if math.fabs((math.sqrt((p.model.getX() * p.model.getX()) + (p.model.getY() * p.model.getY()))
                    - math.sqrt((self.camFocus.getX() * self.camFocus.getX()) + (self.camFocus.getY() * self.camFocus.getY())))) <= 400:
                        p.show()
                        #Ice cube movement
                        p.bob(delta)
                    else:
                        p.hide()
                    
                if p.type == 'Prism':
                    if p.type == 'Prism':
                        if math.fabs((math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y))
                        - math.sqrt((self.camFocus.getX() * self.camFocus.getX()) + (self.camFocus.getY() * self.camFocus.getY())))) <= 1000:
                            p.show()
                        else:
                            p.hide()


            ######################
            #
            # SIMPLE OCCLUSION FOR CAVE PARTS
            #
            ######################
            for p in self.cave.parts:
                if p.type == 'Prism':
                    if math.fabs((math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y))
                    - math.sqrt((self.flamieNP.getX() * self.flamieNP.getX()) + (self.flamieNP.getY() * self.flamieNP.getY())))) <= 2500:
                        p.show()
                    else:
                        p.hide()
                    
                if p.type == 'IceCube':
                    if math.fabs((math.sqrt((p.model.getX() * p.model.getX()) + (p.model.getY() * p.model.getY()))
                    - math.sqrt((self.flamieNP.getX() * self.flamieNP.getX()) + (self.flamieNP.getY() * self.flamieNP.getY())))) <= 2000:
                        p.show()

                        #Ice cube movement
                        self.cave.moveIceCubes(delta/25)
                        for p in self.cave.iceCubesThirdRoom:
                            p.bob(delta/25)
                        for p in self.cave.iceCubesSecondRoom:
                            p.bob(delta/25)
                        self.cave.bigCube.bob(delta/25)

                        for p in self.start.iceCubes:
                            p.bob(delta)
                    else:
                        p.hide()
            '''

            #Ice cube movement
            self.cave.moveIceCubes(delta)
            for p in self.cave.iceCubesThirdRoom:
                p.bob(delta)
            for p in self.cave.iceCubesSecondRoom:
                p.bob(delta)
            self.cave.bigCube.bob(delta)

            for p in self.start.iceCubes:
                p.bob(delta)

        elif self.inMenu:
            self.menu()


            

        if self.backgroundSound.status() is not self.backgroundSound.PLAYING:
            self.backgroundSound.play()

            
        return task.cont

    def menu(self):
        if self.keyMap["down"]:
            self.inMenu = False
            self.menuScreen.destroy()
            self.initialize()
            

    def flamieBob(self, delta):
        if self.mayFlamieBob:
            self.flamie2.setZ(self.flamie2.getZ() + .5*delta)
            if self.flamie2.getZ() - self.flamie2OriZ > 1:
                self.mayFlamieBob = False
        else:
            self.flamie2.setZ(self.flamie2.getZ() - .5*delta)
            if self.flamie2.getZ() - self.flamie2OriZ < -2:
                self.mayFlamieBob = True
        
    #Function to create a box collision using six polygon. The top face is created as terrain and thus provides gravity.
    #While the rest of the faces only act as wall pushers.
    def collisionBoxCreator(self, posx, posy, posz, length, width, height, floorname, wallname):
        ret = ()
        #Create top face
        terrain = CollisionPolygon(Point3(posx, posy+width, posz), Point3(posx, posy, posz),
                                Point3(posx+length, posy, posz), Point3(posx+length, posy+width, posz))
        terrainCol = CollisionNode(floorname)
        terrainCol.addSolid(terrain)
        terrainCol.setIntoCollideMask(BitMask32.bit(1))
        terrainColNp = self.render.attachNewNode(terrainCol)
        self.cTrav.addCollider(terrainColNp, self.floorHandler)
        ret += (terrainColNp,)
    
        #Create left face
        sideLeft = CollisionPolygon(Point3(posx, posy+width, posz-height), Point3(posx, posy, posz-height),
                                Point3(posx, posy, posz), Point3(posx, posy+width, posz))
        sideLeftCol = CollisionNode(wallname)
        sideLeftCol.addSolid(sideLeft)
        sideLeftCol.setIntoCollideMask(BitMask32.bit(2))
        sideLeftColNp = self.render.attachNewNode(sideLeftCol)
        self.cTrav.addCollider(sideLeftColNp, self.wallHandler)
        ret += (sideLeftColNp,)
        
        #Create right face
        sideRight = CollisionPolygon(Point3(posx+length, posy+width, posz), Point3(posx+length, posy, posz),
                                Point3(posx+length, posy, posz-height), Point3(posx+length, posy+width, posz-height))
        sideRightCol = CollisionNode(wallname)
        sideRightCol.addSolid(sideRight)
        sideRightCol.setIntoCollideMask(BitMask32.bit(2))
        sideRightColNp = self.render.attachNewNode(sideRightCol)
        self.cTrav.addCollider(sideRightColNp, self.wallHandler)
        ret += (sideRightColNp,)
        
        #Create front face
        sideFront = CollisionPolygon(Point3(posx, posy+width, posz-height), Point3(posx, posy+width, posz),
                                Point3(posx+length, posy+width, posz), Point3(posx+length, posy+width, posz-height))
        sideFrontCol = CollisionNode(wallname)
        sideFrontCol.addSolid(sideFront)
        sideFrontCol.setIntoCollideMask(BitMask32.bit(2))
        sideFrontColNp = self.render.attachNewNode(sideFrontCol)
        self.cTrav.addCollider(sideFrontColNp, self.wallHandler)
        ret += (sideFrontColNp,)
        
        #Create back face
        sideBack = CollisionPolygon(Point3(posx, posy, posz), Point3(posx, posy, posz-height),
                                Point3(posx+length, posy, posz-height), Point3(posx+length, posy, posz))
        sideBackCol = CollisionNode(wallname)
        sideBackCol.addSolid(sideBack)
        sideBackCol.setIntoCollideMask(BitMask32.bit(2))
        sideBackColNp = self.render.attachNewNode(sideBackCol)
        self.cTrav.addCollider(sideBackColNp, self.wallHandler)
        ret += (sideBackColNp,)

        #Create bottom face
        sideBot = CollisionPolygon(Point3(posx, posy, posz-height), Point3(posx, posy+width, posz-height),
                                Point3(posx+length, posy+width, posz-height), Point3(posx+length, posy, posz-height))
        sideBotCol = CollisionNode(wallname)
        sideBotCol.addSolid(sideBot)
        sideBotCol.setIntoCollideMask(BitMask32.bit(2))
        sideBotColNp = self.render.attachNewNode(sideBotCol)
        self.cTrav.addCollider(sideBotColNp, self.wallHandler)
        ret += (sideBotColNp,)

        #Uncomment these lines to see the collision polygons.
        '''terrainColNp.show()
        sideLeftColNp.show()
        sideRightColNp.show()
        sideFrontColNp.show()
        sideBackColNp.show()
        sideBotColNp.show()'''

        return ret
        #Old way of creating box collisions (left here for reference)
        '''box = CollisionBox((posx+(length/2), posy+(width/2),-(posz+height/2)), length/2, width/2, height/2)
        boxCol = CollisionNode('testcollision')
        boxCol.addSolid(box)
        boxCol.setIntoCollideMask(BitMask32.bit(2))
        boxColNp = self.render.attachNewNode(boxCol)
        boxHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(boxColNp, self.wallHandler)

        #Uncomment this line to see the collision solids.
        #boxColNp.show()'''

    def checkpointCreator(self, posx, posy, posz, radius):
        cp = loader.loadModel('models/Campfire/logs')
        cp.setPos(posx,posy, posz)
        cp.reparentTo(render)
        checkpoint = CollisionSphere(cp.getX(),cp.getY(),cp.getZ(),radius)
        checkpoint.setTangible(0)
        checkpointCol = CollisionNode('checkpointCol')
        checkpointCol.addSolid(checkpoint)
        checkpointCol.setIntoCollideMask(BitMask32.bit(2))
        checkpointColNp = self.render.attachNewNode(checkpointCol)
        self.cTrav.addCollider(checkpointColNp, self.wallHandler)
Exemple #20
0
class Character(DirectObject, XMLExportable, PropertiesTableAbstract,
                GameEntity):
    def __init__(self, attributes, showCollisions, grid_currentx,
                 grid_currenty, grid_playable_pos, parent):
        GameEntity.__init__(self, parent)  #running parent constructor

        self.movtask = 0
        self.showCollisions = showCollisions
        self.grid_currentx = grid_currentx
        self.grid_currenty = grid_currenty
        self.grid_playable_pos = grid_playable_pos
        self.attributes = attributes
        self.onPicked = ''
        self.onWalked = ''
        self.typeName = 'character'

        self.properties = {
            'url': '',
            'onWalked': '',
            'onPicked': '',
            'id': '',
            'inclination': '',
            'scale': '',
            'hitboxscale': '',
            'speed': '',
            'playable': '',
            'direction': ''
        }

        if attributes.has_key('url'):
            self.properties['url'] = attributes['url'].value
        else:
            print "WARNING: url not defined, loading placeholder"
            self.properties['url'] = 'misc/placeholder'

        if attributes.has_key('id'):
            self.properties['id'] = attributes['id'].value
        else:
            self.properties['id'] = 'all'

        if attributes.has_key('inclination'):
            self.properties['inclination'] = float(
                attributes['inclination'].value)
        else:
            self.properties['inclination'] = 30.0

        if attributes.has_key('scale'):
            self.properties['scale'] = float(attributes['scale'].value)
        else:
            self.properties['scale'] = 1.0

        if attributes.has_key('hitboxscale'):
            self.properties['hitboxscale'] = float(
                attributes['hitboxscale'].value)
        else:
            self.properties['hitboxscale'] = 1.0

        if attributes.has_key('speed'):
            self.properties['speed'] = float(attributes['speed'].value)
        else:
            self.properties['speed'] = 1.0

        #self.isNPC remains true while isPlayable is changable
        if attributes.has_key('playable'):
            self.playable = playable = attributes['playable'].value
            if self.playable == 'false':
                self.isNPC = False
                #print "setting ", self.properties['id'], " to ", self.isNPC
            else:
                self.isNPC = True
                #print "setting ", self.properties['id'], " to ", self.isNPC
        else:
            self.playable = playable = 'false'
            self.isNPC = True
        self.properties['playable'] = self.playable

        if attributes.has_key('direction'):
            self.properties['direction'] = attributes['direction'].value
        else:
            self.properties['direction'] = "down"

        if attributes.has_key('onWalked'):
            self.properties['onWalked'] = self.onWalked = attributes[
                'onWalked'].value
        else:
            self.properties['onWalked'] = self.onWalked = ""

        if attributes.has_key('onPicked'):
            self.properties['onPicked'] = self.onPicked = attributes[
                'onPicked'].value

        self.generateNode(showCollisions)

    def generateNode(self, showCollisions):
        self.destroy()

        #setting local variable
        attributes = self.attributes

        #defaulted to None
        self.pickCTrav = None

        #movement
        self.state = "still"
        self.showCollisions = showCollisions

        self.movtask = 0
        self.currentlydown = []
        self.currentlyfollowed = 0

        self.pickRequest = False

        #public props
        self.node = NodePath("characternode")
        self.node.setTwoSided(True)

        self.wtop = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/wtop.egg'))
        self.wdown = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/wdown.egg'))
        self.wleft = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/wleft.egg'))
        self.wright = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/wright.egg'))
        self.stop = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/stop.egg'))
        self.sdown = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/sdown.egg'))
        self.sleft = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/sleft.egg'))
        self.sright = self.applyNearestFilter(
            loader.loadModel(
                resourceManager.getResource(self.properties['url']) +
                '/sright.egg'))

        #Texture.FTNearest

        self.wtop.reparentTo(self.node)
        self.wdown.reparentTo(self.node)
        self.wleft.reparentTo(self.node)
        self.wright.reparentTo(self.node)
        self.stop.reparentTo(self.node)
        self.sdown.reparentTo(self.node)
        self.sleft.reparentTo(self.node)
        self.sright.reparentTo(self.node)

        self.leftdown = False
        self.rightdown = False
        self.downdown = False
        self.topdown = False

        if self.playable == "true":
            self.setPlayable(
                False)  #seems nonsense, triggered on grid.changeMap event
            self.node.setTag(
                "playable", "true"
            )  #setting this to make it recognizable from grid changeMap api
            self.setCollisions(True)
            self.setPickCollisions(True)
        else:
            self.setPlayable(False)
            self.node.setTag("playable", "false")
            self.setCollisions(False)
            self.setPickCollisions(False)

        #self.node.setX((-32/2)+0.5)
        self.node.setP(-(360 - int(self.properties['inclination'])))
        self.node.setScale(float(self.properties['scale']))
        self.node.setTransparency(TransparencyAttrib.MAlpha)

        self.lastpos = self.node.getPos()

        self.showAllSubnodes()

        #taskMgr.doMethodLater(4, self.face, 'charload'+self.properties['id'], [self.properties['direction']])
        self.face(self.properties['direction'])

        #set unique id
        self.node.setTag("id", self.properties['id'])
        #setting scripting part
        self.node.setTag("onWalked", self.onWalked)
        self.node.setTag("onPicked", self.onPicked)

        #storing a pointer of the gamenode
        self.node.setPythonTag("gamenode", self)

        self.npc_walk_stack = []
        self.npc_walk_happening = False
        self.globalLock = False

        self.setX(self.grid_currentx)
        self.setY(self.grid_currenty)

        if self.isNPC != True:
            print "attempting creation of NPC in ", self.grid_currentx, "-", self.grid_currenty

        if attributes.has_key('playable'):
            if self.isNPC != False:
                if ((self.grid_playable_pos.getX() != 0)
                        and (self.grid_playable_pos.getY() != 0)):
                    print 'GRID: moving player to ' + str(
                        self.grid_playable_pos)
                    self.setX(self.grid_playable_pos.getX())
                    self.setY(self.grid_playable_pos.getY())

        #automatic reparenting (and showing) when (re)generating node
        self.node.wrtReparentTo(self.parent.node)

    def getName(self):
        return 'Character: ' + self.properties['id']

    def xmlAttributes(self):
        return self.properties

    def xmlTypeName(self):
        return self.typeName

    '''
    Sanitize properties data to be of correct type from string
    '''

    def sanitizeProperties(self):
        #sanitizing data
        self.properties['inclination'] = float(self.properties['inclination'])
        self.properties['hitboxscale'] = float(self.properties['hitboxscale'])
        self.properties['speed'] = float(self.properties['speed'])
        self.properties['scale'] = float(self.properties['scale'])

        self.updateTilePosition()

    #interface needed by PropertiesTable
    # regenerates the node at every change
    def onPropertiesUpdated(self):
        self.sanitizeProperties()
        self.generateNode(self.showCollisions)

    #interface needed by PropertiesTable
    #TODO: implement as real interface?
    def getPropertyList(self):
        return self.properties

    #interface needed by PropertiesTable
    def setProperty(self, key, value):
        self.properties[key] = value

    def setSpeed(self, s):
        self.properties['speed'] = s

    def applyNearestFilter(self, model):
        for tex in model.findAllTextures():
            tex.setMinfilter(Texture.FT_nearest)
            tex.setMagfilter(Texture.FT_nearest)
        return model

    '''
    make the npc walk in direction for units
    '''

    def npc_push_walk(self, direction, units):
        #locking script execution
        self.globalLock = True
        script.addOneCustomLock(self)

        #start the walking
        self.npc_walk_stack.append([direction, units])
        self.npc_walk_helper()

    #apicall
    def npc_walk_helper(self):
        x = self.node.getX()
        y = self.node.getZ()

        #concurrent protection
        if self.npc_walk_happening == True:
            return

        #returning if no movement has to be performed
        if len(self.npc_walk_stack) < 0:
            return

        movement = self.npc_walk_stack.pop(0)

        direction = movement[0]
        units = movement[1]

        self.npc_targetx = x
        self.npc_targety = y
        self.npc_direction = direction

        if (direction == "down"):
            self.npc_targety = self.npc_targety - units
        elif (direction == "up"):
            self.npc_targety = self.npc_targety + units
        elif (direction == "left"):
            self.npc_targetx = self.npc_targetx - units
        elif (direction == "right"):
            self.npc_targetx = self.npc_targetx + units

        self.setAnim(direction)

        self.npc_walk_happening = True
        self.npc_movtask = taskMgr.add(self.npc_walk_task,
                                       "npc_moveCharacterTask" +
                                       self.properties['id'],
                                       uponDeath=self.npc_walk_callback)

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

        if (self.npc_direction == 'left'):
            self.node.setX(self.node.getX() -
                           1 * dt * self.properties['speed'])
            currentx = self.node.getX()

            if currentx <= self.npc_targetx:
                return task.done
        if (self.npc_direction == 'right'):
            self.node.setX(self.node.getX() +
                           1 * dt * self.properties['speed'])
            currentx = self.node.getX()

            if currentx >= self.npc_targetx:
                return task.done
        if (self.npc_direction == 'up'):
            self.node.setZ(self.node.getZ() +
                           1 * dt * self.properties['speed'])
            currenty = self.node.getZ()

            if currenty >= self.npc_targety:
                return task.done
        if (self.npc_direction == 'down'):
            self.node.setZ(self.node.getZ() -
                           1 * dt * self.properties['speed'])
            currenty = self.node.getZ()

            if currenty <= self.npc_targety:
                return task.done

        return task.cont

    def npc_walk_callback(self, task):
        self.face(self.npc_direction)

        #unlocking concurrent movement protection
        self.npc_walk_happening = False

        if len(self.npc_walk_stack) > 0:
            self.npc_walk_helper()
        else:  #character ended walking, unlock
            self.globalLock = False

    '''
    write destroyfunction
    '''

    def destroy(self):
        #not accepting events
        self.ignoreAll()
        #destroying everything down
        if self.node != None:
            self.node.remove_node()
        #removing all tasks
        if self.movtask != 0:
            taskMgr.remove(self.movtask)
            self.movtask = 0

    def face(self, direction):
        if direction == "left":
            self.hideAllSubnodes()
            self.sleft.show()
        if direction == "right":
            self.hideAllSubnodes()
            self.sright.show()
        if direction == "top" or direction == "up":  #let's keep retrocompatibility
            self.hideAllSubnodes()
            self.stop.show()
        if direction == "down":
            self.hideAllSubnodes()
            self.sdown.show()

    def setCollisions(self, value):
        if value == True:
            b = self.node.getBounds().getRadius()

            self.cTrav = CollisionTraverser()

            self.collisionTube = CollisionSphere(
                b / 2, 0, b / 2, 0.035 * self.properties['hitboxscale'])
            self.collisionNode = CollisionNode('characterTube')
            self.collisionNode.addSolid(self.collisionTube)
            self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
            self.collisionHandler = CollisionHandlerQueue()
            self.cTrav.addCollider(self.collisionNodeNp, self.collisionHandler)

            if self.showCollisions == True or main.editormode:
                # Uncomment this line to see the collision rays
                self.collisionNodeNp.show()

                # Uncomment this line to show a visual representation of the
                # collisions occuring
                self.cTrav.showCollisions(render)
        else:
            b = self.node.getBounds().getRadius()
            self.collisionTube = CollisionSphere(
                b / 2, 0, b / 2, 0.035 * self.properties['hitboxscale'])

            #allowing playables to collide with npcs
            if self.isNPC == True:  #TODO: fix because it's completely f****d up
                self.collisionNode = CollisionNode('characterTube')
            else:
                self.collisionNode = CollisionNode('characterNPCTube')

            self.collisionNode.addSolid(self.collisionTube)
            self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)

    #set if camera has to effectively follow the character
    #while it moves
    def setFollowedByCamera(self, value):
        #camera follow
        if value:
            if self.currentlyfollowed != True:
                customCamera.follow(self)
                self.currentlyfollowed = True
        else:
            if self.currentlyfollowed != False:
                customCamera.dontFollow()
                self.currentlyfollowed = False

    def setPickCollisions(self, value):
        if value:
            print "setting pick collisions"
            b = self.node.getBounds().getRadius()

            self.pickCTrav = CollisionTraverser()

            self.pickCollisionTube = CollisionSphere(
                b / 2, 0, b / 2, 0.035 * self.properties['hitboxscale'] + 0.01)
            self.pickCollisionNode = CollisionNode('characterPickTube')
            self.pickCollisionNode.addSolid(self.pickCollisionTube)
            self.pickCollisionNodeNp = NodePath(self.pickCollisionNode)
            self.pickCollisionNodeNp.reparentTo(self.node)
            self.pickCollisionHandler = CollisionHandlerQueue()
            self.pickCTrav.addCollider(self.pickCollisionNodeNp,
                                       self.pickCollisionHandler)

            if self.showCollisions == True:
                # Uncomment this line to see the collision rays
                self.pickCollisionNodeNp.show()

                # Uncomment this line to show a visual representation of the
                # collisions occuring
                self.pickCTrav.showCollisions(render)
        else:
            #dereferincing all pick colliders (must be done in order not to collide onto NPCs)
            self.pickCTrav = None
            self.pickCollisionTube = None
            self.pickCollisionNode = None
            self.pickCollisionNodeNp = None
            self.pickCollisionHandler = None

    #used to set playability in real time
    #useful when we want to switch context/scripted scenes
    def setPlayable(self, value):
        if self.isNPC != False:
            if value == True:
                #down events
                self.accept("arrow_left", self.arrowLeftDown)
                self.accept("arrow_right", self.arrowRightDown)
                self.accept("arrow_up", self.arrowUpDown)
                self.accept("arrow_down", self.arrowDownDown)
                #up events
                self.accept("arrow_left-up", self.arrowLeftUp)
                self.accept("arrow_right-up", self.arrowRightUp)
                self.accept("arrow_up-up", self.arrowUpUp)
                self.accept("arrow_down-up", self.arrowDownUp)
                self.accept("space", self.spaceDown)
                self.node.setTag("playable", "true")
                self.setFollowedByCamera(True)
                self.accept("pauseGameplay", self.setPlayable,
                            [False])  #can pause play
            else:
                self.ignoreAll()
                self.node.setTag("playable", "false")
                self.setFollowedByCamera(False)
                self.resetMovement()  #reset every movement happening
                self.accept("resumeGameplay", self.setPlayable,
                            [True])  #can resume play if not NPC

    #estimate loading time 4 seconds... lol... UPDATE: seems fixed in newer panda versions, inspect
    def showAllSubnodes(self):
        self.wtop.show()
        self.wdown.show()
        self.wleft.show()
        self.wright.show()
        self.stop.show()
        self.sdown.show()
        self.sleft.show()
        self.sright.show()

    def hideAllSubnodes(self):
        self.wtop.hide()
        self.wdown.hide()
        self.wleft.hide()
        self.wright.hide()
        self.stop.hide()
        self.sdown.hide()
        self.sleft.hide()
        self.sright.hide()

    def setMovement(self, value):
        if value == True:
            if self.movtask == 0:
                self.movtask = taskMgr.add(self.moveCharacter,
                                           "moveCharacterTask")
        if value == False:
            if self.movtask != 0:
                if len(self.currentlydown) == 0:
                    taskMgr.remove(self.movtask)
                    self.movtask = 0

    '''
    reset every movement actually happening
    '''

    def resetMovement(self):
        if self.leftdown == True:
            self.face("left")
        if self.rightdown == True:
            self.face("right")
        if self.downdown == True:
            self.face("down")
        if self.topdown == True:
            self.face("top")

        self.leftdown = False
        self.rightdown = False
        self.downdown = False
        self.topdown = False

        self.currentlydown = []

        self.setMovement(False)

    def setAnim(self, direction=''):
        self.hideAllSubnodes()

        if direction == '':
            if len(self.currentlydown) > 0:
                if self.currentlydown[-1] == 'left':
                    self.wleft.show()
                if self.currentlydown[-1] == 'right':
                    self.wright.show()
                if self.currentlydown[-1] == 'top':
                    self.wtop.show()
                if self.currentlydown[-1] == 'down':
                    self.wdown.show()
        else:
            if direction == 'left':
                self.wleft.show()
            if direction == 'right':
                self.wright.show()
            if direction == 'up':
                self.wtop.show()
            if direction == 'down':
                self.wdown.show()

    #pick request function
    def spaceDown(self):
        self.pickRequest = True

    #movement related functions
    def arrowLeftDown(self):
        #track key down
        self.leftdown = True
        self.setMovement(True)
        #show changes to screen
        self.currentlydown.append("left")
        self.setAnim()

    def arrowLeftUp(self):
        self.leftdown = False
        self.setMovement(False)
        #show changes to screen
        if len(self.currentlydown) == 1:
            self.hideAllSubnodes()
            self.sleft.show()
        if "left" in self.currentlydown:
            self.currentlydown.remove("left")

        if len(self.currentlydown) > 0:
            self.setAnim()

    def arrowRightDown(self):
        #track key down
        self.rightdown = True
        self.setMovement(True)
        #show changes to screen
        self.currentlydown.append("right")
        self.setAnim()

    def arrowRightUp(self):
        self.setMovement(False)
        self.rightdown = False
        #show changes to screen
        if len(self.currentlydown) == 1:
            self.hideAllSubnodes()
            self.sright.show()
        if "right" in self.currentlydown:
            self.currentlydown.remove("right")

        if len(self.currentlydown) > 0:
            self.setAnim()

    def arrowDownDown(self):
        #track key down
        self.downdown = True
        self.setMovement(True)
        #show changes to screen
        self.currentlydown.append("down")
        self.setAnim()

    def arrowDownUp(self):
        self.downdown = False
        self.setMovement(False)
        #show changes to screen
        if len(self.currentlydown) == 1:
            self.hideAllSubnodes()
            self.sdown.show()
        if "down" in self.currentlydown:
            self.currentlydown.remove("down")

        if len(self.currentlydown) > 0:
            self.setAnim()

    def arrowUpDown(self):
        #track key down
        self.topdown = True
        self.setMovement(True)
        #show changes to screen
        self.currentlydown.append("top")
        self.setAnim()

    def arrowUpUp(self):
        self.topdown = False
        self.setMovement(False)
        #show changes to screen
        if len(self.currentlydown) == 1:
            self.hideAllSubnodes()
            self.stop.show()
        if "top" in self.currentlydown:
            self.currentlydown.remove("top")
        if len(self.currentlydown) > 0:
            self.setAnim()

    def moveCharacter(self, task):
        dt = globalClock.getDt()
        if len(self.currentlydown) > 0:
            if self.currentlydown[-1] == 'left':
                self.node.setX(self.node.getX() -
                               1 * dt * self.properties['speed'])
            if self.currentlydown[-1] == 'right':
                self.node.setX(self.node.getX() +
                               1 * dt * self.properties['speed'])
            if self.currentlydown[-1] == 'top':
                self.node.setZ(self.node.getZ() +
                               1 * dt * self.properties['speed'])
            if self.currentlydown[-1] == 'down':
                self.node.setZ(self.node.getZ() -
                               1 * dt * self.properties['speed'])

        #check collisions
        if self.cTrav != None:
            self.cTrav.traverse(render)

        if self.pickCTrav != None:
            self.pickCTrav.traverse(render)

        #entries python list
        entries = list(self.collisionHandler.getEntries())
        pickentries = list(self.pickCollisionHandler.getEntries())

        for e in entries[:]:
            if e.getIntoNodePath().getName() == "characterPickTube":
                entries.remove(e)

        for e in pickentries[:]:
            if e.getIntoNodePath().getName() == "characterTube":
                pickentries.remove(e)

        if len(entries) == 0:
            self.lastpos = self.node.getPos()
        else:
            sp = entries[0].getSurfacePoint(self.node)  #surface point
            objectNode = entries[0].getIntoNodePath().getParent(
            )  #into object node
            groundNode = entries[0].getIntoNodePath()  #into object node

            if objectNode.hasTag("collideandwalk"):
                if objectNode.getTag("collideandwalk") != "yes":
                    self.node.setPos(self.lastpos)
            else:
                self.node.setPos(self.lastpos)

            #if node is a real object (not a wall)
            if objectNode.hasTag("avoidable"):
                if objectNode.getTag(
                        "avoidable"
                ) == "true":  #see if object is intelligently avoidable
                    if objectNode.hasTag("xscaled") and objectNode.hasTag(
                            "yscaled"):
                        if len(
                                self.currentlydown
                        ) > 0:  #at least 1, avoids list index out of range exception
                            if self.currentlydown[
                                    -1] == 'left' or self.currentlydown[
                                        -1] == 'right':  #TODO: fix the shiet, not always working
                                bottomObjPos = objectNode.getZ() - (
                                    float(objectNode.getTag("yscaled")) / 2)
                                topObjPos = objectNode.getZ() + (
                                    float(objectNode.getTag("yscaled")) / 2)
                                if self.node.getZ() < bottomObjPos:
                                    self.node.setZ(self.node.getZ() - 1 * dt *
                                                   self.properties['speed'])
                                if self.node.getZ() > topObjPos:
                                    self.node.setZ(self.node.getZ() + 1 * dt *
                                                   self.properties['speed'])
                                pass
                            if self.currentlydown[
                                    -1] == 'top' or self.currentlydown[
                                        -1] == 'down':
                                leftObjPos = objectNode.getX() - (
                                    float(objectNode.getTag("xscaled")) / 2)
                                rightObjPos = objectNode.getX() + (
                                    float(objectNode.getTag("xscaled")) / 2)

                                if self.node.getX() < leftObjPos:
                                    self.node.setX(self.node.getX() - 1 * dt *
                                                   self.properties['speed'])

                                if self.node.getX() > rightObjPos:
                                    self.node.setX(self.node.getX() + 1 * dt *
                                                   self.properties['speed'])
                            self.lastpos = self.node.getPos()

        for entry in entries:
            objectNode = entry.getIntoNodePath().getParent()
            onWalked = objectNode.getTag("onWalked")
            if len(onWalked) > 0:
                eval(onWalked)  #oh lol, danger detected here

        evaluatedOnce = False
        if self.pickRequest == True:
            for entry in pickentries:
                objectNode = entry.getIntoNodePath().getParent()
                onPicked = objectNode.getTag("onPicked")
                if len(onPicked) > 0 and evaluatedOnce == False:
                    eval(onPicked)  #oh lol, danger detected again here
                    evaluatedOnce = True
                else:
                    if hasattr(objectNode.getPythonTag('gamenode'), 'name'):
                        print "WARNING: picking on this object is not defined: ", objectNode.getPythonTag(
                            'gamenode').name
                        print "X: ", objectNode.getX()
                        print "Y: ", objectNode.getZ()
            self.pickRequest = False  #resetting request

        #this is needed for empty pick
        if self.pickRequest == True:
            self.pickRequest = False  #resetting request

        return Task.cont

    def getWorldPos(self):
        return self.node.getPos(render)

    def setX(self, x):
        self.node.setX(x)
        self.lastpos.setX(x)

    def setY(self, y):
        self.node.setZ(y)
        self.lastpos.setZ(y)

    #here for polymorph
    def getTileX(self):
        return self.parent.getX()

    #here for polymorph
    def getTileY(self):
        return self.parent.getY()
Exemple #21
0
class CreditsReel(object):
    '''
    Creates a Panda scene that's independent of the main render tree, so that
    the credits can be displayed in a smaller display region within the main
    screen.
    '''
    def __init__(self, app):
        self.app = app
        self.do = DirectObject()

        self.running = False
        self.displayRegion = None
        self.root = NodePath('creditsRender')
        self.camera = Camera('creditsCam')
        self.cameraNP = NodePath(self.camera)

        # Set parameters to match those of render2d
        self.root.setDepthTest(0)
        self.root.setDepthWrite(0)
        self.root.setMaterialOff(1)
        self.root.setTwoSided(1)

        self.aspect2d = self.root  # self.root.attachNewNode('creditsAspect')

        lens = OrthographicLens()
        lens.setFilmSize(2, 2)
        lens.setFilmOffset(0, 0)
        lens.setNearFar(-1000, 1000)
        self.camera.setLens(lens)

        self.cameraNP.reparentTo(self.root)

        self.scrollTask = None
        self.lastTime = None
        self.creditsFileLoaded = False

    def loadCreditsFileIfNeeded(self):
        if self.creditsFileLoaded:
            return

        filePath = getPath(startupMenu, 'credits3d.txt')
        with codecs.open(filePath, 'rU', encoding='utf-8') as f:
            creditsLines = f.read().splitlines()

        y = 0
        for line in creditsLines:
            if line.startswith('!!'):
                font = self.app.fonts.creditsH1
                line = line[len('!!'):]
            elif line.startswith('!'):
                font = self.app.fonts.creditsH2
                line = line[len('!'):]
            else:
                font = self.app.fonts.creditsFont

            lineHeight = font.getPandaLineHeight(self.app)
            node = font.makeOnscreenText(
                self.app,
                text=line or ' ',  # Prevents .getNumRows() bug
                fg=self.app.theme.colours.mainMenuColour,
                align=TextNode.ACenter,
                pos=(0, y - lineHeight),
                parent=self.aspect2d,
                wordwrap=28,
            )
            y -= lineHeight * (node.textNode.getNumRows() + 0.2)

        self.creditsFileLoaded = True

    def stop(self):
        if not self.running:
            return
        self.running = False
        self.do.ignoreAll()

        if self.scrollTask is not None:
            self.app.panda.taskMgr.remove(self.scrollTask)
            self.scrollTask = None

        if self.displayRegion is not None:
            self.displayRegion.setActive(False)

    def start(self):
        self.cameraNP.setPos((0, 0, 0))
        if self.running:
            return
        self.running = True

        self.loadCreditsFileIfNeeded()

        if self.scrollTask is None:
            self.scrollTask = self.app.panda.taskMgr.add(
                self.updateCredits, 'creditsLoop')
            self.lastTime = self.scrollTask.time

        if self.displayRegion is None:
            self.displayRegion = self.app.panda.win.makeDisplayRegion()
            self.displayRegion.setSort(5)
            self.displayRegion.setClearDepthActive(1)
            self.displayRegion.setIncompleteRender(False)
            self.displayRegion.setCamera(self.cameraNP)

        self.displayRegion.setActive(True)
        self.do.accept('aspectRatioChanged', self.aspectRatioChanged)
        self.aspectRatioChanged()

    def aspectRatioChanged(self):
        # Scaling from -1 to +1
        idealTop = 0.66
        idealBottom = -0.74

        aspectRatio = self.app.panda.getAspectRatio()
        top = idealTop * min(aspectRatio * 3. / 4, 1)
        bottom = idealBottom * min(aspectRatio * 3. / 4, 1)

        self.displayRegion.setDimensions(0, 1, 0.5 * (1 + bottom),
                                         0.5 * (1 + top))

        windowRatio = 2 * aspectRatio / (top - bottom)

        self.cameraNP.setScale(windowRatio * 3. / 4, 1.0, 1.0)

    def updateCredits(self, task):
        deltaT = task.time - self.lastTime
        self.lastTime = task.time

        z = self.cameraNP.getZ()
        z -= deltaT * CREDITS_SCROLL_SPEED
        self.cameraNP.setZ(z)
        return Task.cont
class UpAllTheWay(ShowBase):
  def __init__(self):
    ShowBase.__init__(self)
    self.setupLights()
    self.setup()
    
    # Accept the control keys for movement and rotation
    self.accept('escape', self.doExit)
    self.accept('f1', self.toggleHelp)
    self.accept('f3', self.toggleDebug)
    self.accept('space', self.player.doJump)
    self.accept("a", self.player.setKey, ["left", True])
    self.accept("a-up", self.player.setKey, ["left", False])
    self.accept("d", self.player.setKey, ["right", True])
    self.accept("d-up", self.player.setKey, ["right", False])
    self.accept("w", self.player.setKey, ["forward", True])
    self.accept("w-up", self.player.setKey, ["forward", False])
    self.accept("s", self.player.setKey, ["reverse", True])
    self.accept("s-up", self.player.setKey, ["reverse", False])

    # Task
    taskMgr.add(self.update, 'updateWorld')

    base.setBackgroundColor(0.1, 0.1, 0.8, 1)
    base.setFrameRateMeter(True)
#     base.disableMouse()
    base.camera.setPos(self.player.getCharacterNP().getPos())
    base.camera.setHpr(self.player.getCharacterNP().getHpr())
    base.camera.lookAt(self.player.getCharacterNP())
    # 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)
    
    # Add environment
    self.env = self.loader.loadModel("models/env/PeachSky")
    self.env.reparentTo(render)
    
    # Add text
    self.collectibleCounter = 0
    self.collectibleTotal = Data.collectibleTotal1
    self.collectibleIndicator = "Level " + str(Data.currentLevel) + ": collectible items - " + str(self.collectibleCounter) + "/" + str(self.collectibleTotal)
    self.timeIndicator = "Time left - " + str(Data.maxTime/Data.frameRate)
    self.helpIndicator = "[F1] - Help"
    self.inst1 = self.addInstructions(0.06, self.collectibleIndicator)
    self.inst2 = self.addInstructions(0.12, self.timeIndicator)
    self.inst3 = self.addInstructions(0.18, self.helpIndicator)
    
    # Help variable
    self.helpOn = False
  
  # Function to put instructions on the screen.
  def addInstructions(self, pos, msg):
    return OnscreenText(text=msg, style=1, fg=(89/255, 255/255, 56/255, 1), 
                        scale=.06, shadow=(0, 0, 0, 1), parent = base.a2dTopLeft, 
                        pos=(0.04, -pos - 0.02), align = TextNode.ALeft)
  
  def addVictoryText(self, msg):
    return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), 
                        scale=.25, shadow=(0, 0, 0, 1), parent = base.a2dTopLeft, 
                        pos=(0.6, -1), align = TextNode.ALeft)
  
  def doExit(self):
    self.cleanup()
    sys.exit(1)

  def toggleHelp(self):
    if (self.helpOn == False):
      self.helpOn = True
      taskMgr.remove('updateWorld')
      self.inst1.destroy()
      self.inst2.destroy()
      self.inst3.destroy()
      self.inst1 = self.addInstructions(0.06, "Game paused")
      self.inst2 = self.addInstructions(0.12, "")
      self.inst3 = self.addInstructions(0.18, "STORY")
      self.inst4 = self.addInstructions(0.24, "Di is a CSULA CS graduate student fighting for his CS MS degree.")
      self.inst5 = self.addInstructions(0.30, "He's on his journey to gain his degree, but it will not be easy.")
      self.inst6 = self.addInstructions(0.36, "He needs to go upward and collect books as knowledge, and avoid professor attacks.")
      self.inst7 = self.addInstructions(0.42, "Eventually he will reach a new height in life and collect his diploma in a magic box!")
      self.inst8 = self.addInstructions(0.48, "")
      self.inst9 = self.addInstructions(0.54, "ACTION KEYS")
      self.inst10 = self.addInstructions(0.60, "[W] - forward, [S] - reverse, [A] - turn left, [D] - turn right, [SPACE] - jump")
    else:
      self.helpOn = False
      taskMgr.add(self.update, 'updateWorld')
      self.inst1.destroy()
      self.inst2.destroy()
      self.inst3.destroy()
      self.inst4.destroy()
      self.inst5.destroy()
      self.inst6.destroy()
      self.inst7.destroy()
      self.inst8.destroy()
      self.inst9.destroy()
      self.inst10.destroy()
      self.inst1 = self.addInstructions(0.06, self.collectibleIndicator)
      self.inst2 = self.addInstructions(0.12, self.timeIndicator)
      self.inst3 = self.addInstructions(0.18, self.helpIndicator)
  
  def toggleDebug(self):
    if self.debugNP.isHidden():
      self.debugNP.show()
    else:
      self.debugNP.hide()
      
  def level1Selector(self):
    Data.maxTime = 7200
    Data.detectDistance = 4
    Data.dropRate = 60
    self.collectibleTotal = Data.collectibleTotal1
    self.player.resetCharacter()
    self.level2Music.stop()
    self.level1Music.play()
  
  def level2Selector(self):
    Data.maxTime = 9000
    Data.detectDistance = 5
    Data.dropRate = 30
    self.collectibleTotal = Data.collectibleTotal2
    self.player.resetCharacter()
    self.level1Music.stop()
    self.level2Music.play()
      
  def createMainMenu(self):
    self.v = [0]
    self.myFrame = DirectFrame(frameColor = (0.8, 0.8, 0.8, 1), frameSize = (-0.5, 0.5, -0.3, 0.3), pos = (0, 0, 0))
    self.myLabel = DirectLabel(text = 'MAIN  MENU', scale = 0.1, pos = (0, 0, 0.16))
    self.buttons = [
      DirectRadioButton(text = 'Level 1', variable = self.v, value = [1], scale = 0.1, pos = (-0.2,0,-0.05), command = self.setLevel),
      DirectRadioButton(text = 'Level 2', variable = self.v, value = [2], scale = 0.1, pos = (0.25,0,-0.05), command = self.setLevel)
    ]
    for button in self.buttons:
      button.setOthers(self.buttons)
    self.start = DirectButton(text = "START", scale = 0.1, pos = (-0.2,0,-0.2), command = self.levelStart)
    self.quit = DirectButton(text = "QUIT", scale = 0.1, pos = (0.2,0,-0.2), command = self.doExit)
    
  def setLevel(self):
    Data.currentLevel = self.v[0]
  
  def levelStart(self):
    self.myFrame.destroy()
    self.myLabel.destroy()
    self.buttons[0].destroy()
    self.buttons[1].destroy()
    self.start.destroy()
    self.quit.destroy()
    
    if (Data.currentLevel == 1):
      self.level1Selector()
    else:
      self.level2Selector()
              
  def update(self, task):
    dt = globalClock.getDt()
    self.player.move()
    self.world.doPhysics(dt, 4, 1./240.)
    self.processMovements()
    self.countdown()
    self.refreshCollectibleCount()

    camvec = self.player.getCharacterNP().getPos() - base.camera.getPos()
    camvec.setZ(0)
    camdist = camvec.length()
    camvec.normalize()
    # If the camera is too far from Di, move it closer.
    if (camdist > 25.0):
      base.camera.setPos(base.camera.getPos() + camvec*(camdist-20))
      camdist = 25.0
    # If the camera is too close to Di, move it farther.
    if (camdist < 5.0):
      base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
      camdist = 5.0

    self.floater.setPos(self.player.getCharacterNP().getPos())
    self.floater.setZ(self.player.getCharacterNP().getZ() + 2.0)
    
    if (self.floater.getZ() > -20.0):
      base.camera.setZ(self.floater.getZ() + 20.0)
    else:
      base.camera.setZ(0.0)
    
    base.camera.lookAt(self.floater)
    
    if (self.player.getCharacterNP().getZ() < -40):
      self.player.resetCharacter()
      self.laughSound.play()

    return task.cont

  def cleanup(self):
    self.world = None
    self.render.removeNode()

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

    self.render.clearLight()
    self.render.setLight(alightNP)
    self.render.setLight(dlightNP)

  def setup(self):
    # World
    self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug'))
    self.debugNP.hide()

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))
    self.world.setDebugNode(self.debugNP.node())

    # Create starting platforms
    Platform(self.render, self.world, self.loader, 0, 1, 2, 0, 0, -3)
    Platform(self.render, self.world, self.loader, 0, 2, 2, 100, 100, -3)

    # Generate platforms
    PlatformFactory(self.render, self.world, self.loader)
    
    # Create player character
    self.player = Player(self.render, self.world, 0, 0, 0)
    
    # Music and sound
    self.level1Music = base.loader.loadSfx("sounds/level1.mp3")
    self.level1Music.setLoop()
    self.level1Music.setVolume(0.4)
    self.level1Music.play()
    self.level2Music = base.loader.loadSfx("sounds/level2.mp3")
    self.level2Music.setLoop()
    self.level2Music.setVolume(0.4)
    self.winMusic = base.loader.loadSfx("sounds/win.ogg")
    self.winMusic.setLoop()
    self.winMusic.setVolume(0.4)
    self.laughSound = base.loader.loadSfx("sounds/laugh.ogg")
    self.collectSound = base.loader.loadSfx("sounds/collect.mp3")
    
    self.createMainMenu()
  
  # Handle contacts
  def processMovements(self):
    if (len(Data.books) > 0):
      for book in Data.books:
        self.distanceTest(book)
    
    if (len(Data.door) > 0):
      self.distanceTest(Data.door[0])
      
    if (len(Data.akises) > 0):
      for akis in Data.akises:
        self.distanceTest(akis)
        
    if (len(Data.kangs) > 0):
      for kang in Data.kangs:
        self.distanceTest(kang)
        
    if (len(Data.balls) > 0):
      for ball in Data.balls:
        self.distanceTest(ball)
        
    if (len(Data.magicBox) > 0):
      self.distanceTest(Data.magicBox[0])

  def distanceTest(self, secondObject):
    name = secondObject.getActor().getName()
    distance = self.getDistance(self.player.getCharacterNP(), secondObject.getNP())
    
    if (distance > Data.contactDistance and distance <= Data.detectDistance):
      if ("Akis" in name or "Kang" in name):
        secondObject.move(self.player)
      if ("Kang" in name and Data.maxTime % Data.dropRate == 0):
        secondObject.drop(self.player)
    
    if (distance <= Data.winningDistance):
      if (self.collectibleCounter == self.collectibleTotal):
        if ("Door" in name):
          self.collectibleCounter = 0
          Data.currentLevel = 2
          self.level2Selector()
        elif ("MagicBox" in name):
          taskMgr.remove('updateWorld')
          self.addVictoryText("GRADUATED!")
          self.level2Music.stop()
          self.winMusic.play()
    
    if (distance <= Data.contactDistance):
      if ("Collectible" in name):
        secondObject.killNP()
        secondObject.getActorModelNP().removeNode()
        self.collectSound.play()
        self.collectibleCounter += 1
      elif ("Akis" in name or "Kang" in name or "Ball" in name):
        self.player.resetCharacter()
        self.laughSound.play()
          
  def refreshCollectibleCount(self):
    self.collectibleIndicator = "Level " + str(Data.currentLevel) + ": collectible items - " + str(self.collectibleCounter) + "/" + str(self.collectibleTotal)
    self.inst1.destroy()
    self.inst1 = self.addInstructions(0.06, self.collectibleIndicator)
    
    # refresh time
    self.timeIndicator = "Time left - " + str(Data.maxTime/Data.frameRate)
    self.inst2.destroy()
    self.inst2 = self.addInstructions(0.12, self.timeIndicator)
  
  def countdown(self):
    if (Data.maxTime > 0):
      Data.maxTime -= 1
    elif (Data.maxTime == 0):
      taskMgr.remove('updateWorld')
      self.addVictoryText("YOU LOST!!!")
      
  # UTIL METHODS
  def getDistance(self, one, two):
    vec = one.getPos() - two.getPos()
    return vec.length()