module RPGEngine.Input.Playing ( handleInputPlaying , spawnPlayer ) where import RPGEngine.Input.Core ( composeInputHandlers, handleKey, InputHandler ) import RPGEngine.Data ( Player(Player, position), Direction(West, North, East, South), Physical(Entrance), Y, X, Level(Level, layout), State(..), StateBase(StateBase, renderer, inputHandler), Game(Game, state, player) ) import RPGEngine.Data.Level ( findFirstOf, directionOffsets ) import RPGEngine.Data.Game ( isLegalMove ) import RPGEngine.Input.Paused ( handleInputPaused ) import RPGEngine.Render.Paused ( renderPaused ) import Graphics.Gloss.Interface.IO.Game (Key(..)) import Graphics.Gloss.Interface.IO.Interact (SpecialKey(..)) import Data.Maybe (isNothing, fromJust) ------------------------------ Exported ------------------------------ handleInputPlaying :: InputHandler Game handleInputPlaying = composeInputHandlers [ -- Pause the game handleKey (Char 'p') pauseGame, -- Player movement handleKey (SpecialKey KeyUp) $ movePlayer North, handleKey (SpecialKey KeyRight) $ movePlayer East, handleKey (SpecialKey KeyDown) $ movePlayer South, handleKey (SpecialKey KeyLeft) $ movePlayer West, handleKey (Char 'w') $ movePlayer North, handleKey (Char 'd') $ movePlayer East, handleKey (Char 's') $ movePlayer South, handleKey (Char 'a') $ movePlayer West ] -- Set the initial position of the player in a given level. spawnPlayer :: Level -> Player -> Player spawnPlayer l@Level{ layout = lay } p@Player{ position = prevPos } = p{ position = newPos } where try = findFirstOf l Entrance newPos | isNothing try = prevPos | otherwise = fromJust try ---------------------------------------------------------------------- pauseGame :: Game -> Game pauseGame g@Game{ state = Playing{ level = level } } = pausedGame where pausedGame = g{ state = pausedState } pausedState = Paused{ base = newBase, level = level } newBase = StateBase { renderer = renderPaused, inputHandler = handleInputPaused } -- Move a player in a direction if possible. movePlayer :: Direction -> Game -> Game movePlayer dir g@Game{ player = p@Player{ position = (x, y) }} = newGame where newGame = g{ player = newPlayer } newPlayer = p{ position = newCoord } newCoord | isLegalMove dir g = (x + xD, y + yD) | otherwise = (x, y) (xD, yD) = directionOffsets dir -- TODO goToNextLevel :: Game -> Game goToNextLevel = undefined ---------------------------------------------------------------------- -- Map all Physicals onto coordinates putCoords :: Level -> [(X, Y, Physical)] putCoords l@Level{ layout = lay } = concatMap (\(a, bs) -> map (\(b, c) -> (b, a, c)) bs) numberedList where numberedStrips = zip [0::Int .. ] lay numberedList = map (\(x, strip) -> (x, zip [0::Int ..] strip)) numberedStrips