Exemple #1
0
class LinearFog(object):
    def __init__(self, r, g, b, min_dist, max_dist):
        self.fog = Fog("GlobalFog")
        self.fog.setColor(r, g, b)
        dist_base = 100 if G.debug else 0
        min_dist += dist_base
        max_dist += dist_base
        assert min_dist < max_dist
        self.fog.set_linear_range(min_dist, max_dist)
        self.fog.setLinearFallback(15, min_dist, max_dist)
        G.setBackgroundColor(r, g, b, 1)
        G.render.setFog(self.fog)
        self._enabled = True

    def switch(self):
        self._enabled = not self._enabled
        self.set_enabled(self._enabled)

    def set_enabled(self, enabled):
        self._enabled = enabled
        if enabled:
            G.render.setFog(self.fog)
        else:
            G.render.clear_fog()

    def destory(self):
        G.render.clear_fog()
Exemple #2
0
    def __init__(self, *args, **kwargs):
        template.Panda.__init__(self, *args, **kwargs)
        print "Hurray!"

        self.cube = self.loader.loadModel("models/low-cube")
        self.cube.reparentTo(self.render)
        self.cube2 = self.loader.loadModel("models/low-cube")
        self.cube2.reparentTo(self.render)
        self.cube2.setPos(self.cube, 10,20,30)
        self.cube2.setHpr(175,3,45)

        self.taskMgr.add(self.update, "update")
        self.taskMgr.add(self.move, "move")
        self._dir = 1

        colour = (0.5,0.8,0.8)
        linfog = Fog("A linear-mode Fog node")
        linfog.setColor(*colour)
        linfog.setLinearRange(0,320)
        linfog.setLinearFallback(45,160,320)
        render.attachNewNode(linfog)
        render.setFog(linfog)
Exemple #3
0
class VisualTest(ShowBase):
    def __init__(self):
        super().__init__(self)
        self.var1 = 0
        self.scene = loader.loadModel("models/world")
        playerTexture = loader.loadTexture("models/starfoxShip.jpg")
        self.player = self.scene.find("player")
        self.player.setTexture(playerTexture)

        base.setBackgroundColor(0.1, 0.1, 0.1, 1)
        enemyTexture = loader.loadTexture("models/enemyShip.jpg")
        self.enemy = self.scene.find("enemy1")
        self.enemy.setTexture(enemyTexture)

        self.basePlane = self.scene.find("basePlane")

        self.scene.reparentTo(self.render)
        self.player.setPos(50, 50, 3)
        self.enemy.setPos(50, 55, 0)

        self.ambient = AmbientLight("ambient")
        self.ambient.color = (0.1, 0.1, 0.1, 1)
        self.ambientPath = self.render.attachNewNode(self.ambient)
        render.setLight(self.ambientPath)

        self.dirLight = DirectionalLight("dir light")
        self.dirLight.color = (1, 1, 1, 1)
        self.dirLightPath = self.render.attachNewNode(self.dirLight)
        self.dirLightPath.setHpr(0, -90, 0)
        self.dirLight.setShadowCaster(True, 512, 512)
        render.setLight(self.dirLightPath)

        self.pointLight = PointLight("point light")
        self.pointLight.color = (1, 1, 1, 1)
        self.pointLightPath = self.render.attachNewNode(self.pointLight)
        self.pointLightPath.setPos(50, 52.5, 4)
        self.pointLight.attenuation = (.5, 0, 0)
        self.pointLight.setShadowCaster(True, 1024, 1024)
        self.render.setLight(self.pointLightPath)

        self.fog = Fog("fog")
        self.fog.setColor(0.1, 0.1, 0.1)
        self.fog.setExpDensity(.3)
        self.fog.setLinearRange(150, 300)
        self.fog.setLinearFallback(45, 160, 320)
        self.render.setFog(self.fog)

        self.render.setShaderAuto()
        self.render.setAntialias(AntialiasAttrib.MAuto)

        filters = CommonFilters(base.win, base.cam)
        filters.setBloom(size="large")
        filters.setAmbientOcclusion(strength=0.6, falloff=0.0005, radius=0.1)
        filters.setCartoonInk(separation=2, color=(0, 0, 0, 1))
        self.taskMgr.add(self.update, "update")

    def update(self, evt):
        self.var1 = self.var1 + 0.1
        #self.dirLight.color = (self.var1,0,1,1)
        #self.dirLightPath.setHpr(self.var1,-self.var1,0)
        self.camera.setPos(60 + self.var1, 60 + self.var1, 20)
        #self.pointLightPath.setPos(30+self.var1 ,52.5,4)
        self.camera.lookAt(self.player)

        return Task.cont
