module Main where import GameTypes import GameLogic import GameConfig import GameDraw import Draw import Control.Lens import Data.List import Data.Maybe import Linear.V2 import Control.Exception import System.IO import qualified Data.Map as M {- ncurses view -} main :: IO () main = play' opts 60 world renderWorld (\_ w -> w) handleEvent where world = newWorldWithBoss (V2 10 1) (V2 10 16) (defaultConfig^.worldSize) opts = defaultConfig^.ncursesOpts handleEvent :: Event -> World -> World handleEvent (EventCharacter c) w = fromMaybe w $ performAction w <$> getAction c handleEvent _ w = w {- Terminal view -} main' :: IO () main' = gameLoop $ newWorldWithBoss (V2 10 1) (V2 10 16) (20, 32) gameLoop :: World -> IO () gameLoop oldW = do putStrLn "" renderWorld' oldW putStrLn "Use 'w', 'a', 's', 'd' to navigate through the world. Press ' ' to attack, 'p' to pause." input <- getChar let newW = fromMaybe oldW $ performAction oldW <$> getAction input gameLoop newW renderWorld' :: World -> IO () renderWorld' world = do let graphics = map (map (renderEntity)) (layout $ M.toAscList $ world^.entities) layout = groupBy (\(u,_) (v,_) -> u^._y /= v^._y) mapM_ putStrLn graphics renderEntity :: (V2 Integer, Entity) -> Char renderEntity (p, Floor) = '-' renderEntity (p, (Hero s)) = 'H' renderEntity (p, (Boss s)) = 'M' renderEntity (p, (Wall)) = '#' renderEntity (p, (Bomb _)) = 'o' renderEntity (p, (Fire s)) | s^.life < 2 = 'x' | otherwise = 'X' renderEntity _ = '?' hide :: IO a -> IO a hide action = bracket_ (hSetEcho stdin False) (hSetEcho stdin True) action