module Types where
import Data.Monoid
import IxMap
import Data.IORef
import qualified Physics.Hipmunk as H
type Time = Double
-- actions
data GameState = On | WaitForClick Int
data Query
= Remove Ball
| HeroVelocity H.Velocity | MakeBall Freq
| GameOver | Step
-- senses
data Event = Touch Ball | UserClick H.Position
data Sense = Sense
{ senseHero :: HeroBall
, senseBalls :: [Ball] }
-- graphics
data Picture = EmptyPicture
| Prim Color Primitive
| Join Picture Picture
foldPicture :: a -> (Color -> Primitive -> a) -> (a -> a -> a)
-> Picture -> a
foldPicture emptyPic primPic joinPic p = case p of
EmptyPicture -> emptyPic
Prim col a -> primPic col a
Join a b -> joinPic (f a) (f b)
where f = foldPicture emptyPic primPic joinPic
instance Monoid Picture where
mempty = EmptyPicture
mappend = Join
data Primitive = Line Point Point
| Circle Point Radius
| Rect Point Point
| CircleSolid Point Radius
| RectSolid Point Point
| Text Point String
data Point = Point Double Double
type Radius = Double
data Color = Color Double Double Double
------------------------------------------------------
data World = World
{ worldPure :: Pure
, worldDirty :: Dirty }
-- pure
data Pure = Pure
{ pureScores :: Scores
, pureHero :: HeroBall
, pureBalls :: [Ball]
, pureCreation :: Creation
, pureTouch :: Maybe (Int, [Ball])
, pureGameState :: GameState
}
data HeroBall = HeroBall
{ heroPos :: H.Position
, heroVel :: H.CpFloat
}
data Ball = Ball
{ ballType :: BallType
, ballPos :: H.Position
, ballId :: Id
}
data BallType = Hero | Good | Bad | Bonus
deriving (Show, Eq, Enum)
type Id = Int
data Scores = Scores
{ scoresLevel :: Int
, scoresLives :: Int
, scoresBonus :: Int
} deriving (Show)
data Creation = Creation
{ creationStat :: Stat
, creationGoalStat :: Stat
, creationTick :: Int
}
data Stat = Stat
{ goodCount :: Int
, badCount :: Int
, bonusCount :: Int
} deriving (Eq, Show, Read)
data Freq = Freq
{ freqGood :: Float
, freqBad :: Float
, freqBonus :: Float
}
-- dirty
data Dirty = Dirty
{ dirtyHero :: Obj
, dirtyObjs :: IxMap Obj
, dirtySpace :: H.Space
, dirtyTouchVar :: Sensor H.Shape
, dirtyMouse :: Sensor H.Position
}
data Obj = Obj
{ objType :: BallType
, objShape :: H.Shape
, objBody :: H.Body
} deriving (Eq)
type Sensor a = IORef (Maybe a)
foldQuery :: (Ball -> a) -> (H.Velocity -> a) -> (Freq -> a)
-> a -> a
-> Query -> a
foldQuery rm hv mb go step q = case q of
Remove ball -> rm ball
HeroVelocity vel -> hv vel
MakeBall freq -> mb freq
GameOver -> go
Step -> step
foldEvent :: (Ball -> a) -> (H.Position -> a)
-> (Event -> a)
foldEvent touch click a = case a of
Touch ball -> touch ball
UserClick p -> click p