class ToontownFogManager:
    def __init__(self):
        self.fog = None
        self.fogMode = None
        print("Initialized Fog Manager")

        self.fog = Fog("ActiveFog")
        self.fog.setColor(1, 1, 1)

        self.fogTypes = {
            0: Fog.MExponential,
            1: Fog.MExponentialSquared,
            2: Fog.MLinear
        }

    def setFog(self, np):
        np.setFog(self.fog)

    def setColor(self, r, g, b):
        self.fog.setColor(r, g, b)

    def clearFog(self):
        return render.clearFog()

    def getFogMode(self):
        self.fogMode = self.fog.getMode()

    def setFogMode(self, id):
        mode = self.fog.setMode(self.fogTypes[id])
        self.fogMode = mode

    ## For Exponential Fog

    def setDensity(self, density):
        """
        Determines the density value used for exponential fog calculations.

        :param float density: A value between [0, 1]
        """
        self.fog.setExpDensity(density)

    ## For Linear Fog

    def setLinearRange(self, range, opacity):
        """
        Specifies the effects of the fog in linear distance units. This is only used if the mode is M_linear.

        This specifies a fog that begins at distance onset units from the origin, and becomes totally opaque at distance
        <opaque units> from the origin, along the forward axis (usually Y).

        This function also implicitly sets the mode the M_linear, if it is not already set.

        :param float opacity: [0, 1]
        """
        self.fog.setLinearRange(range, opacity)

    def setLinearFallback(self, angle, onset, opaque):
        """
        :param float angle: the minimum viewing angle (angle between the camera direction and fog direction) at which
         the fallback effect will be employed.
        :type onset: float
        :param float opaque: [0, 1]

        Defines how the fog should be rendered when the fog effect is diminished in this way.

        Onset and opaque specify camera-relative onset and opaque distances that will be fallen back on, overriding the
        Fog node's own onset and opaque distances.

        The linear fallback workaround will only look good in certain situations, for example when the fog is deep inside a dark cave.

        So in general, exponential mode fog is more useful than the default linear mode fog.
        """
        self.fog.setLinearFallback(angle, onset, opaque)
