packages feed

edge-0.8.16: AfterEffect/SimpleExplosion.hs

module AfterEffect.SimpleExplosion where

import Data.WrapAround
import Animation
import Updating
import qualified Moving as M
import Graphics.Gloss.Data.Picture
import Graphics.Gloss.Data.Color
import Sound.ALUT
import Data.Maybe
import ResourceTracker
import GHC.Float
import Common

data SimpleExplosion =
  SimpleExplosion { center :: WrapPoint
                  , timeRemaining :: Time
                  , soundSource :: Maybe Source
                  , wrapMap :: WrapMap
                  , resourceTracker :: ResourceTracker
                  , animClock :: Time
                  , velocity :: Velocity
                  }

new :: ResourceTracker -> WrapMap -> WrapPoint -> Velocity -> SimpleExplosion
new rt wmap center' velocity' =
  SimpleExplosion { center = center'
                  , timeRemaining = 3.0
                  , soundSource = Nothing
                  , wrapMap = wmap
                  , resourceTracker = rt
                  , animClock = 0.0
                  , velocity = velocity'
                  }

instance Animation SimpleExplosion where
  image self t =
    let dFrame = Color white (Scale 0.10 0.10 (Text "boom!")) in
    let rt = resourceTracker self in
    let f00 = fromMaybe dFrame $ getImage rt "explosion-00.bmp" in 
    let f01 = fromMaybe dFrame $ getImage rt "explosion-01.bmp" in 
    let f02 = fromMaybe dFrame $ getImage rt "explosion-02.bmp" in 
    let f03 = fromMaybe dFrame $ getImage rt "explosion-03.bmp" in 
    let f04 = fromMaybe dFrame $ getImage rt "explosion-04.bmp" in 
    let f05 = fromMaybe dFrame $ getImage rt "explosion-05.bmp" in 
    let f06 = fromMaybe dFrame $ getImage rt "explosion-06.bmp" in
    let at = animClock self in
    let fspace = 0.07 in
    if at < fspace * 1 then f00
    else if at < fspace * 2 then f01
    else if at < fspace * 3 then f02
    else if at < fspace * 4 then f03
    else if at < fspace * 5 then f04
    else if at < fspace * 6 then f05
    else if at < fspace * 7 then f06
    else Blank

instance M.Locatable SimpleExplosion where
  center = center

instance Transient SimpleExplosion where

  expired' self = if timeRemaining self <= 0.0
                    then Just []
                    else Nothing

instance InternallyUpdating SimpleExplosion where

  preUpdate self t = self { timeRemaining = timeRemaining self - t
                          , center = M.newLocation (wrapMap self)
                                                        (center self)
                                                        (velocity self)
                                                        t
                          }

  postUpdate self t = self { animClock = animClock self + t }

instance Audible SimpleExplosion where

  processAudio self lcenter =
    if isNothing (soundSource self)
      then do self' <- initializeSoundSource self
              let (x, y) = vectorRelation
                                      (wrapMap self')
                                      (lcenter)
                                      (center self')
              let s = fromJust $ soundSource self'
              sourcePosition s $= (Vertex3 (double2Float x)
                                           (double2Float (-y))
                                           0)
              play [s]
              return self'
      else return self

  terminateAudio self =
    if isNothing (soundSource self)
      then return self
      else do stop [fromJust (soundSource self)]
              return self

initializeSoundSource self =
  do [source] <- genObjectNames 1
     buffer source $= getSound (resourceTracker self) "explosion.wav"
     sourceRelative source $= Listener
     referenceDistance source $= audioReferenceDistance
     rolloffFactor source $= audioRolloffFactor
     sourceGain source $= 0.5
     return self { soundSource = Just source }