83 lines
No EOL
3 KiB
Haskell
83 lines
No EOL
3 KiB
Haskell
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(..) )
|
|
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@Playing{} } = pausedGame
|
|
where pausedGame = g{ state = pausedState }
|
|
pausedState = Paused{ base = newBase, continue = playing }
|
|
newBase = StateBase { renderer = renderPaused, inputHandler = handleInputPaused }
|
|
pauseGame g = g
|
|
|
|
-- Move a player in a direction if possible.
|
|
movePlayer :: Direction -> Game -> Game
|
|
movePlayer dir g@Game{ state = s@Playing{ player = p@Player{ position = (x, y) }}} = newGame
|
|
where newGame = g{ state = newState }
|
|
newState = s{ player = newPlayer }
|
|
newPlayer = p{ position = newCoord }
|
|
newCoord | isLegalMove dir g = (x + xD, y + yD)
|
|
| otherwise = (x, y)
|
|
(xD, yD) = directionOffsets dir
|
|
movePlayer _ g = g
|
|
|
|
-- 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 |