reanimate-0.1.9.0: examples/shatter.hs
#!/usr/bin/env stack
-- stack runghc --package reanimate
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Chiphunk.Low
import Control.Monad
import Graphics.SvgTree (Tree)
import Linear.V2
import Reanimate
import Reanimate.Chiphunk
import Reanimate.PolyShape
import System.IO.Unsafe
test :: Animation
test = unsafePerformIO $ do
bodyStore <- newBodyStore
let gravity = Vect 0 (-1)
-- Create an empty space.
space <- spaceNew
spaceCollisionSlop space $= (screenWidth/2560)
spaceGravity space $= gravity
-- Add a static line segment shape for the ground.
-- We'll make it slightly tilted so the ball will roll off.
-- We attach it to a static body to tell Chipmunk it shouldn't be movable.
static <- get $ spaceStaticBody space
ground <- segmentShapeNew static
(Vect (-screenWidth/2) 0)
(Vect (screenWidth/2) (-screenHeight/2)) 0
-- ground <- polyShapeNewRaw static
-- [ Vect (-screenWidth/2) (screenHeight/2)
-- , Vect (screenWidth/2) (-screenHeight/2)
-- , Vect (-screenWidth/2) (-screenHeight/2)
-- , Vect (-screenWidth/2) (screenHeight/2) ] 0
shapeFriction ground $= 1
spaceAddShape space ground
-- Now let's make a ball that falls onto the line and rolls off.
-- First we need to make a cpBody to hold the physical properties of the object.
-- These include the mass, position, velocity, angle, etc. of the object.
-- Then we attach collision shapes to the Body to give it a size and shape.
let toVect (V2 x y) = Vect x y
let svg = center $ scale 2 $ latex "\\LaTeX"
poly = svgToPolyShapes svg
vectGroup = plDecompose poly
--mkCircle (Num radius)
-- vects = svgToVects svg
-- vects' = fst $ convexHull vects 0
-- svg' =
-- withFillOpacity 0 $ withStrokeColor "white" $
-- withStrokeWidth 0.01 $
-- renderPolyShapes (map plFromPolygon vectGroup)
--
-- ballBody <- polyShapesToBody space poly
-- bodyPosition ballBody $= Vect (-screenWidth/4) (screenHeight/2)
--
-- addToBodyStore bodyStore ballBody $
-- withFillColor "white" $
-- mkGroup
-- [ svg' ]
-- let splitPolys = vectGroup
forM_ vectGroup $ \polygon -> do
bd <- polygonsToBody space [map toVect polygon]
bodyPosition bd $= Vect 0 (screenHeight/3)
addToBodyStore bodyStore bd $
renderPolyShape $ plFromPolygon polygon
-- withFillColor "white" $
-- mkGroup
-- [ --withStrokeWidth (Num 0.005) $
-- -- withStrokeWidth (Num 0.00) $
-- -- withStrokeColor "white" $
-- -- withFillOpacity 1 $
-- renderPolyShape $ plFromPolygon polygon
-- ]
ani <- simulate space bodyStore 60 60 10
spaceFreeRecursive space
return ani
-- data LineCommand
-- = LineMove RPoint
-- -- | LineDraw RPoint
-- | LineBezier [RPoint]
-- | LineEnd
-- vectsToSVG :: [Vect] -> Tree
-- vectsToSVG (Vect x y:rest) =
-- mkPath $
-- MoveTo OriginAbsolute [V2 x y] :
-- [ LineTo OriginAbsolute [V2 a b] | Vect a b <- rest ] ++
-- [ EndPath ]
-- where
-- mkPath cmds = PathTree $ defaultSvg & pathDefinition .~ cmds
-- polygonsToSVG :: [[Vect]] -> Tree
-- polygonsToSVG = merge . mkGroup . map vectsToSVG
-- where
-- merge svg = PathTree $ defaultSvg & pathDefinition .~ extractPath svg
-- svgToVects :: Tree -> [Vect]
-- svgToVects svg = map worker (lineToPoints 200 cmds)
-- where
-- worker (V2 x y) = Vect x y
-- cmds = toLineCommands $ wibble $ extractPath svg
-- wibble xs = takeWhile (/=EndPath) xs ++ [EndPath]
chunkPolyshapes :: Tree -> Tree
chunkPolyshapes t =
withStrokeColor "white" $
withStrokeWidth 0.01 $
withFillColor "white" $ t
-- plArea :: PolyShape -> Double
-- plArea pl = areaForPoly (map toVect $ plPolygonify polyShapeTolerance pl) 0
-- where
-- toVect (Point x y) = Vect x y
reorient :: Tree -> Tree
reorient = id -- scale 4 . translate 0 (-0.9)
main :: IO ()
main = reanimate $ bg `parA` mapA reorient (line `parA` mapA chunkPolyshapes test)
where
bg = animate $ const $ mkBackground "black"
line = animate $ const $ withStrokeColor "white" $
withStrokeWidth 0.01 $
mkLine (-screenWidth/2, 0)
(screenWidth/2, -screenHeight/2)