def __init__(self, node):
     self.fish = Actor.Actor('phase_4/models/props/SZ_fish-mod', {
         'jump': 'phase_4/models/props/SZ_fish-jump',
         'swim': 'phase_4/models/props/SZ_fish-swim'
     },
                             copy=0)
     self.fish.hide()
     self.fish.reparentTo(node)
     self.splashSfxList = (
         loader.loadSfx('phase_4/audio/sfx/TT_splash1.ogg'),
         loader.loadSfx('phase_4/audio/sfx/TT_splash2.ogg'))
     self.geom = self.fish.getGeomNode()
     self.exitRipples = Ripples(self.geom)
     self.exitRipples.setBin('fixed', 25, 1)
     self.exitRipples.setPosHprScale(-0.3, 0.0, 1.24, 0.0, 0.0, 0.0, 0.7,
                                     0.7, 0.7)
     self.splash = Splash(self.geom, wantParticles=0)
     self.splash.setPosHprScale(-1, 0.0, 1.23, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
     randomSplash = random.choice(self.splashSfxList)
     self.track = Sequence(
         Wait(5 + 10 * random.random()),
         Parallel(
             Func(self.fish.show), self.fish.actorInterval('jump'),
             Sequence(Wait(0.25), Func(self.exitRipples.play, 0.75)),
             Sequence(
                 Wait(1.13), Func(self.splash.play),
                 SoundInterval(randomSplash, volume=0.3, node=self.fish),
                 Func(self.fish.hide))))
예제 #2
0
class FishAnimatedProp:

    def __init__(self, node):
        self.fish = Actor.Actor('phase_4/models/props/SZ_fish-mod', {'jump': 'phase_4/models/props/SZ_fish-jump', 'swim': 'phase_4/models/props/SZ_fish-swim'}, copy=0)
        self.fish.hide()
        self.fish.reparentTo(node)
        self.splashSfxList = (loader.loadSfx('phase_4/audio/sfx/TT_splash1.ogg'), loader.loadSfx('phase_4/audio/sfx/TT_splash2.ogg'))
        self.geom = self.fish.getGeomNode()
        self.exitRipples = Ripples(self.geom)
        self.exitRipples.setBin('fixed', 25, 1)
        self.exitRipples.setPosHprScale(-0.3, 0.0, 1.24, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
        self.splash = Splash(self.geom, wantParticles=0)
        self.splash.setPosHprScale(-1, 0.0, 1.23, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
        randomSplash = random.choice(self.splashSfxList)
        self.track = Sequence(Wait(5 + 10 * random.random()), Parallel(Func(self.fish.show), self.fish.actorInterval('jump'), Sequence(Wait(0.25), Func(self.exitRipples.play, 0.75)), Sequence(Wait(1.13), Func(self.splash.play), SoundInterval(randomSplash, volume = 0.3, node = self.fish), Func(self.fish.hide))))

    def delete(self):
        self.exitRipples.destroy()
        del self.exitRipples
        self.splash.destroy()
        del self.splash
        del self.track
        self.fish.removeNode()
        del self.fish
        del self.geom

    def enter(self):
        self.track.loop()

    def exit(self):
        self.track.finish()
        self.splash.stop()
        self.exitRipples.stop()
예제 #3
0
 def __loadStuff(self):
     rodId = self.av.getFishingRod()
     rodPath = FishGlobals.RodFileDict.get(rodId)
     if not rodPath:
         self.notify.warning('Rod id: %s model not found' % rodId)
         rodPath = RodFileDict[0]
     self.pole = Actor.Actor()
     self.pole.loadModel(rodPath)
     self.pole.loadAnims({'cast': 'phase_4/models/props/fishing-pole-chan'})
     self.pole.pose('cast', 0)
     self.ptop = self.pole.find('**/joint_attachBill')
     if self.line == None:
         self.line = Rope.Rope(self.uniqueName('Line'))
         self.line.setColor(1, 1, 1, 0.4)
         self.line.setTransparency(1)
         self.lineSphere = BoundingSphere(Point3(-0.6, -2, -5), 5.5)
     if self.bob == None:
         self.bob = loader.loadModel('phase_4/models/props/fishing_bob')
         self.bob.setScale(1.5)
         self.ripples = Ripples.Ripples(self.nodePath)
         self.ripples.setScale(0.4)
         self.ripples.hide()
     if self.splashSounds == None:
         self.splashSounds = (
             base.loadSfx('phase_4/audio/sfx/TT_splash1.ogg'),
             base.loadSfx('phase_4/audio/sfx/TT_splash2.ogg'))
     return
 def __init__(self, node):
     AnimatedProp.AnimatedProp.__init__(self, node)
     parent = node.getParent()
     self.fish = Actor.Actor(node, copy=0)
     self.fish.reparentTo(parent)
     self.fish.setTransform(node.getTransform())
     node.clearMat()
     self.fish.loadAnims({"jump": "phase_4/models/props/SZ_fish-jump", "swim": "phase_4/models/props/SZ_fish-swim"})
     self.splashSfxList = (
         loader.loadSfx("phase_4/audio/sfx/TT_splash1.ogg"),
         loader.loadSfx("phase_4/audio/sfx/TT_splash2.ogg"),
     )
     self.node = self.fish
     self.geom = self.fish.getGeomNode()
     self.exitRipples = Ripples(self.geom)
     self.exitRipples.setBin("fixed", 25, 1)
     self.exitRipples.setPosHprScale(-0.3, 0.0, 1.24, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
     self.splash = Splash(self.geom, wantParticles=0)
     self.splash.setPosHprScale(-1, 0.0, 1.23, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
     randomSplash = random.choice(self.splashSfxList)
     self.track = Sequence(
         Func(self.randomizePosition),
         Func(self.node.unstash),
         Parallel(
             self.fish.actorInterval("jump"),
             Sequence(Wait(0.25), Func(self.exitRipples.play, 0.75)),
             Sequence(Wait(1.14), Func(self.splash.play)),
         ),
         Wait(1),
         Func(self.node.stash),
         Wait(10 * random.random()),
         name=self.uniqueName("Fish"),
     )
예제 #5
0
class FishAnimatedProp(AnimatedProp.AnimatedProp):
    
    def __init__(self, node):
        AnimatedProp.AnimatedProp.__init__(self, node)
        parent = node.getParent()
        self.fish = Actor.Actor(node, copy = 0)
        self.fish.reparentTo(parent)
        self.fish.setTransform(node.getTransform())
        node.clearMat()
        self.fish.loadAnims({
            'jump': 'phase_4/models/props/SZ_fish-jump',
            'swim': 'phase_4/models/props/SZ_fish-swim' })
        self.splashSfxList = (loader.loadSfx('phase_4/audio/sfx/TT_splash1.mp3'), loader.loadSfx('phase_4/audio/sfx/TT_splash2.mp3'))
        self.node = self.fish
        self.geom = self.fish.getGeomNode()
        self.exitRipples = Ripples(self.geom)
        self.exitRipples.setBin('fixed', 25, 1)
        self.exitRipples.setPosHprScale(-0.29999999999999999, 0.0, 1.24, 0.0, 0.0, 0.0, 0.69999999999999996, 0.69999999999999996, 0.69999999999999996)
        self.splash = Splash(self.geom, wantParticles = 0)
        self.splash.setPosHprScale(-1, 0.0, 1.23, 0.0, 0.0, 0.0, 0.69999999999999996, 0.69999999999999996, 0.69999999999999996)
        randomSplash = random.choice(self.splashSfxList)
        self.track = Sequence(FunctionInterval(self.randomizePosition), Func(self.node.unstash), Parallel(self.fish.actorInterval('jump'), Sequence(Wait(0.25), Func(self.exitRipples.play, 0.75)), Sequence(Wait(1.1399999999999999), Func(self.splash.play), SoundInterval(randomSplash, volume = 0.80000000000000004, node = self.node))), Wait(1), Func(self.node.stash), Wait(4 + 10 * random.random()), name = self.uniqueName('Fish'))

    
    def delete(self):
        self.exitRipples.destroy()
        del self.exitRipples
        self.splash.destroy()
        del self.splash
        del self.track
        self.fish.removeNode()
        del self.fish
        del self.node
        del self.geom

    
    def randomizePosition(self):
        x = 5 * (random.random() - 0.5)
        y = 5 * (random.random() - 0.5)
        h = 360 * random.random()
        self.geom.setPos(x, y, 0)
        self.geom.setHpr(h, 0, 0)

    
    def enter(self):
        AnimatedProp.AnimatedProp.enter(self)
        self.track.loop()

    
    def exit(self):
        AnimatedProp.AnimatedProp.exit(self)
        self.track.finish()
        self.splash.stop()
        self.exitRipples.stop()
예제 #6
0
 def __init__(self, node):
     AnimatedProp.AnimatedProp.__init__(self, node)
     parent = node.getParent()
     self.fish = Actor.Actor(node, copy=0)
     self.fish.reparentTo(parent)
     self.fish.setTransform(node.getTransform())
     node.clearMat()
     self.fish.loadAnims({'jump': 'phase_4/models/props/SZ_fish-jump',
      'swim': 'phase_4/models/props/SZ_fish-swim'})
     self.splashSfxList = (loader.loadSfx('phase_4/audio/sfx/TT_splash1.mp3'), loader.loadSfx('phase_4/audio/sfx/TT_splash2.mp3'))
     self.node = self.fish
     self.geom = self.fish.getGeomNode()
     self.exitRipples = Ripples(self.geom)
     self.exitRipples.setBin('fixed', 25, 1)
     self.exitRipples.setPosHprScale(-0.3, 0.0, 1.24, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
     self.splash = Splash(self.geom, wantParticles=0)
     self.splash.setPosHprScale(-1, 0.0, 1.23, 0.0, 0.0, 0.0, 0.7, 0.7, 0.7)
     randomSplash = random.choice(self.splashSfxList)
     self.track = Sequence(FunctionInterval(self.randomizePosition), Func(self.node.unstash), Parallel(self.fish.actorInterval('jump'), Sequence(Wait(0.25), Func(self.exitRipples.play, 0.75)), Sequence(Wait(1.14), Func(self.splash.play), SoundInterval(randomSplash, volume=0.8, node=self.node))), Wait(1), Func(self.node.stash), Wait(4 + 10 * random.random()), name=self.uniqueName('Fish'))
예제 #7
0
 def __init__(self, parent = hidden, wantParticles = 1):
     NodePath.__init__(self, parent)
     self.assign(parent.attachNewNode('splash'))
     self.splashdown = globalPropPool.getProp('splashdown')
     self.splashdown.reparentTo(self)
     self.splashdown.setZ(-0.01)
     self.splashdown.setScale(0.4)
     ta = TransparencyAttrib.make(TransparencyAttrib.MBinary)
     self.splashdown.node().setAttrib(ta, 1)
     self.splashdown.setBin('fixed', 130, 1)
     self.ripples = Ripples(self)
     self.ripples.setBin('fixed', 120, 1)
     self.wantParticles = 1
     if self.wantParticles:
         self.pSystem = BattleParticles.createParticleEffect('SplashLines')
         self.pSystem.setScale(0.4)
         self.pSystem.setBin('fixed', 150, 1)
         self.particles = self.pSystem.particlesDict.get('particles-1')
     self.track = None
     self.trackId = Splash.splashCount
     Splash.splashCount += 1
     self.setBin('fixed', 100, 1)
     self.hide()
    def load(self):
        self.notify.debug('load')
        DistributedMinigame.load(self)
        self.timer = ToontownTimer.ToontownTimer()
        self.timer.posInTopRightCorner()
        self.timer.hide()
        self.room = loader.loadModel('phase_4/models/minigames/tug_of_war_dock')
        self.room.reparentTo(hidden)
        ropeModel = loader.loadModel('phase_4/models/minigames/tug_of_war_rope')
        self.ropeTexture = ropeModel.findTexture('*')
        ropeModel.removeNode()
        self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
        self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow')
        self.correctSound = base.loadSfx('phase_4/audio/sfx/MG_pos_buzzer.ogg')
        self.sndHitWater = base.loadSfx('phase_4/audio/sfx/MG_cannon_splash.ogg')
        self.whistleSound = base.loadSfx('phase_4/audio/sfx/AA_sound_whistle.ogg')
        self.music = base.loadMusic(self.bgm)
        self.roundText = DirectLabel(text='     ', text_fg=(0, 1, 0, 1), frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0.014, 0, -.84), scale=0.2)
        self.powerMeter = MinigamePowerMeter.MinigamePowerMeter(17)
        self.powerMeter.reparentTo(aspect2d)
        self.powerMeter.setPos(0, 0, 0.4)
        self.powerMeter.setPower(8)
        self.powerMeter.setTarget(8)
        self.arrows = [None] * 2
        for x in range(len(self.arrows)):
            self.arrows[x] = loader.loadModel('phase_3/models/props/arrow')
            self.arrows[x].reparentTo(self.powerMeter)
            self.arrows[x].hide()
            self.arrows[x].setScale(0.2 - 0.4 * x, 0.2, 0.2)
            self.arrows[x].setPos(0.12 - 0.24 * x, 0, -.26)
            self.disableArrow(self.arrows[x])

        self.splash = Splash.Splash(render)
        self.suitSplash = Splash.Splash(render)
        self.ripples = Ripples.Ripples(render)
        self.suitRipples = Ripples.Ripples(render)
        return
 def __loadStuff(self):
     if self.pole == None:
         self.pole = Actor.Actor()
         self.pole.loadModel('phase_4/models/props/fishing-pole-mod')
         self.pole.setBlend(
             frameBlend=config.GetBool('interpolate-animations', True))
         self.pole.loadAnims(
             {'cast': 'phase_4/models/props/fishing-pole-chan'})
         self.pole.pose('cast', 0)
         self.ptop = self.pole.find('**/joint_attachBill')
     if self.bob == None:
         self.bob = loader.loadModel('phase_4/models/props/fishing_bob')
         self.ripples = Ripples.Ripples(self.nodePath)
         self.ripples.hide()
     if self.splashSound == None:
         self.splashSound = base.loader.loadSfx(
             'phase_4/audio/sfx/TT_splash1.ogg')
     return
예제 #10
0
    def __init__(self, id, toNpcId=20001, fAutonomous=1):
        # Default NPC ID is Flippy
        Toon.Toon.__init__(self)
        self.id = id
        self.fAutonomous = fAutonomous
        npcInfo = NPCToons.NPCToonDict[toNpcId]
        dnaList = npcInfo[2]
        gender = npcInfo[3]
        dna = ToonDNA.ToonDNA()
        dna.newToonFromProperties(*dnaList)
        self.setDNA(dna)
        self.reparentTo(render)
        self.angleNP = self.find('**/actorGeom')
        # Create pole
        self.pole = Actor.Actor()
        self.pole.loadModel('phase_4/models/props/fishing-pole-mod')
        self.pole.loadAnims({'cast': 'phase_4/models/props/fishing-pole-chan'})
        # Get the top of the pole.
        self.ptop = self.pole.find('**/joint_attachBill')
        self.pole.pose('cast', 0)
        # Prepare Pole
        self.poleNode = []
        self.holdPole()
        self.createCastTrack()
        self.castIval = None
        # Prepare actor
        self.setupNeutralBlend()
        self.targetInterval = None
        # Start automatic casting or create cast button
        if self.fAutonomous:
            self.castButton = None
            self.targetButton = None
            self.startCasting()
        else:
            # Starts casting mode when mouse enters button region
            self.castButton = DirectButton(text='CAST',
                                           relief=None,
                                           scale=0.1,
                                           pos=(0, 0, -0.2))
            self.castButton.bind(DGG.ENTER, self.showCancelFrame)
            # A big screen encompassing frame to catch the button releases
            self.cancelFrame = DirectFrame(parent=self.castButton,
                                           frameSize=(-1, 1, -1, 1),
                                           relief=None,
                                           state='normal')
            # Make sure this is on top of all the other widgets
            self.cancelFrame.setBin('gui-popup', 0)
            self.cancelFrame.bind(DGG.B1PRESS, self.startAdjustingCastTask)
            self.cancelFrame.bind(DGG.B1RELEASE, self.finishCast)
            self.cancelFrame.hide()
            # Create bob
            self.bob = loader.loadModel('phase_4/models/props/fishing_bob')
            self.bobSpot = Point3(0)
            # Parameters to control bob motion
            self.vZeroMax = 30.0
            self.angleMax = 30.0
            # Ripple effect
            self.ripples = Ripples.Ripples(self.angleNP)
            self.ripples.hide()
            # Target
            self.buttonFrame = DirectFrame()
            self.target = base.distributedFishingTarget.fishingTargetNode

            self.fishPivot = self.attachNewNode('fishPivot')
            self.fish = loader.loadModel('models/misc/smiley')
            self.fish.reparentTo(self.fishPivot)
            self.fish.setScale(0.3, 1, 0.3)
            self.wiggleIval = None
            self.circleIval = None
            self.initFish()

            self.targetButton = DirectButton(parent=self.buttonFrame,
                                             text='MOVE',
                                             relief=DGG.RAISED,
                                             scale=0.1,
                                             pos=(0, 0, -0.9),
                                             command=self.moveTarget)
            self.targetTypeButton = DirectCheckButton(parent=self.buttonFrame,
                                                      text='MOVING',
                                                      relief=DGG.RAISED,
                                                      scale=0.085,
                                                      pos=(0.4, 0, -0.895),
                                                      command=self.setfMove)
            self.fMovingTarget = 0
            self.targetModeButton = DirectCheckButton(
                parent=self.buttonFrame,
                text='dTASK',
                relief=DGG.RAISED,
                scale=0.085,
                pos=(0.8, 0, -0.895),
                command=self.setfTargetMode)
            self.fTargetMode = 0
            # Vector line
            self.line = LineNodePath(render2d)
            self.line.setColor(VBase4(1, 0, 0, 1))
            self.line.moveTo(0, 0, 0)
            self.line.drawTo(1, 0, 0)
            self.line.create()
            self.moveTarget()
예제 #11
0
    def __init__(self, node):
        # To access fish in game:
        # fish = base.cr.playGame.hood.loader.animPropDict.values()[0]
        AnimatedProp.AnimatedProp.__init__(self, node)
        parent = node.getParent()
        self.fish = Actor.Actor(node, copy=0)
        self.fish.reparentTo(parent)

        # Move the transform from the original character node,
        # self.node, to the new Actor node, self.fish.
        self.fish.setTransform(node.getTransform())
        node.clearMat()

        self.fish.loadAnims({
            'jump': "phase_4/models/props/SZ_fish-jump",
            'swim': "phase_4/models/props/SZ_fish-swim"
        })

        self.splashSfxList = (
            loader.loadSfx("phase_4/audio/sfx/TT_splash1.mp3"),
            loader.loadSfx("phase_4/audio/sfx/TT_splash2.mp3"),
        )

        # Now forget about the old self.node; we're now the Actor.
        self.node = self.fish

        # Except that we still want a handle to the model node so we
        # can randomly position the fish around.
        self.geom = self.fish.getGeomNode()

        # Ripples to display when fish exits the water
        self.exitRipples = Ripples(self.geom)
        self.exitRipples.setBin('fixed', 25, 1)
        # Put it a little higher to help transparency sort order
        self.exitRipples.setPosHprScale(-0.3, 0.0, 1.24, 0.00, 0.00, 0.00, 0.7,
                                        0.7, 0.7)

        # Splash and ripples to display when fish re-enters the water
        self.splash = Splash(self.geom, wantParticles=0)
        self.splash.setPosHprScale(-1, 0.0, 1.23, 0.00, 0.00, 0.00, 0.7, 0.7,
                                   0.7)

        randomSplash = random.choice(self.splashSfxList)

        # Track to play back the whole think
        self.track = Sequence(
            FunctionInterval(self.randomizePosition),
            Func(self.node.unstash),
            Parallel(
                self.fish.actorInterval('jump'),
                # Ripples when exiting water
                Sequence(
                    Wait(0.25),
                    Func(self.exitRipples.play, 0.75),
                ),
                # Splash when re-entering water
                Sequence(
                    Wait(1.14),
                    Func(self.splash.play),
                    SoundInterval(randomSplash, volume=0.8, node=self.node),
                )),
            Wait(1),
            Func(self.node.stash),
            # Wait inbetween
            Wait(4 + 10 * random.random()),
            name=self.uniqueName("Fish"))
예제 #12
0
class FishAnimatedProp(AnimatedProp.AnimatedProp):
    def __init__(self, node):
        AnimatedProp.AnimatedProp.__init__(self, node)
        parent = node.getParent()
        self.fish = Actor.Actor(node, copy=0)
        self.fish.reparentTo(parent)
        self.fish.setTransform(node.getTransform())
        node.clearMat()
        self.fish.loadAnims({
            'jump': 'phase_4/models/props/SZ_fish-jump',
            'swim': 'phase_4/models/props/SZ_fish-swim'
        })
        self.splashSfxList = (
            loader.loadSfx('phase_4/audio/sfx/TT_splash1.mp3'),
            loader.loadSfx('phase_4/audio/sfx/TT_splash2.mp3'))
        self.node = self.fish
        self.geom = self.fish.getGeomNode()
        self.exitRipples = Ripples(self.geom)
        self.exitRipples.setBin('fixed', 25, 1)
        self.exitRipples.setPosHprScale(-0.29999999999999999, 0.0, 1.24, 0.0,
                                        0.0, 0.0, 0.69999999999999996,
                                        0.69999999999999996,
                                        0.69999999999999996)
        self.splash = Splash(self.geom, wantParticles=0)
        self.splash.setPosHprScale(-1, 0.0, 1.23, 0.0, 0.0, 0.0,
                                   0.69999999999999996, 0.69999999999999996,
                                   0.69999999999999996)
        randomSplash = random.choice(self.splashSfxList)
        self.track = Sequence(FunctionInterval(self.randomizePosition),
                              Func(self.node.unstash),
                              Parallel(
                                  self.fish.actorInterval('jump'),
                                  Sequence(Wait(0.25),
                                           Func(self.exitRipples.play, 0.75)),
                                  Sequence(
                                      Wait(1.1399999999999999),
                                      Func(self.splash.play),
                                      SoundInterval(randomSplash,
                                                    volume=0.80000000000000004,
                                                    node=self.node))),
                              Wait(1),
                              Func(self.node.stash),
                              Wait(4 + 10 * random.random()),
                              name=self.uniqueName('Fish'))

    def delete(self):
        self.exitRipples.destroy()
        del self.exitRipples
        self.splash.destroy()
        del self.splash
        del self.track
        self.fish.removeNode()
        del self.fish
        del self.node
        del self.geom

    def randomizePosition(self):
        x = 5 * (random.random() - 0.5)
        y = 5 * (random.random() - 0.5)
        h = 360 * random.random()
        self.geom.setPos(x, y, 0)
        self.geom.setHpr(h, 0, 0)

    def enter(self):
        AnimatedProp.AnimatedProp.enter(self)
        self.track.loop()

    def exit(self):
        AnimatedProp.AnimatedProp.exit(self)
        self.track.finish()
        self.splash.stop()
        self.exitRipples.stop()
class Splash(NodePath):
    splashCount = 0

    def __init__(self, parent=hidden, wantParticles=1):
        NodePath.__init__(self, parent)
        self.assign(parent.attachNewNode('splash'))
        self.splashdown = globalPropPool.getProp('splashdown')
        self.splashdown.reparentTo(self)
        self.splashdown.setZ(-0.01)
        self.splashdown.setScale(0.4)
        ta = TransparencyAttrib.make(TransparencyAttrib.MBinary)
        self.splashdown.node().setAttrib(ta, 1)
        self.splashdown.setBin('fixed', 130, 1)
        self.ripples = Ripples(self)
        self.ripples.setBin('fixed', 120, 1)
        self.wantParticles = 1
        if self.wantParticles:
            self.pSystem = BattleParticles.createParticleEffect('SplashLines')
            self.pSystem.setScale(0.4)
            self.pSystem.setBin('fixed', 150, 1)
            self.particles = self.pSystem.particlesDict.get('particles-1')

        self.track = None
        self.trackId = Splash.splashCount
        Splash.splashCount += 1
        self.setBin('fixed', 100, 1)
        self.hide()

    def createTrack(self, rate=1):
        self.ripples.createTrack(rate)
        self.splashdown.setPlayRate(rate, 'splashdown')
        animDuration = self.splashdown.getDuration('splashdown') * 0.65
        rippleSequence = Sequence(Func(self.splashdown.show),
                                  Func(self.splashdown.play, 'splashdown'),
                                  Wait(animDuration),
                                  Func(self.splashdown.hide))
        if self.wantParticles:
            particleSequence = Sequence(Func(self.pSystem.show),
                                        Func(self.particles.induceLabor),
                                        Func(self.pSystem.start, self),
                                        Wait(2.2), Func(self.pSystem.hide),
                                        Func(self.pSystem.disable))
        else:
            particleSequence = Sequence()

        self.track = Sequence(Func(self.show),
                              Parallel(self.ripples.track, rippleSequence,
                                       particleSequence),
                              Func(self.hide),
                              name='splashdown-%d-track' % self.trackId)

    def play(self, rate=1):
        self.stop()
        self.createTrack(rate)
        self.track.start()

    def loop(self, rate=1):
        self.stop()
        self.createTrack(rate)
        self.track.loop()

    def stop(self):
        if self.track:
            self.track.finish()

    def destroy(self):
        self.stop()
        del self.track
        self.ripples.destroy()
        del self.ripples
        if self.wantParticles:
            self.pSystem.cleanup()
            del self.pSystem
            del self.particles

        self.removeNode()