module MiniLight.Component.AnimationLayer where import Control.Monad.State import Data.Aeson import Linear import Lens.Micro import MiniLight.Figure import MiniLight.Light import qualified MiniLight.Component.Layer as Layer import MiniLight.Component.Types import qualified SDL import qualified SDL.Vect as Vect data AnimationLayer = AnimationLayer { layer :: Layer.Layer, counter :: Int, tileSize :: Vect.V2 Int, scaler :: 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) * scaler c then 0 else counter c } figures comp = do let iv = V2 ((counter comp `div` scaler comp) `mod` division (config comp) ^. _x) ((counter comp `div` scaler 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 } instance FromJSON Config where parseJSON = withObject "config" $ \v -> do conf <- parseJSON (Object v) division <- (\v -> Vect.V2 <$> v .: "x" <*> v .: "y") =<< v .: "division" return $ Config conf division 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 , scaler = 25 , config = conf }