edge-0.8: Projectile/Blade.hs
module Projectile.Blade ( Blade(..)
, new
, range
, speed
) where
import Combat
import Animation
import Updating
import Graphics.Gloss.Data.Picture
import Graphics.Gloss.Data.Color
import Data.WrapAround
import qualified Moving as M
import Trigonometry
import Data.Maybe
import ResourceTracker
import GHC.Float
velocityC = 250.0
rangeC = 1500.0
punch = 4.0
range = rangeC
speed = velocityC
data Blade =
Blade { velocity :: (Double, Double)
, center :: WrapPoint
, rangeLeft :: Double
, wrapMap :: WrapMap
, idealNewCenter :: Maybe WrapPoint
, clock :: Double
, resourceTracker :: ResourceTracker
}
-- angle is radians
new :: WrapMap -> ResourceTracker -> Double -> WrapPoint -> (Double, Double) -> Blade
new wmap rt angle center' (vpx, vpy) =
let x = cos angle * velocityC in
let y = sin angle * velocityC in
Blade { velocity = (x + vpx, y + vpy)
, center = center'
, rangeLeft = rangeC
, wrapMap = wmap
, idealNewCenter = Nothing
, clock = 0.0
, resourceTracker = rt
}
instance Animation Blade where
image self t = Rotate (double2Float deg) p
where deg = radToDeg ((clock self * 4 * pi) `doubleRem` (2 * pi))
p = fromMaybe
(Color white
(Line [(-40, 0), (40, 0)]))
(getImage rt "blade.bmp")
rt = resourceTracker self
instance M.Colliding Blade where
collisionRadius self = 20.0
instance M.Moving Blade where
velocity self = Projectile.Blade.velocity self
instance M.Locatable Blade where
center self = Projectile.Blade.center self
instance SimpleTransient Blade where
expired self = rangeLeft self <= 0.0
instance InternallyUpdating Blade where
preUpdate self t = updateIdealTargetCenter t self
postUpdate self t =
let center' = case idealNewCenter self of
Nothing -> center self
Just x -> x in
self { center = center'
, idealNewCenter = Nothing
, clock = clock self + t
}
updateIdealTargetCenter :: Double -> Blade -> Blade
updateIdealTargetCenter t self =
let newLoc = M.idealNewLocation (wrapMap self)
(center self)
(velocity self)
t in
self { idealNewCenter = Just (newLoc)
, rangeLeft = max 0.0 $ rangeLeft self
- Data.WrapAround.distance (wrapMap self)
(center self)
(newLoc)
}
instance Damaging Blade where
damageEnergy b = punch
instance Transient Blade where
expired' self = if rangeLeft self <= 0.0
then Just []
else Nothing
instance Damageable Blade where
inflictDamage self d = self