edge-0.8.18: Projectile/SWForward.hs
module Projectile.SWForward ( SWForward(..)
, new
, prj
) where
import Combat ( Damageable(..), Damaging(..), Projectile(..) )
import Animation ( Animation(..) )
import Updating
( SimpleTransient(..), Transient(..), InternallyUpdating(..) )
import Graphics.Gloss.Data.Picture ( Picture(Circle, Color) )
import Graphics.Gloss.Data.Color ( violet )
import Data.WrapAround ( WP, WM, distance )
import qualified Moving as M
( Colliding(..), Moving(..), Locatable(..), newLocation )
import Common ( Velocity, Angle, Time )
import Math ( appPair, zeroOrLess )
import GHC.Float ( double2Float )
velocityC = 700
rangeC = 1000
integrityMax = 60
damE = 6
radiusGrowth = 30
data SWForward =
SWForward { velocity :: Velocity
, center :: WP
, rangeLeft :: Double
, wrapMap :: WM
, impacted :: Bool
, clock :: Time
, integrity :: Double
, radius :: Double
}
new a b c (d, e) =
SWForward { velocity = (x + d, y + e)
, center = c
, rangeLeft = rangeC
, wrapMap = a
, impacted = False
, clock = 0.0
, integrity = integrityMax
, radius = 2.0
}
where (x, y) = appPair ((* velocityC) . ($ b)) (cos, sin)
instance Animation SWForward where
image s t = Color violet (Circle (double2Float (radius s)))
instance M.Colliding SWForward where
collisionRadius = radius
instance M.Moving SWForward where
velocity = velocity
instance M.Locatable SWForward where
center = center
expirationFormula s = f rangeLeft || f integrity where f g = (zeroOrLess . g) s
instance SimpleTransient SWForward where
expired = expirationFormula
instance InternallyUpdating SWForward where
preUpdate s t = s { clock = clock s + t }
postUpdate s t = s { center = a, rangeLeft = r, radius = q }
where a = M.newLocation (wrapMap s) (center s) (velocity s) t
r = max 0 (rangeLeft s - distance (wrapMap s) (center s) a)
q = min 128.0 ((radius s) + radiusGrowth * t)
instance Damaging SWForward where
damageEnergy _ = damE
instance Transient SWForward where
expired' s = if expirationFormula s then Just [] else Nothing
instance Damageable SWForward where
inflictDamage s d = s { integrity = integrity s - d }
-- | Func abstracting construction of 'SWForward' projectile
prj :: (M.Moving a)
=> a -- ^ object receiving projectile
-> (a -> WM) -- ^ func which retrieves WM from object
-> Angle -- ^ firing angle
-> Projectile
prj a f b = Projectile (new (f a) b (M.center a) (M.velocity a))