{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE NoImplicitPrelude #-} module Imj.Graphics.Animation.Design.Create ( mkAnimation ) where import Imj.Prelude import Imj.Geo.Discrete import Imj.Graphics.Animation.Design.Types import Imj.Graphics.Animation.Design.Update import Imj.Graphics.Animation.Design.UpdateAnimatedPoints import Imj.Iteration import Imj.Timing -- | Creates an animation and initializes it by updating it once. mkAnimation :: Coords Pos -- ^ Center of the root 'AnimatedPoints'. -> [Coords Pos -> Frame -> [AnimatedPoint]] {- ^ List of /animation functions/. Every /animation function/ generates 'AnimatedPoint's for a given level of the root 'AnimatedPoints': The k-th /animation function/ generates 'AnimatedPoints' living in the (k+2)-th level, and takes the center of a (k+1)-th level 'AnimatedPoints' in its 'Coords' argument. /Animation functions/ are expected to return the same number of 'AnimatedPoint's at each iteration, or none after a given iteration to indicate that their animation is over. -} -> Speed -- ^ Animation discrete speed. Tells by how much the 'Frame', passed -- to animation functions, is incremented during an update. -> (Coords Pos -> InteractionResult) {- ^ The environmental interaction function. During update, 'AnimatedPoint's for which this function returns 'Mutation' can mutate if they are allowed to. During render, 'AnimatedPoint's for which this function returns 'Stable' are drawn. Others are not drawn because they would overlap with the environment. -} -> Either SystemTime KeyTime -- ^ 'Right' 'KeyTime' of the event's deadline -- that triggered this animation, or 'Left' 'SystemTime' -- of the current time if a player action triggered this animation -> Maybe Char {- ^ The default 'Char' to draw an 'AnimatedPoint' with, if an 'AnimatedPoint' of that 'Animation' doesn't specify one (i.e if one of the /animation functions/ passed as argument don't set the 'Char' of the 'AnimatedPoint' they generate). -} -> Maybe Animation -- ^ Depending on /animation functions/, the created 'Animation' may be over -- after the first update, hence 'Nothing' would be returned. mkAnimation center updates speed interaction t' mayChar = let update = updateAnimatedPoints updates t = either KeyTime id t' u = UpdateSpec t (zeroIteration speed) points = mkAnimatedPoints center in updateAnimation $ Animation points update interaction u mayChar -- | Constructs an 'AnimatedPoints'. mkAnimatedPoints :: Coords Pos -- ^ Where the first animation should start. -> AnimatedPoints mkAnimatedPoints center = AnimatedPoints Nothing center 0