Exemple #5
0
    def setIndex(self, index):
        self.index = index
        
        hood = self.cr.playGame.hood
        hoodAbbr = None
        
        if self.index == 0:
            hoodAbbr = hood.abbr
        elif self.index == 1:
            hoodAbbr = 'TT' #ZoneUtil.ZoneId2HoodAbbr[self.toZone]
        self.hoodAbbr = hoodAbbr
        
        findStr = '**/prop_trolley_station_' + hoodAbbr + '_DNARoot'
        
        self.trolleyStation = hood.loader.geom.find(findStr)
        self.trolleyStation.flattenStrong()
        self.trolleyCar = self.trolleyStation.find('**/trolley_car')
        self.trolleyKey = self.trolleyStation.find('**/key')

        base.audio3d.attachSoundToObject(self.trolleyAwaySfx, self.trolleyCar)
        base.audio3d.attachSoundToObject(self.trolleyBellSfx, self.trolleyCar)

        exitFog = Fog('TrolleyExitFog')
        exitFog.setColor(0.0, 0.0, 0.0)
        exitFog.setLinearOnsetPoint(30.0, 14.0, 0.0)
        exitFog.setLinearOpaquePoint(37.0, 14.0, 0.0)
        exitFog.setLinearFallback(70.0, 999.0, 1000.0)
        self.trolleyExitFog = self.trolleyStation.attachNewNode(exitFog)
        self.trolleyExitFogNode = exitFog
        enterFog = Fog('TrolleyEnterFog')
        enterFog.setColor(0.0, 0.0, 0.0)
        enterFog.setLinearOnsetPoint(0.0, 14.0, 0.0)
        enterFog.setLinearOpaquePoint(-7.0, 14.0, 0.0)
        enterFog.setLinearFallback(70.0, 999.0, 1000.0)
        self.trolleyEnterFog = self.trolleyStation.attachNewNode(enterFog)
        self.trolleyEnterFogNode = enterFog
        self.trolleyCar.setFogOff()

        tn = TextNode('trolleycountdowntext')
        tn.setFont(CIGlobals.getMickeyFont())
        tn.setTextColor(1, 0, 0, 1)
        tn.setAlign(TextNode.ACenter)

        self.keys = self.trolleyCar.findAllMatches('**/key')
        self.numKeys = self.keys.getNumPaths()
        self.keyInit = []
        self.keyRef = []
        for i in range(self.numKeys):
            key = self.keys[i]
            key.setTwoSided(1)
            ref = self.trolleyCar.attachNewNode('key' + `i` + 'ref')
            ref.setPosHpr(key, 0, 0, 0, 0, 0, 0)
            self.keyRef.append(ref)
            self.keyInit.append(key.getTransform())

        self.frontWheels = self.trolleyCar.findAllMatches('**/front_wheels')
        self.numFrontWheels = self.frontWheels.getNumPaths()
        self.frontWheelInit = []
        self.frontWheelRef = []
        for i in range(self.numFrontWheels):
            wheel = self.frontWheels[i]
            ref = self.trolleyCar.attachNewNode('frontWheel' + `i` + 'ref')
            ref.setPosHpr(wheel, 0, 0, 0, 0, 0, 0)
            self.frontWheelRef.append(ref)
            self.frontWheelInit.append(wheel.getTransform())

        self.backWheels = self.trolleyCar.findAllMatches('**/back_wheels')
        self.numBackWheels = self.backWheels.getNumPaths()
        self.backWheelInit = []
        self.backWheelRef = []
        for i in range(self.numBackWheels):
            wheel = self.backWheels[i]
            ref = self.trolleyCar.attachNewNode('backWheel' + `i` + 'ref')
            ref.setPosHpr(wheel, 0, 0, 0, 0, 0, 0)
            self.backWheelRef.append(ref)
            self.backWheelInit.append(wheel.getTransform())

        trolleyAnimationReset = Func(self.resetAnimation)
        trolleyEnterStartPos = Point3(-20, 14, -1)
        trolleyEnterEndPos = Point3(15, 14, -1)
        trolleyEnterPos = Sequence(name='TrolleyEnterPos')
        trolleyEnterPos.append(Func(self.trolleyCar.setFog, self.trolleyEnterFogNode))
        trolleyEnterPos.append(self.trolleyCar.posInterval(TROLLEY_ENTER_TIME, trolleyEnterEndPos, startPos=trolleyEnterStartPos, blendType='easeOut'))
        trolleyEnterPos.append(Func(self.trolleyCar.setFogOff))
        trolleyEnterTrack = Sequence(trolleyAnimationReset, trolleyEnterPos, name='trolleyEnter')
        keyAngle = round(TROLLEY_ENTER_TIME) * 360
        dist = Vec3(trolleyEnterEndPos - trolleyEnterStartPos).length()
        wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
        trolleyEnterAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=TROLLEY_ENTER_TIME, blendType='easeOut', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
        trolleyEnterSoundTrack = SoundInterval(self.trolleyAwaySfx, node=self.trolleyCar)
        self.trolleyEnterTrack = Parallel(trolleyEnterTrack, trolleyEnterAnimateInterval, trolleyEnterSoundTrack)
        trolleyExitStartPos = Point3(15, 14, -1)
        trolleyExitEndPos = Point3(50, 14, -1)
        trolleyExitPos = Sequence(name='TrolleyExitPos')
        trolleyExitPos.append(Func(self.trolleyCar.setFog, self.trolleyExitFogNode))
        trolleyExitPos.append(self.trolleyCar.posInterval(TROLLEY_EXIT_TIME, trolleyExitEndPos, startPos=trolleyExitStartPos, blendType='easeIn'))
        trolleyExitPos.append(Func(self.trolleyCar.setFogOff))
        trolleyExitStartPos = Point3(15, 14, -1)
        trolleyExitEndPos = Point3(50, 14, -1)
        trolleyExitBellInterval = SoundInterval(self.trolleyBellSfx, node=self.trolleyCar)
        trolleyExitAwayInterval = SoundInterval(self.trolleyAwaySfx, node=self.trolleyCar)
        keyAngle = round(TROLLEY_EXIT_TIME) * 360
        dist = Vec3(trolleyExitEndPos - trolleyExitStartPos).length()
        wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
        trolleyExitAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=TROLLEY_EXIT_TIME, blendType='easeIn', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
        self.trolleyExitTrack = Parallel(trolleyExitPos, trolleyExitBellInterval, trolleyExitAwayInterval, trolleyExitAnimateInterval, name=self.uniqueName('trolleyExit'))

        self.countdownText = self.trolleyStation.attachNewNode(tn)
        self.countdownText.setScale(3.0)
        self.countdownText.setPos(14.58, 10.77, 11.17)
        
        try:
            self.trolleySphere = self.trolleyStation.find('**/trolley_sphere')
            self.trolleySphere.setName('trolley{0}_sphere'.format(hoodAbbr))
        except:
            pass
    def generate(self):
        DistributedObject.announceGenerate(self)
        self.trolleyStation = self.cr.playGame.hood.loader.geom.find('**/prop_trolley_station_DNARoot')
        self.trolleyCar = self.trolleyStation.find('**/trolley_car')
        self.trolleyKey = self.trolleyStation.find('**/key')
        exitFog = Fog('TrolleyExitFog')
        exitFog.setColor(0.0, 0.0, 0.0)
        exitFog.setLinearOnsetPoint(30.0, 14.0, 0.0)
        exitFog.setLinearOpaquePoint(37.0, 14.0, 0.0)
        exitFog.setLinearFallback(70.0, 999.0, 1000.0)
        self.trolleyExitFog = self.trolleyStation.attachNewNode(exitFog)
        self.trolleyExitFogNode = exitFog
        enterFog = Fog('TrolleyEnterFog')
        enterFog.setColor(0.0, 0.0, 0.0)
        enterFog.setLinearOnsetPoint(0.0, 14.0, 0.0)
        enterFog.setLinearOpaquePoint(-7.0, 14.0, 0.0)
        enterFog.setLinearFallback(70.0, 999.0, 1000.0)
        self.trolleyEnterFog = self.trolleyStation.attachNewNode(enterFog)
        self.trolleyEnterFogNode = enterFog
        self.trolleyCar.setFogOff()
        tn = TextNode('trolleycountdowntext')
        tn.setFont(CIGlobals.getMickeyFont())
        tn.setTextColor(1, 0, 0, 1)
        tn.setAlign(TextNode.ACenter)
        self.keys = self.trolleyCar.findAllMatches('**/key')
        self.numKeys = self.keys.getNumPaths()
        self.keyInit = []
        self.keyRef = []
        for i in range(self.numKeys):
            key = self.keys[i]
            key.setTwoSided(1)
            ref = self.trolleyCar.attachNewNode('key' + `i` + 'ref')
            ref.iPosHpr(key)
            self.keyRef.append(ref)
            self.keyInit.append(key.getTransform())

        self.frontWheels = self.trolleyCar.findAllMatches('**/front_wheels')
        self.numFrontWheels = self.frontWheels.getNumPaths()
        self.frontWheelInit = []
        self.frontWheelRef = []
        for i in range(self.numFrontWheels):
            wheel = self.frontWheels[i]
            ref = self.trolleyCar.attachNewNode('frontWheel' + `i` + 'ref')
            ref.iPosHpr(wheel)
            self.frontWheelRef.append(ref)
            self.frontWheelInit.append(wheel.getTransform())

        self.backWheels = self.trolleyCar.findAllMatches('**/back_wheels')
        self.numBackWheels = self.backWheels.getNumPaths()
        self.backWheelInit = []
        self.backWheelRef = []
        for i in range(self.numBackWheels):
            wheel = self.backWheels[i]
            ref = self.trolleyCar.attachNewNode('backWheel' + `i` + 'ref')
            ref.iPosHpr(wheel)
            self.backWheelRef.append(ref)
            self.backWheelInit.append(wheel.getTransform())

        trolleyAnimationReset = Func(self.resetAnimation)
        trolleyEnterStartPos = Point3(-20, 14, -1)
        trolleyEnterEndPos = Point3(15, 14, -1)
        trolleyEnterPos = Sequence(name='TrolleyEnterPos')
        trolleyEnterPos.append(Func(self.trolleyCar.setFog, self.trolleyEnterFogNode))
        trolleyEnterPos.append(self.trolleyCar.posInterval(TROLLEY_ENTER_TIME, trolleyEnterEndPos, startPos=trolleyEnterStartPos, blendType='easeOut'))
        trolleyEnterPos.append(Func(self.trolleyCar.setFogOff))
        trolleyEnterTrack = Sequence(trolleyAnimationReset, trolleyEnterPos, name='trolleyEnter')
        keyAngle = round(TROLLEY_ENTER_TIME) * 360
        dist = Vec3(trolleyEnterEndPos - trolleyEnterStartPos).length()
        wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
        trolleyEnterAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=TROLLEY_ENTER_TIME, blendType='easeOut', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
        trolleyEnterSoundTrack = SoundInterval(self.trolleyAwaySfx, node=self.trolleyCar)
        self.trolleyEnterTrack = Parallel(trolleyEnterTrack, trolleyEnterAnimateInterval, trolleyEnterSoundTrack)
        trolleyExitStartPos = Point3(15, 14, -1)
        trolleyExitEndPos = Point3(50, 14, -1)
        trolleyExitPos = Sequence(name='TrolleyExitPos')
        trolleyExitPos.append(Func(self.trolleyCar.setFog, self.trolleyExitFogNode))
        trolleyExitPos.append(self.trolleyCar.posInterval(TROLLEY_EXIT_TIME, trolleyExitEndPos, startPos=trolleyExitStartPos, blendType='easeIn'))
        trolleyExitPos.append(Func(self.trolleyCar.setFogOff))
        trolleyExitStartPos = Point3(15, 14, -1)
        trolleyExitEndPos = Point3(50, 14, -1)
        trolleyExitBellInterval = SoundInterval(self.trolleyBellSfx, node=self.trolleyCar)
        trolleyExitAwayInterval = SoundInterval(self.trolleyAwaySfx, node=self.trolleyCar)
        keyAngle = round(TROLLEY_EXIT_TIME) * 360
        dist = Vec3(trolleyExitEndPos - trolleyExitStartPos).length()
        wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
        trolleyExitAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=TROLLEY_EXIT_TIME, blendType='easeIn', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
        self.trolleyExitTrack = Parallel(trolleyExitPos, trolleyExitBellInterval, trolleyExitAwayInterval, trolleyExitAnimateInterval, name=self.uniqueName('trolleyExit'))
        self.countdownText = self.trolleyStation.attachNewNode(tn)
        self.countdownText.setScale(3.0)
        self.countdownText.setPos(14.58, 10.77, 11.17)
        self.acceptOnce('entertrolley_sphere', self.__handleTrolleyTrigger)
