brillo-examples-2.0.0: picture/Occlusion/Main.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
import Brillo.Data.Extent
import Brillo.Data.QuadTree
import Brillo.Interface.Pure.Game
import Cell
import Data
import Data.Maybe
import State
import System.Environment
import World
main :: IO ()
main =
do
args <- getArgs
case args of
[fileName] ->
do
world <- loadWorld fileName
mainWithWorld world
_ -> do
let world = readWorld worldData
mainWithWorld world
mainWithWorld :: World -> IO ()
mainWithWorld world =
play
( InWindow
"Occlusion"
(windowSizeOfWorld world)
(10, 10)
)
black
10
(initState world)
drawState
(handleInput world)
(\_ -> id)
-- | Convert the state to a picture.
drawState :: State -> Picture
drawState state =
let world = stateWorld state
-- The ray cast by the user.
p1 = stateLineStart state
p2 = stateLineEnd state
picRay = drawRay world p1 p2
-- The cell hit by the ray (if any)
mHitCell = castSegIntoWorld world p1 p2
hitCells = maybeToList mHitCell
picCellsHit = Pictures $ map (drawHitCell world) hitCells
-- All the cells in the world.
cellsAll = flattenQuadTree (worldExtent world) (worldTree world)
picCellsAll = Pictures $ map (uncurry (drawCell False world)) cellsAll
-- The cells visible from the designated point.
cellsVisible =
[ (coord, cell)
| (coord, cell) <- flattenQuadTree (worldExtent world) (worldTree world)
, cellAtCoordIsVisibleFromPoint world p1 coord
]
picCellsVisible = Pictures $ map (uncurry (drawCell True world)) cellsVisible
-- How big to draw the cells.
scaleFactor = fromIntegral $ worldCellSize world
(windowSizeX, windowSizeY) =
windowSizeOfWorld $
stateWorld state
-- Shift the cells so they are centered in the window.
offsetX = -(fromIntegral $ windowSizeX `div` 2)
offsetY = -(fromIntegral $ windowSizeY `div` 2)
in Translate offsetX offsetY $
Scale scaleFactor scaleFactor $
Pictures [picCellsAll, picCellsVisible, picCellsHit, picRay]
-- | Draw the cell hit by the ray defined by the user.
drawHitCell :: World -> (Point, Extent, Cell) -> Picture
drawHitCell _ (_, extent, _) =
let (_, s, _, w) = takeExtent extent
x = w
y = s
posX = fromIntegral x
posY = fromIntegral y
in Pictures [Color blue $ cellShape 1 posX posY]
-- | Draw the ray defined by the user.
drawRay :: World -> Point -> Point -> Picture
drawRay _ p1@(x, y) p2 =
Pictures
[ Color red $ Line [p1, p2]
, Color cyan $
Translate x y $
Pictures
[ Line [(-0.3, -0.3), (0.3, 0.3)]
, Line [(-0.3, 0.3), (0.3, -0.3)]
]
]
-- | Draw a cell in the world.
drawCell :: Bool -> World -> Coord -> Cell -> Picture
drawCell visible world (x, y) cell =
let cs = fromIntegral (worldCellSize world)
-- cp = fromIntegral (worldCellSpace world)
posX = fromIntegral x
posY = fromIntegral y
in if visible
then pictureOfCell (worldCellSize world) posX posY cell
else Color (greyN 0.4) (cellShape cs posX posY)