module Data.Component.AnimationLayer where import Control.Lens import Control.Monad.State import Data.Aeson import Linear import MiniLight import qualified Data.Component.Layer as Layer import qualified SDL import qualified SDL.Vect as Vect data AnimationLayer = AnimationLayer { layer :: Layer.Layer, counter :: Int, tileSize :: Vect.V2 Int, config :: Config } instance ComponentUnit AnimationLayer where update = execStateT $ do modify $ \c -> c { counter = (counter c + 1) } modify $ \c -> c { counter = if counter c >= (division (config c) ^._x * division (config c) ^. _y) * interval (config c) then 0 else counter c } figures comp = do let iv = V2 ((counter comp `div` interval (config comp)) `mod` division (config comp) ^. _x) ((counter comp `div` interval (config comp)) `div` division (config comp) ^. _x) return [ clip (SDL.Rectangle (SDL.P (tileSize comp * iv)) (tileSize comp)) $ Layer.layer $ layer comp ] data Config = Config { layerConf :: Layer.Config, division :: Vect.V2 Int, interval :: Int } instance FromJSON Config where parseJSON = withObject "config" $ \v -> do conf <- parseJSON (Object v) division <- (\v -> Vect.V2 <$> v .: "x" <*> v .: "y") =<< v .: "division" interval <- v .:? "interval" .!= 30 return $ Config conf division interval new :: Config -> MiniLight AnimationLayer new conf = do layer <- Layer.new (layerConf conf) let size = getFigureSize (Layer.layer layer) return $ AnimationLayer { layer = layer , counter = 0 , tileSize = div <$> size <*> division conf , config = conf }