class VisualTest(ShowBase):
    def __init__(self):
        super().__init__(self)

        self.scene = loader.loadModel("models/world")
        self.player = self.scene.find("player")
        self.basePlane = self.scene.find("basePlane")
        self.player.reparentTo(self.render)
        self.basePlane.reparentTo(self.render)

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

        self.camera.setPos(self.render, 0, -100, 70)
        base.setBackgroundColor(0.1, 0.1, 0.1, 1)

        self.dirLight = DirectionalLight("dir light")
        self.dirLight.setShadowCaster(True, 512, 512)
        self.dirLight.color = (1, 0, 1, 1)
        self.dirLightPath = self.render.attachNewNode(self.dirLight)
        self.dirLightPath.setHpr(45, -60, 0)
        render.setLight(self.dirLightPath)
        self.angleTime = 0.0
        self.totalAngleTime = 10.0
        self.hAngle = 0

        self.ambientLight = AmbientLight("ambient")
        self.ambientLight.color = (0.1, 0.1, 0.1, 1)
        self.ambLightPath = self.render.attachNewNode(self.ambientLight)
        render.setLight(self.ambLightPath)

        self.pointLight = PointLight("point")
        self.pointLight.color = (1, 1, 1, 1)
        self.pointLightPath = self.render.attachNewNode(self.pointLight)
        self.pointLightPath.setPos(0, 5, 5)
        self.pointLight.setShadowCaster(True, 512, 512)
        self.render.setLight(self.pointLightPath)

        self.fog = Fog("fog")
        self.fog.setColor(.1, .1, .1)
        self.fog.setExpDensity(.3)
        self.fog.setLinearRange(150, 200)
        self.fog.setLinearFallback(45, 160, 320)
        render.setFog(self.fog)
        self.render.setShaderAuto()

        self.p = self.render.attachNewNode("particles")
        base.enableParticles()
        p = ParticleEffect()
        p.loadConfig('./mysmoke.ptf')
        p.start(parent=self.p, renderParent=render)
        self.p.setPos(self.player, 0, 0, 2)

        self.font = loader.loadFont('./fonts/Magenta.ttf')
        self.sceneName = DirectLabel(text="Starfox visual test",
                                     parent=self.aspect2d,
                                     scale=0.07,
                                     pos=(-1.2, 0, 0.85),
                                     text_font=self.font,
                                     relief=None,
                                     text_fg=(1, 1, 1, 1),
                                     textMayChange=True,
                                     text_align=TextNode.ALeft)

        self.foxy = OnscreenImage(image='./UI/fox-icon-png-8.png',
                                  pos=(1.2, 9, 0.85),
                                  scale=0.1)
        self.foxy.setTransparency(True)

        self.controlsPanel = DirectDialog(frameSize=(-1.1, 1.1, -0.9, -0.7),
                                          relief=DGG.FLAT)

        btn = DirectButton(text="Rotate",
                           command=self.doRotate,
                           image='./UI/fox-icon-png-8.png',
                           pos=(-0.9, 0, -0.8),
                           parent=self.controlsPanel,
                           scale=0.07,
                           relief=None)

        btn2 = DirectButton(text="Anin Light",
                            command=self.doLight,
                            image='./UI/fox-icon-png-8.png',
                            pos=(-0.7, 0, -0.8),
                            parent=self.controlsPanel,
                            scale=0.07,
                            relief=None)

        self.camera.lookAt(self.player)
        self.makeRotation = False
        self.rotateAngles = 0
        self.animLight = False

        filter = CommonFilters(base.win, base.cam)
        filter.setBloom(size="large", intensity=2)
        #filter.setAmbientOcclusion(strength = 5,  radius = 3)
        filter.setCartoonInk(separation=4)

    def doRotate(self):
        self.makeRotation = True
        return 0

    def doLight(self):
        self.animLight = True
        return 0

    def update(self, evt):
        ang = (self.angleTime / self.totalAngleTime)
        #self.camera.setPos(self.player, ang*100,ang*100,ang*100)

        self.player.setPos(self.render, 0, 0, 1)
        #self.camera.lookAt( Vec3(0,300,0) )

        #self.p.setPos(self.player, 0,0,0,)
        # self.dirLightPath.setHpr(ang*360.0 ,-60,0)
        if (self.makeRotation):
            self.makeRotation = False
            self.rotateAngles = (self.rotateAngles + 90) % 360
            self.player.setHpr(self.rotateAngles, 0, 0)
            self.sceneName[
                "text"] = f"Starfox visual test ({self.rotateAngles})"

        self.camera.setPos(self.render, 10, 10, 10)
        self.camera.lookAt(self.player)

        if (ang >= 1):
            self.angleTime = 0
        self.angleTime = self.angleTime + globalClock.getDt()
        self.dirLight.color = (ang, 0, 1, 1)

        if self.animLight:
            self.pointLightPath.setPos(ang * 10 - 5, ang * 10 - 5, ang * 5)

        return Task.cont
