2016-12-13 10:08:49 +00:00
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
|
2016-12-12 02:34:57 +00:00
|
|
|
-- | This module introduces a simple particle system to Affection
|
|
|
|
module Affection.Particle
|
2016-12-13 10:08:49 +00:00
|
|
|
( updateParticle
|
2016-12-12 02:34:57 +00:00
|
|
|
, drawParticles
|
2016-12-13 10:08:49 +00:00
|
|
|
, updateParticleSystem
|
2016-12-12 02:34:57 +00:00
|
|
|
) where
|
|
|
|
|
|
|
|
import Affection.Types
|
|
|
|
|
2016-12-23 13:18:39 +00:00
|
|
|
import Control.Monad
|
|
|
|
|
|
|
|
import Data.Maybe
|
2016-12-13 10:08:49 +00:00
|
|
|
|
|
|
|
import qualified GEGL as G
|
|
|
|
|
2016-12-12 02:34:57 +00:00
|
|
|
-- This function updates particles through a specified function. Particle ageing
|
|
|
|
-- and death is being handled by 'updateParticles' itself and does not need to
|
|
|
|
-- bother you.
|
2016-12-13 10:08:49 +00:00
|
|
|
updateParticle
|
2016-12-24 00:13:00 +00:00
|
|
|
:: Double
|
|
|
|
-- ^ Elapsed time in seconds
|
|
|
|
-> (Double -> Particle -> Affection us Particle)
|
|
|
|
-- ^ Update function for a single 'Particle'
|
|
|
|
-- This Function should take the elapsed time
|
|
|
|
-- in seconds and the initial particle as arguments.
|
|
|
|
-> Particle
|
|
|
|
-- ^ 'Particle' to be processed
|
|
|
|
-> Affection us (Maybe Particle)
|
|
|
|
-- ^ resulting 'Particle'
|
2016-12-23 13:18:39 +00:00
|
|
|
updateParticle time funct pa =
|
|
|
|
if particleLife pa - time < 0
|
|
|
|
then do
|
2016-12-24 00:13:00 +00:00
|
|
|
liftIO $ G.gegl_node_drop $ particleRootNode pa
|
2016-12-23 13:18:39 +00:00
|
|
|
return $ Nothing
|
2016-12-12 02:34:57 +00:00
|
|
|
else
|
2016-12-24 00:13:00 +00:00
|
|
|
Just <$> funct time pa { particleLife = particleLife pa - time }
|
2016-12-23 13:18:39 +00:00
|
|
|
-- updateParticle time funct acc@[p] pa =
|
|
|
|
-- if particleLife pa - time < 0
|
|
|
|
-- then do
|
|
|
|
-- G.gegl_node_drop $ particleRootNode pa
|
|
|
|
-- return $ Nothing : acc
|
|
|
|
-- else
|
|
|
|
-- return $ (Just $ funct time $ pa { particleLife = particleLife pa - time }) : acc
|
|
|
|
-- updateParticle time funct acc@(p:ps) pa =
|
|
|
|
-- if particleLife pa - time < 0
|
|
|
|
-- then do
|
|
|
|
-- G.gegl_node_drop $ particleRootNode pa
|
|
|
|
-- return $ Nothing : acc
|
|
|
|
-- else
|
|
|
|
-- return $ (Just $ funct time $ pa { particleLife = particleLife pa - time }) : acc
|
2016-12-12 02:34:57 +00:00
|
|
|
|
|
|
|
drawParticles
|
|
|
|
:: (Particle -> Affection us ())
|
|
|
|
-> [Particle]
|
|
|
|
-> Affection us ()
|
|
|
|
drawParticles = mapM_
|
2016-12-13 10:08:49 +00:00
|
|
|
|
|
|
|
updateParticleSystem
|
|
|
|
:: ParticleSystem
|
|
|
|
-> Double
|
2016-12-24 00:13:00 +00:00
|
|
|
-> (Double -> Particle -> Affection us Particle)
|
2016-12-13 10:08:49 +00:00
|
|
|
-> (G.GeglBuffer -> G.GeglNode -> Particle -> Affection us ())
|
|
|
|
-> Affection us ParticleSystem
|
|
|
|
updateParticleSystem sys sec upd draw = do
|
2016-12-23 13:18:39 +00:00
|
|
|
-- let x = catMaybes <$> mapM (updateParticle sec upd) (psParts sys)
|
|
|
|
-- x <- liftIO $ catMaybes <$> foldM (updateParticle sec upd) [] (psParts sys)
|
2016-12-24 00:13:00 +00:00
|
|
|
x <- catMaybes <$> mapM (updateParticle sec upd) (psParts sys)
|
2016-12-23 13:18:39 +00:00
|
|
|
liftIO $ G.gegl_node_link_many $ map particleStackCont x ++ [psNode sys]
|
2016-12-13 10:08:49 +00:00
|
|
|
mapM_ (draw (psBuffer sys) (psNode sys)) x
|
|
|
|
return $ sys
|
|
|
|
{ psParts = x }
|