class Starfox(ShowBase):
    def __init__(self):
        self.height = 500
        super().__init__(self)
        self.scene = self.loader.loadModel("./models/world.egg")
        playerTexture = loader.loadTexture("models/starfoxShip.jpg")
        enemyTexture = loader.loadTexture("models/enemyShip.jpg")
        bulletTexture = loader.loadTexture("models/shot.png")
        self.scene.reparentTo(self.render)

        base.setBackgroundColor(0.1, 0.1, 0.1, 1)

        self.player = self.scene.find("player")
        self.player.setPythonTag("ObjectController", Player(self.player))
        self.player.setTexture(playerTexture)

        self.building_enemy = self.scene.find("building_enemy")
        self.dynamic_enemy = self.scene.find("enemy1")
        self.dynamic_enemy.setTexture(enemyTexture)
        self.bullet = self.scene.find("bullet")
        self.bullet.setTexture(bulletTexture)

        base.cTrav = CollisionTraverser()
        self.CollisionHandlerEvent = CollisionHandlerEvent()
        base.enableParticles()
        self.CollisionHandlerEvent.addInPattern('into-%in')
        self.CollisionHandlerEvent.addOutPattern('out-%in')

        self.accept('into-collision_player', self.crash)
        self.accept('into-collision_plane', self.crash)
        self.accept('into-collision_enemy', self.crash)

        base.cTrav.addCollider(self.scene.find("player/collision**"),
                               self.CollisionHandlerEvent)
        base.cTrav.addCollider(self.scene.find("basePlane/collision**"),
                               self.CollisionHandlerEvent)

        self.player.find("**collision**").node().setFromCollideMask(0x3)
        self.player.find("**collision**").node().setIntoCollideMask(0x3)

        self.dynamic_enemy.find("**collision**").node().setFromCollideMask(0x5)
        self.dynamic_enemy.find("**collision**").node().setIntoCollideMask(0x5)

        self.building_enemy.find("**collision**").node().setFromCollideMask(
            0x5)
        self.building_enemy.find("**collision**").node().setIntoCollideMask(
            0x5)

        #base.cTrav.showCollisions(self.render)

        self.taskMgr.add(self.update, "update")
        InputManager.initWith(self, [
            InputManager.arrowUp, InputManager.arrowDown,
            InputManager.arrowLeft, InputManager.arrowRight,
            InputManager.space, InputManager.keyX, InputManager.keyV
        ])

        self.rails = self.scene.attachNewNode("rails")
        self.scene.find("basePlane").setHpr(70, 0, 0)
        self.rails.setPos(self.scene, 0, 0, 0)
        self.player.reparentTo(self.rails)
        self.player.setPos(self.rails, 0, 0, 0)
        self.rails_y = -50

        self.createStaticEnemy(self.building_enemy, 0, 50, 0)
        self.createStaticEnemy(self.building_enemy, -50, 50, 0)
        self.createStaticEnemy(self.building_enemy, -100, 50, 0)
        self.createStaticEnemy(self.building_enemy, -70, 130, 0)
        self.createStaticEnemy(self.building_enemy, -120, 80, 0)
        self.createStaticEnemy(self.building_enemy, -220, 130, 0)

        DynamicEnemy(self.dynamic_enemy,
                     self.scene,
                     Vec3(-230, 140, 10),
                     base.cTrav,
                     self.CollisionHandlerEvent,
                     type=ENEMY_TYPE.CHASER)
        #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-240,160,10) ,  base.cTrav, self.CollisionHandlerEvent)
        #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-250,200,10) ,  base.cTrav, self.CollisionHandlerEvent)
        #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-270,160,10) ,  base.cTrav, self.CollisionHandlerEvent)
        #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-250,200,10) ,  base.cTrav, self.CollisionHandlerEvent)

        self.building_enemy.hide()
        self.dynamic_enemy.hide()

        self.fog = Fog("fog")
        self.fog.setColor(0.1, 0.1, 0.1)
        self.fog.setExpDensity(.3)
        self.fog.setLinearRange(50, 150)
        self.fog.setLinearFallback(45, 160, 320)
        self.render.setFog(self.fog)

        self.dirLight = DirectionalLight("dir light")
        self.dirLight.color = (0.7, 0.7, 1, 1)
        self.dirLightPath = self.render.attachNewNode(self.dirLight)
        self.dirLightPath.setHpr(45, -45, 0)
        self.dirLight.setShadowCaster(True, 512, 512)
        render.setLight(self.dirLightPath)

        filters = CommonFilters(base.win, base.cam)
        filters.setBloom(size="large", mintrigger=0.2)

        self.render.setShaderAuto()

        self.initSounds()
        self.initUI()
        self.onGame = False

    def initUI(self):
        self.font = loader.loadFont('./fonts/Magenta.ttf')

        self.lifes = [
            OnscreenImage(image='./UI/fox-icon-png-8.png',
                          pos=(1.1, 0, 0.8),
                          scale=0.05),
            OnscreenImage(image='./UI/fox-icon-png-8.png',
                          pos=(1.2, 0, 0.8),
                          scale=0.05)
        ]

        self.lifes[0].setTransparency(True)
        self.lifes[1].setTransparency(True)

        self.dialogScreen = DirectDialog(frameSize=(-0.7, 0.7, -0.7, 0.7),
                                         relief=DGG.FLAT)

        s = OnscreenImage(image='./UI/fox-icon-png-8.png',
                          pos=(0, 0, -0.2),
                          scale=0.20,
                          parent=self.dialogScreen)
        s.setTransparency(True)

        self.titleUI = DirectLabel(text="Starfox Region 4",
                                   parent=self.dialogScreen,
                                   scale=0.1,
                                   pos=(0, 0, .2),
                                   text_font=self.font)

        self.btn = DirectButton(text="Start",
                                command=self.startGame,
                                pos=(0, 0, 0),
                                parent=self.dialogScreen,
                                scale=0.07)

    def startGame(self):
        self.dialogScreen.hide()
        self.flyingSound.play()
        self.onGame = True
        self.btn.hide()

    def initSounds(self):
        self.audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0],
                                                     self.camera)

        self.flyingSound = self.audio3d.loadSfx(
            "./sounds/great fox flying.mp3")
        self.flyingSound.setLoop(True)

        self.audio3d.attachSoundToObject(self.flyingSound, self.player)
        self.audio3d.setSoundVelocityAuto(self.flyingSound)
        self.audio3d.setListenerVelocityAuto()
        #self.audio3d.setDistanceFactor(100)
        self.audio3d.setDropOffFactor(0)

        self.fireSound = self.audio3d.loadSfx(
            "./sounds/arwing double laser one shot.mp3")
        self.crashSound = self.audio3d.loadSfx("./sounds/break.mp3")

    def createStaticEnemy(self, original, px, py, pz):
        be = original.copyTo(self.scene)
        be.setPos(px, py, pz)
        base.cTrav.addCollider(be.find("**collision**"),
                               self.CollisionHandlerEvent)
        """
        self.pointLight = PointLight("point light")
        self.pointLight.color = (1,1,1,1)
        self.pointLightPath = self.render.attachNewNode(self.pointLight)
        self.pointLightPath.setPos(px,py,pz)
        self.pointLight.attenuation = (1,0,0)
        #self.pointLight.setShadowCaster(True,1024,1024)
        self.render.setLight(self.pointLightPath)
        """

    def crash(self, evt):

        self.crashSound.play()
        objectInto = evt.getIntoNodePath().node().getParent(0).getPythonTag(
            "ObjectController")
        objectFrom = evt.getFromNodePath().node().getParent(0).getPythonTag(
            "ObjectController")

        if (objectInto != None):
            objectInto.crash(objectFrom)

        if (objectFrom != None):
            objectFrom.crash(objectInto)

        lifes = self.player.getPythonTag("ObjectController").getLifes()
        if (lifes <= 0):
            self.onGame = False
            self.dialogScreen.show()
            self.flyingSound.stop()

    def update(self, evt):
        #self.camera.setPos(0,-100,100)

        lifes = self.player.getPythonTag("ObjectController").getLifes()

        if (lifes > 2):
            self.lifes[0].show()
            self.lifes[1].show()
        elif (lifes > 1):
            self.lifes[0].show()
            self.lifes[1].hide()
        elif (lifes > 0):
            self.lifes[0].hide()
            self.lifes[1].hide()

        self.camera.lookAt(self.player)
        self.rails.setPos(self.scene, Path.getXOfY(self.rails_y), self.rails_y,
                          12.4)
        self.rails.setHpr(Path.getHeading(self.rails_y), 0, 0)
        self.dirLight.color = (self.rails_y / 600, 0.7, 1, 1)
        self.camera.setHpr(Path.getHeading(self.rails_y), 0, 0)

        if (self.onGame):
            self.rails_y = self.rails_y + globalClock.getDt() * 10
            #self.player.setPos(self.rails, 0, 0, sin(self.z/10.0)*40 )
            relX, relZ, isShooting = self.player.getPythonTag(
                "ObjectController").update(self.rails, globalClock.getDt())
            self.camera.setPos(self.rails, relX, -30, relZ)
            if (isShooting):
                self.fireSound.play()
                b = Bullet(
                    self.bullet, self.scene, self.player.getPos(self.scene),
                    base.cTrav, self.CollisionHandlerEvent,
                    self.scene.getRelativeVector(self.player,
                                                 Vec3(0, 1, 0)), 40, 0x4)
            enemies = self.scene.findAllMatches("dynamicEnemy")
            for e in enemies:
                enemy = e.getPythonTag("ObjectController")
                enemy.update(self.scene, globalClock.getDt(), self.player,
                             self.bullet)

            bullets = self.scene.findAllMatches("bulletC")
            for b in bullets:
                bullet = b.getPythonTag("ObjectController")
                bullet.update(self.scene, globalClock.getDt(), self.player)

        return Task.cont