Fix dependency loop
This commit is contained in:
		
							parent
							
								
									b7278d6afc
								
							
						
					
					
						commit
						f529fc5237
					
				
					 25 changed files with 251 additions and 199 deletions
				
			
		
							
								
								
									
										10
									
								
								lib/Input.hs
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								lib/Input.hs
									
										
									
									
									
								
							|  | @ -1,10 +0,0 @@ | ||||||
| -- Go to the next stage of the Game |  | ||||||
| -- setNextState :: Game -> Game |  | ||||||
| -- setNextState game = game{ state = newState } |  | ||||||
| --     where newState = nextState $ state game |  | ||||||
| 
 |  | ||||||
| -- -- Get the next state based on the current state |  | ||||||
| -- nextState :: State -> State |  | ||||||
| -- nextState Menu {} = defaultLvlSelect |  | ||||||
| -- nextState Pause {} = Playing |  | ||||||
| -- nextState _ = Menu |  | ||||||
|  | @ -6,8 +6,11 @@ module RPGEngine | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Config ( bgColor, winDimensions, winOffsets ) | import RPGEngine.Config ( bgColor, winDimensions, winOffsets ) | ||||||
| import RPGEngine.Render ( initWindow, render, initGame ) | import RPGEngine.Render ( initWindow, render ) | ||||||
| import RPGEngine.Input ( handleAllInput ) | import RPGEngine.Input ( handleAllInput ) | ||||||
|  | import RPGEngine.Input.Playing ( checkPlaying, spawnPlayer ) | ||||||
|  | import RPGEngine.Data (Game (..), State (..), Layout, Level (..), Physical (..)) | ||||||
|  | import RPGEngine.Data.Default (defaultLevel, defaultPlayer) | ||||||
| 
 | 
 | ||||||
| import Graphics.Gloss ( play ) | import Graphics.Gloss ( play ) | ||||||
| 
 | 
 | ||||||
|  | @ -19,4 +22,59 @@ playRPGEngine :: String -> Int -> IO() | ||||||
| playRPGEngine title fps = do | playRPGEngine title fps = do | ||||||
|     play window bgColor fps initGame render handleAllInput step |     play window bgColor fps initGame render handleAllInput step | ||||||
|     where window       = initWindow title winDimensions winOffsets |     where window       = initWindow title winDimensions winOffsets | ||||||
|           step _ g     = g -- TODO Do something with step? Check health etc. |           step _       = checkPlaying -- TODO Do something with step? Check health etc. | ||||||
|  | 
 | ||||||
|  | -- TODO revert this | ||||||
|  | -- Initialize the game | ||||||
|  | initGame :: Game | ||||||
|  | -- initGame = Game {  | ||||||
|  | --     state   = Menu{ base = StateBase{  | ||||||
|  | --         renderer = renderMenu,  | ||||||
|  | --         inputHandler = handleInputMenu | ||||||
|  | --     }} | ||||||
|  | -- } | ||||||
|  | initGame = Game{ | ||||||
|  |     state = initState | ||||||
|  | } | ||||||
|  |     where initState = Playing{ | ||||||
|  |         levels = [defaultLevel, otherLevel], | ||||||
|  |         count = 0, | ||||||
|  |         level  = defaultLevel, | ||||||
|  |         player = spawnPlayer defaultLevel defaultPlayer, | ||||||
|  |         restart = initState | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | -- TODO remove this | ||||||
|  | otherLayout :: Layout | ||||||
|  | otherLayout = [ | ||||||
|  |     [Blocked, Blocked, Blocked], | ||||||
|  |     [Blocked, Entrance, Blocked], | ||||||
|  |     [Blocked, Walkable, Blocked], | ||||||
|  |     [Blocked, Exit, Blocked], | ||||||
|  |     [Blocked, Blocked, Blocked] | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  | -- TODO remove this | ||||||
|  | otherLevel :: Level | ||||||
|  | otherLevel = Level { | ||||||
|  |     layout   = otherLayout, | ||||||
|  |     index    = [ | ||||||
|  |         (0, 0, Blocked), | ||||||
|  |         (1, 0, Blocked), | ||||||
|  |         (2, 0, Blocked), | ||||||
|  |         (0, 1, Blocked), | ||||||
|  |         (1, 1, Entrance), | ||||||
|  |         (2, 1, Blocked), | ||||||
|  |         (0, 2, Blocked), | ||||||
|  |         (1, 2, Walkable), | ||||||
|  |         (2, 2, Blocked), | ||||||
|  |         (0, 3, Blocked), | ||||||
|  |         (1, 3, Exit), | ||||||
|  |         (2, 3, Blocked), | ||||||
|  |         (0, 4, Blocked), | ||||||
|  |         (1, 4, Blocked), | ||||||
|  |         (2, 4, Blocked) | ||||||
|  |     ], | ||||||
|  |     items    = [], | ||||||
|  |     entities = [] | ||||||
|  | } | ||||||
|  | @ -16,32 +16,23 @@ data Game = Game { | ||||||
| 
 | 
 | ||||||
| ------------------------------- State -------------------------------- | ------------------------------- State -------------------------------- | ||||||
| 
 | 
 | ||||||
| -- Code reusability |  | ||||||
| data StateBase = StateBase { |  | ||||||
|     renderer     :: Renderer State, |  | ||||||
|     inputHandler :: InputHandler Game |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
|            -- Main menu |            -- Main menu | ||||||
| data State = Menu           { base      :: StateBase    } | data State = Menu | ||||||
|            -- Select the level you want to play |            -- Select the level you want to play | ||||||
|            | LevelSelection { base      :: StateBase, |            | LevelSelection { levelList :: [FilePath], | ||||||
|                               levelList :: [FilePath], |  | ||||||
|                               selector  :: ListSelector } |                               selector  :: ListSelector } | ||||||
|            -- Playing a level |            -- Playing a level | ||||||
|            | Playing        { base      :: StateBase, |            | Playing        { levels    :: [Level], | ||||||
|                               levels    :: [Level], |                               count     :: Int, | ||||||
|                               level     :: Level, |                               level     :: Level, | ||||||
|                               player    :: Player, |                               player    :: Player, | ||||||
|                               restart   :: State        } |                               restart   :: State        } | ||||||
|            -- Paused while playing a level |            -- Paused while playing a level | ||||||
|            | Paused         { base      :: StateBase,  |            | Paused         { continue  :: State        } | ||||||
|                               continue  :: State        } |  | ||||||
|            -- Won a level |            -- Won a level | ||||||
|            | Win            { base      :: StateBase    } |            | Win | ||||||
|            -- Lost a level |            -- Lost a level | ||||||
|            | Lose           { base      :: StateBase, |            | Lose           { restart   :: State        } | ||||||
|                               restart   :: State        } |  | ||||||
| 
 | 
 | ||||||
| ------------------------------- Level -------------------------------- | ------------------------------- Level -------------------------------- | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,11 +1,8 @@ | ||||||
| module RPGEngine.Data.Default | module RPGEngine.Data.Default | ||||||
| -- Everything is exported | -- Everything is exported | ||||||
| where | where | ||||||
| import RPGEngine.Data (Entity (..), Game (..), Item (..), Layout, Player (..), Level (..), StateBase (..), State (..), Physical (..), Direction (..)) | import RPGEngine.Data (Entity (..), Game (..), Item (..), Layout, Player (..), Level (..), State (..), Physical (..), Direction (..)) | ||||||
| import RPGEngine.Input.Core (ListSelector(..)) | import RPGEngine.Input.Core (ListSelector(..)) | ||||||
| import RPGEngine.Render.LevelSelection (renderLevelSelection) |  | ||||||
| import RPGEngine.Input.Playing (spawnPlayer) |  | ||||||
| import RPGEngine.Render.Menu (renderMenu) |  | ||||||
| 
 | 
 | ||||||
| ------------------------------ Defaults ------------------------------ | ------------------------------ Defaults ------------------------------ | ||||||
| 
 | 
 | ||||||
|  | @ -36,9 +33,9 @@ defaultItem = Item { | ||||||
| 
 | 
 | ||||||
| defaultLayout :: Layout | defaultLayout :: Layout | ||||||
| defaultLayout = [ | defaultLayout = [ | ||||||
|     [Blocked, Blocked, Blocked], |     [Blocked, Blocked, Blocked, Blocked, Blocked], | ||||||
|     [Blocked, Entrance, Blocked], |     [Blocked, Entrance, Walkable, Exit, Blocked], | ||||||
|     [Blocked, Blocked, Blocked] |     [Blocked, Blocked, Blocked, Blocked, Blocked] | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
| defaultLevel :: Level | defaultLevel :: Level | ||||||
|  | @ -52,8 +49,14 @@ defaultLevel = Level { | ||||||
|         (1, 1, Entrance), |         (1, 1, Entrance), | ||||||
|         (1, 2, Blocked), |         (1, 2, Blocked), | ||||||
|         (2, 0, Blocked), |         (2, 0, Blocked), | ||||||
|         (2, 1, Blocked), |         (2, 1, Walkable), | ||||||
|         (2, 2, Blocked) |         (2, 2, Blocked), | ||||||
|  |         (3, 0, Blocked), | ||||||
|  |         (3, 1, Exit), | ||||||
|  |         (3, 2, Blocked), | ||||||
|  |         (4, 0, Blocked), | ||||||
|  |         (4, 1, Blocked), | ||||||
|  |         (4, 2, Blocked) | ||||||
|     ], |     ], | ||||||
|     items    = [], |     items    = [], | ||||||
|     entities = [] |     entities = [] | ||||||
|  | @ -65,3 +68,9 @@ defaultPlayer = Player { | ||||||
|     inventory = [], |     inventory = [], | ||||||
|     position  = (0, 0) |     position  = (0, 0) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | defaultSelector :: ListSelector | ||||||
|  | defaultSelector = ListSelector { | ||||||
|  |     selection = 0, | ||||||
|  |     selected = False | ||||||
|  | } | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| module RPGEngine.Data.Game | module RPGEngine.Data.Game | ||||||
| ( isLegalMove | ( isLegalMove | ||||||
|  | , isPlayerAtExit | ||||||
|  | , isPlayerDead | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data | import RPGEngine.Data | ||||||
|  | @ -20,3 +22,15 @@ isLegalMove dir g@Game{ state = Playing { level = lvl, player = p@Player{ positi | ||||||
|           newPos   = (x + xD, y + yD) |           newPos   = (x + xD, y + yD) | ||||||
|           (xD, yD) = directionOffsets dir |           (xD, yD) = directionOffsets dir | ||||||
| isLegalMove _   _ = False | isLegalMove _   _ = False | ||||||
|  | 
 | ||||||
|  | -- Check if a player is standing on an exit | ||||||
|  | isPlayerAtExit :: Game -> Bool | ||||||
|  | isPlayerAtExit g@Game{ state = Playing{ player = player, level = level }} = atExit | ||||||
|  |     where playerPos = position player | ||||||
|  |           atPos     = findAt playerPos level | ||||||
|  |           atExit    = atPos == Exit | ||||||
|  | isPlayerAtExit _ = False | ||||||
|  | 
 | ||||||
|  | -- Check if the players health is <= 0, which means the player is dead. | ||||||
|  | isPlayerDead :: Game -> Bool | ||||||
|  | isPlayerDead _ = False | ||||||
|  | @ -5,7 +5,7 @@ where | ||||||
| import GHC.IO (unsafePerformIO) | import GHC.IO (unsafePerformIO) | ||||||
| import System.Directory (getDirectoryContents) | import System.Directory (getDirectoryContents) | ||||||
| import RPGEngine.Input.Core (ListSelector(..)) | import RPGEngine.Input.Core (ListSelector(..)) | ||||||
| import RPGEngine.Data (Level (..), Physical (..), Direction (..), Entity (..), Game (..), Item (..), Player (..), StateBase (..), State (..), X, Y, Layout) | import RPGEngine.Data (Level (..), Physical (..), Direction (..), Entity (..), Game (..), Item (..), Player (..), State (..), X, Y, Layout) | ||||||
| import RPGEngine.Config (levelFolder) | import RPGEngine.Config (levelFolder) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
|  |  | ||||||
|  | @ -4,12 +4,23 @@ module RPGEngine.Input | ||||||
| ( handleAllInput | ( handleAllInput | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Input.Core | import RPGEngine.Input.Core ( InputHandler, composeInputHandlers, handleAnyKey ) | ||||||
| import RPGEngine.Data | 
 | ||||||
|  | import RPGEngine.Data ( Game(..), State(..) ) | ||||||
|  | import RPGEngine.Input.Menu ( handleInputMenu ) | ||||||
|  | import RPGEngine.Input.LevelSelection (handleInputLevelSelection) | ||||||
|  | import RPGEngine.Input.Playing ( handleInputPlaying ) | ||||||
|  | import RPGEngine.Input.Paused ( handleInputPaused ) | ||||||
|  | import RPGEngine.Input.Win ( handleInputWin ) | ||||||
|  | import RPGEngine.Input.Lose ( handleInputLose ) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| -- Handle all input of all states of the game. | -- Handle all input of all states of the game. | ||||||
| handleAllInput :: InputHandler Game | handleAllInput :: InputHandler Game | ||||||
| handleAllInput ev g@Game{ state = state } = handleInput ev g | handleAllInput ev g@Game{ state = Menu             } = handleInputMenu ev g | ||||||
|     where handleInput = inputHandler $ base state | handleAllInput ev g@Game{ state = LevelSelection{} } = handleInputLevelSelection ev g | ||||||
|  | handleAllInput ev g@Game{ state = Playing{}        } = handleInputPlaying ev g | ||||||
|  | handleAllInput ev g@Game{ state = Paused{}         } = handleInputPaused ev g | ||||||
|  | handleAllInput ev g@Game{ state = Win              } = handleInputWin ev g | ||||||
|  | handleAllInput ev g@Game{ state = Lose{}           } = handleInputLose ev g | ||||||
|  | @ -6,6 +6,8 @@ module RPGEngine.Input.Core | ||||||
| , handle | , handle | ||||||
| , handleKey | , handleKey | ||||||
| , handleAnyKey | , handleAnyKey | ||||||
|  | 
 | ||||||
|  | , SpecialKey(..) | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import Graphics.Gloss.Interface.Pure.Game | import Graphics.Gloss.Interface.Pure.Game | ||||||
|  |  | ||||||
|  | @ -2,17 +2,12 @@ module RPGEngine.Input.LevelSelection | ||||||
| ( handleInputLevelSelection | ( handleInputLevelSelection | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Input.Core | import RPGEngine.Input.Core (InputHandler, composeInputHandlers, handleKey, ListSelector (..)) | ||||||
|     ( composeInputHandlers, handleKey, InputHandler, ListSelector (..) ) |  | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Config ( levelFolder ) | import RPGEngine.Data (Game (..), State (..), Direction (..)) | ||||||
| import RPGEngine.Data ( Game (..), Direction (..), State (..), StateBase (..) ) | import Graphics.Gloss.Interface.IO.Game (Key(..)) | ||||||
| 
 |  | ||||||
| import Graphics.Gloss.Interface.IO.Game |  | ||||||
|     ( Key(SpecialKey), SpecialKey(KeySpace) ) |  | ||||||
| import Graphics.Gloss.Interface.IO.Interact (SpecialKey(..)) | import Graphics.Gloss.Interface.IO.Interact (SpecialKey(..)) | ||||||
| import RPGEngine.Render.Playing (renderPlaying) | import RPGEngine.Config (levelFolder) | ||||||
| import RPGEngine.Input.Playing (handleInputPlaying) |  | ||||||
| import RPGEngine.Parse (parse) | import RPGEngine.Parse (parse) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
|  |  | ||||||
|  | @ -8,6 +8,5 @@ import RPGEngine.Data ( Game ) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| -- TODO |  | ||||||
| handleInputLose :: InputHandler Game | handleInputLose :: InputHandler Game | ||||||
| handleInputLose = undefined | handleInputLose = undefined | ||||||
|  | @ -2,35 +2,22 @@ module RPGEngine.Input.Menu | ||||||
| ( handleInputMenu | ( handleInputMenu | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Input.Core ( InputHandler, composeInputHandlers, handleAnyKey, ListSelector (..) ) | import RPGEngine.Input.Core (InputHandler, composeInputHandlers, handleAnyKey) | ||||||
| 
 | import RPGEngine.Data (Game (state), State (..)) | ||||||
| import RPGEngine.Data ( Game (..), State (..), StateBase (..) ) | import RPGEngine.Data.Default (defaultSelector) | ||||||
| import RPGEngine.Render.LevelSelection (renderLevelSelection) |  | ||||||
| import RPGEngine.Input.LevelSelection (handleInputLevelSelection) |  | ||||||
| import RPGEngine.Data.Level (getLevelList) | import RPGEngine.Data.Level (getLevelList) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| handleInputMenu :: InputHandler Game | handleInputMenu :: InputHandler Game | ||||||
| handleInputMenu = composeInputHandlers [ | handleInputMenu = composeInputHandlers [ | ||||||
|     handleAnyKey selectLevel |     handleAnyKey (\game -> game{ state = startLevelSelection }) | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| selectLevel :: Game -> Game | startLevelSelection :: State | ||||||
| selectLevel g@Game{ state = state } = g{ state = defaultLevelSelection } | startLevelSelection = LevelSelection { | ||||||
| 
 |     levelList = getLevelList, | ||||||
| defaultLevelSelection :: State |     selector  = defaultSelector | ||||||
| defaultLevelSelection = LevelSelection { base = base, selector = defaultSelector, levelList = levels } |  | ||||||
|     where base = StateBase { |  | ||||||
|         renderer = renderLevelSelection, |  | ||||||
|         inputHandler = handleInputLevelSelection |  | ||||||
|         } |  | ||||||
|           levels = getLevelList |  | ||||||
| 
 |  | ||||||
| defaultSelector :: ListSelector |  | ||||||
| defaultSelector = ListSelector {  |  | ||||||
|     selection = 0,  |  | ||||||
|     selected = False |  | ||||||
| } | } | ||||||
|  | @ -3,14 +3,15 @@ module RPGEngine.Input.Paused | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Input.Core (InputHandler, handleAnyKey) | import RPGEngine.Input.Core (InputHandler, handleAnyKey) | ||||||
| 
 | import RPGEngine.Data (Game (..), State (continue, Paused)) | ||||||
| import RPGEngine.Data ( Game (..), State (..) ) |  | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| handleInputPaused :: InputHandler Game | handleInputPaused :: InputHandler Game | ||||||
| handleInputPaused = handleAnyKey continueGame | handleInputPaused = handleAnyKey continueGame | ||||||
| 
 | 
 | ||||||
|  | ---------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
| continueGame :: Game -> Game | continueGame :: Game -> Game | ||||||
| continueGame g@Game{ state = Paused{ continue = state }} = newGame | continueGame g@Game{ state = Paused{ continue = state }} = newGame | ||||||
|     where newGame = g{ state = state } |     where newGame = g{ state = state } | ||||||
|  |  | ||||||
|  | @ -1,28 +1,17 @@ | ||||||
| module RPGEngine.Input.Playing | module RPGEngine.Input.Playing | ||||||
| ( handleInputPlaying | ( handleInputPlaying | ||||||
|  | , checkPlaying | ||||||
| , spawnPlayer | , spawnPlayer | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Input.Core | import RPGEngine.Input.Core (InputHandler, handleKey, composeInputHandlers) | ||||||
|     ( composeInputHandlers, handleKey, InputHandler ) |  | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data | import RPGEngine.Data (Game (..), Layout(..), Level(..), Physical(..), Player(..), State(..), X, Y, Direction (..)) | ||||||
|     ( Player(Player, position), | import RPGEngine.Data.Game (isLegalMove, isPlayerDead, isPlayerAtExit) | ||||||
|       Direction(West, North, East, South), | import RPGEngine.Data.Level (directionOffsets, findFirstOf) | ||||||
|       Physical(Entrance), | import Data.Maybe (fromJust, isNothing) | ||||||
|       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.Game (Key(..)) | ||||||
| import Graphics.Gloss.Interface.IO.Interact (SpecialKey(..)) | import Graphics.Gloss.Interface.IO.Interact (SpecialKey(..)) | ||||||
| import Data.Maybe (isNothing, fromJust) |  | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
|  | @ -43,6 +32,8 @@ handleInputPlaying = composeInputHandlers [ | ||||||
|     handleKey (Char 'a') $ movePlayer West |     handleKey (Char 'a') $ movePlayer West | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
|  | ---------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
| -- Set the initial position of the player in a given level. | -- Set the initial position of the player in a given level. | ||||||
| spawnPlayer :: Level -> Player -> Player | spawnPlayer :: Level -> Player -> Player | ||||||
| spawnPlayer l@Level{ layout = lay } p@Player{ position = prevPos } = p{ position = newPos } | spawnPlayer l@Level{ layout = lay } p@Player{ position = prevPos } = p{ position = newPos } | ||||||
|  | @ -50,15 +41,30 @@ spawnPlayer l@Level{ layout = lay } p@Player{ position = prevPos } = p{ position | ||||||
|           newPos | isNothing try = prevPos |           newPos | isNothing try = prevPos | ||||||
|                  | otherwise     = fromJust try |                  | otherwise     = fromJust try | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | checkPlaying :: Game -> Game | ||||||
|  | checkPlaying g@Game{ state = s@Playing{ restart = restart }} = newGame | ||||||
|  |     where newGame | isPlayerDead g   = loseGame | ||||||
|  |                   | isPlayerAtExit g = g{ state = goToNextLevel s } | ||||||
|  |                   | otherwise        = g | ||||||
|  |           loseGame      = g{ state = restart } | ||||||
|  | checkPlaying g = g | ||||||
| 
 | 
 | ||||||
| pauseGame :: Game -> Game | pauseGame :: Game -> Game | ||||||
| pauseGame g@Game{ state = playing@Playing{} } = pausedGame | pauseGame g@Game{ state = playing@Playing{} } = pausedGame | ||||||
|     where pausedGame  = g{ state = pausedState } |     where pausedGame  = g{ state = Paused playing } | ||||||
|           pausedState = Paused{ base = newBase, continue = playing } |  | ||||||
|           newBase     = StateBase { renderer = renderPaused, inputHandler = handleInputPaused } |  | ||||||
| pauseGame g = g | pauseGame g = g | ||||||
| 
 | 
 | ||||||
|  | -- Go to next level if there is a next level, otherwise, initialize win state. | ||||||
|  | goToNextLevel :: State -> State | ||||||
|  | goToNextLevel s@Playing{ levels = levels, level = current, count = count, player = player } = nextState | ||||||
|  |     where -- Either the next level or winState | ||||||
|  |           nextState | (count + 1) < length levels = nextLevelState | ||||||
|  |                     | otherwise                   = Win | ||||||
|  |           nextLevelState = s{ level = nextLevel, count = count + 1, player = movedPlayer } | ||||||
|  |           nextLevel      = levels !! (count + 1) | ||||||
|  |           movedPlayer    = spawnPlayer nextLevel player | ||||||
|  | goToNextLevel s = s | ||||||
|  | 
 | ||||||
| -- Move a player in a direction if possible. | -- Move a player in a direction if possible. | ||||||
| movePlayer :: Direction -> Game -> Game | movePlayer :: Direction -> Game -> Game | ||||||
| movePlayer dir g@Game{ state = s@Playing{ player = p@Player{ position = (x, y) }}} = newGame | movePlayer dir g@Game{ state = s@Playing{ player = p@Player{ position = (x, y) }}} = newGame | ||||||
|  | @ -70,12 +76,6 @@ movePlayer dir g@Game{ state = s@Playing{ player = p@Player{ position = (x, y) } | ||||||
|           (xD, yD)  = directionOffsets dir |           (xD, yD)  = directionOffsets dir | ||||||
| movePlayer _ g = g | movePlayer _ g = g | ||||||
| 
 | 
 | ||||||
| -- TODO |  | ||||||
| goToNextLevel :: Game -> Game |  | ||||||
| goToNextLevel = undefined |  | ||||||
| 
 |  | ||||||
| ---------------------------------------------------------------------- |  | ||||||
| 
 |  | ||||||
| -- Map all Physicals onto coordinates | -- Map all Physicals onto coordinates | ||||||
| putCoords :: Level -> [(X, Y, Physical)] | putCoords :: Level -> [(X, Y, Physical)] | ||||||
| putCoords l@Level{ layout = lay } = concatMap (\(a, bs) -> map (\(b, c) -> (b, a, c)) bs) numberedList | putCoords l@Level{ layout = lay } = concatMap (\(a, bs) -> map (\(b, c) -> (b, a, c)) bs) numberedList | ||||||
|  |  | ||||||
|  | @ -2,12 +2,15 @@ module RPGEngine.Input.Win | ||||||
| ( handleInputWin | ( handleInputWin | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Input.Core ( InputHandler ) | import RPGEngine.Input.Core (InputHandler, handleAnyKey) | ||||||
| 
 | import RPGEngine.Data (Game (..), State (Menu)) | ||||||
| import RPGEngine.Data ( Game ) |  | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| -- TODO |  | ||||||
| handleInputWin :: InputHandler Game | handleInputWin :: InputHandler Game | ||||||
| handleInputWin = undefined | handleInputWin = handleAnyKey goToMenu | ||||||
|  | 
 | ||||||
|  | ---------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | goToMenu :: Game -> Game | ||||||
|  | goToMenu g = g{ state = Menu } | ||||||
|  | @ -14,3 +14,5 @@ parse :: FilePath -> Game | ||||||
| parse filename = structureToGame struct | parse filename = structureToGame struct | ||||||
|     where (Right struct) = unsafePerformIO io |     where (Right struct) = unsafePerformIO io | ||||||
|           io             = parseFromFile structure filename |           io             = parseFromFile structure filename | ||||||
|  | 
 | ||||||
|  | tempParse = parseFromFile | ||||||
|  | @ -11,24 +11,24 @@ import RPGEngine.Data | ||||||
|       Item(itemId, itemX, itemY, itemName, itemDescription, itemValue, |       Item(itemId, itemX, itemY, itemName, itemDescription, itemValue, | ||||||
|            itemActions, useTimes), |            itemActions, useTimes), | ||||||
|       Level(layout, items, entities), |       Level(layout, items, entities), | ||||||
|       Game (..), State (..), StateBase (..) ) |       Game (..), State (..) ) | ||||||
| import RPGEngine.Parse.TextToStructure | import RPGEngine.Parse.TextToStructure | ||||||
|     ( Value(Infinite, Action, Layout, String, Direction, Integer), |     ( Value(Infinite, Action, Layout, String, Direction, Integer), | ||||||
|       Key(Tag, ConditionList), |       Key(Tag, ConditionList), | ||||||
|       Structure(..) ) |       Structure(..) ) | ||||||
| import RPGEngine.Data.Default (defaultPlayer, defaultLevel, defaultItem, defaultEntity) | import RPGEngine.Data.Default (defaultPlayer, defaultLevel, defaultItem, defaultEntity) | ||||||
| import RPGEngine.Render.Playing (renderPlaying) |  | ||||||
| import RPGEngine.Input.Playing (handleInputPlaying) |  | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| structureToGame :: Structure -> Game | structureToGame :: Structure -> Game | ||||||
| structureToGame (Block [(Entry(Tag "player") playerBlock), (Entry(Tag "levels") levelsBlock)]) = game | -- structureToGame [Entry(Tag "player") playerBlock, Entry(Tag "levels") levelsBlock] = game | ||||||
|     where game         = Game{ state = newState, levels = newLevels, player = newPlayer } | structureToGame (Entry (Tag "player") playerBlock) = game | ||||||
|           newState     = Playing{ base = playingBase, level = currentLevel } |     where game         = Game{ state = newState } | ||||||
|           playingBase  = StateBase{ renderer = renderPlaying, inputHandler = handleInputPlaying } |           newState     = Playing{ levels = newLevels, level = currentLevel, player = newPlayer, restart = newState } | ||||||
|           newLevels    = structureToLevels levelsBlock |           -- newLevels    = structureToLevels levelsBlock | ||||||
|           currentLevel = head newLevels |           -- currentLevel = head newLevels | ||||||
|  |           newLevels    = [defaultLevel] | ||||||
|  |           currentLevel = defaultLevel | ||||||
|           newPlayer    = structureToPlayer playerBlock |           newPlayer    = structureToPlayer playerBlock | ||||||
| 
 | 
 | ||||||
| ------------------------------- Player ------------------------------- | ------------------------------- Player ------------------------------- | ||||||
|  |  | ||||||
|  | @ -2,20 +2,22 @@ | ||||||
| -- submodules. | -- submodules. | ||||||
| module RPGEngine.Render | module RPGEngine.Render | ||||||
| ( initWindow | ( initWindow | ||||||
| , initGame |  | ||||||
| , render | , render | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Render.Core ( Renderer(..) ) | import RPGEngine.Render.Core ( Renderer(..) ) | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data ( State(..), Game(..), StateBase(..) ) | import RPGEngine.Data (Game(..), State (..)) | ||||||
| import Graphics.Gloss ( Display ) |  | ||||||
| import Graphics.Gloss.Data.Display ( Display(InWindow) ) |  | ||||||
| import Graphics.Gloss.Data.Picture (Picture) |  | ||||||
| import RPGEngine.Data.Default (defaultLevel, defaultPlayer) |  | ||||||
| import RPGEngine.Input.Playing (spawnPlayer) |  | ||||||
| import RPGEngine.Render.Menu( renderMenu ) | import RPGEngine.Render.Menu( renderMenu ) | ||||||
| import RPGEngine.Input.Menu (handleInputMenu) | import RPGEngine.Render.LevelSelection ( renderLevelSelection ) | ||||||
|  | import RPGEngine.Render.Playing ( renderPlaying ) | ||||||
|  | import RPGEngine.Render.Paused ( renderPaused ) | ||||||
|  | import RPGEngine.Render.Win ( renderWin ) | ||||||
|  | import RPGEngine.Render.Lose ( renderLose ) | ||||||
|  | 
 | ||||||
|  | import Graphics.Gloss (Display) | ||||||
|  | import Graphics.Gloss.Data.Picture (Picture, blank) | ||||||
|  | import Graphics.Gloss.Data.Display (Display(..)) | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
|  | @ -23,17 +25,12 @@ import RPGEngine.Input.Menu (handleInputMenu) | ||||||
| initWindow :: String -> (Int, Int) -> (Int, Int) -> Display | initWindow :: String -> (Int, Int) -> (Int, Int) -> Display | ||||||
| initWindow = InWindow | initWindow = InWindow | ||||||
| 
 | 
 | ||||||
| -- Initialize the game |  | ||||||
| initGame :: Game |  | ||||||
| initGame = Game {  |  | ||||||
|     state   = Menu{ base = StateBase{  |  | ||||||
|         renderer = renderMenu,  |  | ||||||
|         inputHandler = handleInputMenu |  | ||||||
|     }} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| -- Render all different states | -- Render all different states | ||||||
| render :: Game -> Picture | render :: Game -> Picture | ||||||
| render g@Game{ state = state } = renderFunc state | render Game{ state = s@Menu             } = renderMenu s | ||||||
|     where stateBase  = base state | render Game{ state = s@LevelSelection{} } = renderLevelSelection s | ||||||
|           renderFunc = renderer stateBase | render Game{ state = s@Playing{}        } = renderPlaying s | ||||||
|  | render Game{ state = s@Paused{}         } = renderPaused s | ||||||
|  | render Game{ state = s@Win              } = renderWin s | ||||||
|  | render Game{ state = s@Lose{}           } = renderLose s | ||||||
|  | render _ = blank | ||||||
|  | @ -2,16 +2,15 @@ module RPGEngine.Render.LevelSelection | ||||||
| ( renderLevelSelection | ( renderLevelSelection | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Config ( resolution, zoom ) |  | ||||||
| import RPGEngine.Data ( Game (..), State (..) ) |  | ||||||
| import RPGEngine.Data.Level ( getLevelList ) |  | ||||||
| import RPGEngine.Render.Core (Renderer) | import RPGEngine.Render.Core (Renderer) | ||||||
| 
 | 
 | ||||||
| import Graphics.Gloss | import RPGEngine.Config (resolution, zoom) | ||||||
|     ( pictures, text, translate, blank, Picture, color ) | import RPGEngine.Data (State (..)) | ||||||
|  | 
 | ||||||
|  | import Graphics.Gloss ( pictures, color, text, translate, blank ) | ||||||
|  | import Graphics.Gloss.Data.Color (red) | ||||||
| import Graphics.Gloss.Data.Picture (scale) | import Graphics.Gloss.Data.Picture (scale) | ||||||
| import RPGEngine.Input.Core (ListSelector(..)) | import RPGEngine.Input.Core (ListSelector(..)) | ||||||
| import Graphics.Gloss.Data.Color (red) |  | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,10 +5,11 @@ module RPGEngine.Render.Lose | ||||||
| import RPGEngine.Render.Core (Renderer) | import RPGEngine.Render.Core (Renderer) | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data (State) | import RPGEngine.Data (State) | ||||||
|  | 
 | ||||||
| import Graphics.Gloss (text) | import Graphics.Gloss (text) | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| -- TODO | -- TODO | ||||||
| renderLose :: Renderer State | renderLose :: Renderer State | ||||||
| renderLose _ = text "Win" | renderLose _ = text "You lose" | ||||||
|  | @ -5,9 +5,10 @@ module RPGEngine.Render.Menu | ||||||
| import RPGEngine.Render.Core (Renderer) | import RPGEngine.Render.Core (Renderer) | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data (State) | import RPGEngine.Data (State) | ||||||
|  | 
 | ||||||
| import Graphics.Gloss (text) | import Graphics.Gloss (text) | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| -- TODO | -- TODO | ||||||
| renderMenu :: Renderer State | renderMenu :: Renderer State | ||||||
|  |  | ||||||
|  | @ -5,10 +5,9 @@ module RPGEngine.Render.Paused | ||||||
| import RPGEngine.Render.Core (Renderer, overlay) | import RPGEngine.Render.Core (Renderer, overlay) | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data (State(..)) | import RPGEngine.Data (State(..)) | ||||||
| import Graphics.Gloss ( pictures, scale, text ) |  | ||||||
| import RPGEngine.Render.Playing (renderPlaying) | import RPGEngine.Render.Playing (renderPlaying) | ||||||
| import Graphics.Gloss.Data.Picture (color) | 
 | ||||||
| import Graphics.Gloss.Data.Color (white) | import Graphics.Gloss (pictures, white, color, Color(..), text, scale) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,20 +4,11 @@ module RPGEngine.Render.Playing | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Render.Core (Renderer, getRender, setRenderPos) | import RPGEngine.Render.Core (Renderer, getRender, setRenderPos) | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data |  | ||||||
|     ( Player(..), |  | ||||||
|       Entity(..), |  | ||||||
|       Item(..), |  | ||||||
|       Physical(..), |  | ||||||
|       Layout, |  | ||||||
|       Level(..), |  | ||||||
|       State(..), |  | ||||||
|       Game(..) ) |  | ||||||
| import Graphics.Gloss ( Picture, pictures ) |  | ||||||
| import Graphics.Gloss.Data.Picture (translate) |  | ||||||
| import RPGEngine.Config (resolution, zoom) | import RPGEngine.Config (resolution, zoom) | ||||||
| import Graphics.Gloss (text) | import RPGEngine.Data (State(..), Player (..), Game (..), Level (..), Layout, Physical (..), Item (..), Entity (..)) | ||||||
| import Graphics.Gloss (blank) | 
 | ||||||
|  | import Graphics.Gloss ( pictures, Picture, translate ) | ||||||
|  | import Graphics.Gloss.Data.Picture (blank) | ||||||
| 
 | 
 | ||||||
| ------------------------------ Exported ------------------------------ | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
|  | @ -42,6 +33,7 @@ focusPlayer Game{ state = Playing{ player = Player{ position = (x, y) }}} = move | ||||||
|     where move    = translate centerX centerY |     where move    = translate centerX centerY | ||||||
|           centerX = resolution * zoom * fromIntegral (negate x) |           centerX = resolution * zoom * fromIntegral (negate x) | ||||||
|           centerY = resolution * zoom * fromIntegral (negate y) |           centerY = resolution * zoom * fromIntegral (negate y) | ||||||
|  | focusPlayer _ = id | ||||||
| 
 | 
 | ||||||
| ------------------------------- Level -------------------------------- | ------------------------------- Level -------------------------------- | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,10 +5,11 @@ module RPGEngine.Render.Win | ||||||
| import RPGEngine.Render.Core (Renderer) | import RPGEngine.Render.Core (Renderer) | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data (State) | import RPGEngine.Data (State) | ||||||
|  | 
 | ||||||
| import Graphics.Gloss (text) | import Graphics.Gloss (text) | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ------------------------------ Exported ------------------------------ | ||||||
| 
 | 
 | ||||||
| -- TODO | -- TODO | ||||||
| renderWin :: Renderer State | renderWin :: Renderer State | ||||||
| renderWin _ = text "Win" | renderWin _ = text "You win!\nPress any key to return to the menu." | ||||||
|  | @ -23,12 +23,12 @@ library | ||||||
| 
 | 
 | ||||||
|     RPGEngine.Input |     RPGEngine.Input | ||||||
|     RPGEngine.Input.Core |     RPGEngine.Input.Core | ||||||
|     RPGEngine.Input.LevelSelection |  | ||||||
|     RPGEngine.Input.Lose |  | ||||||
|     RPGEngine.Input.Menu |     RPGEngine.Input.Menu | ||||||
|     RPGEngine.Input.Paused |     RPGEngine.Input.LevelSelection | ||||||
|     RPGEngine.Input.Playing |     RPGEngine.Input.Playing | ||||||
|  |     RPGEngine.Input.Paused | ||||||
|     RPGEngine.Input.Win |     RPGEngine.Input.Win | ||||||
|  |     RPGEngine.Input.Lose | ||||||
| 
 | 
 | ||||||
|     RPGEngine.Parse |     RPGEngine.Parse | ||||||
|     RPGEngine.Parse.Core |     RPGEngine.Parse.Core | ||||||
|  | @ -37,12 +37,12 @@ library | ||||||
|      |      | ||||||
|     RPGEngine.Render |     RPGEngine.Render | ||||||
|     RPGEngine.Render.Core |     RPGEngine.Render.Core | ||||||
|     RPGEngine.Render.LevelSelection |  | ||||||
|     RPGEngine.Render.Lose |  | ||||||
|     RPGEngine.Render.Menu |     RPGEngine.Render.Menu | ||||||
|     RPGEngine.Render.Paused |     RPGEngine.Render.LevelSelection | ||||||
|     RPGEngine.Render.Playing |     RPGEngine.Render.Playing | ||||||
|  |     RPGEngine.Render.Paused | ||||||
|     RPGEngine.Render.Win |     RPGEngine.Render.Win | ||||||
|  |     RPGEngine.Render.Lose | ||||||
| 
 | 
 | ||||||
| executable rpg-engine | executable rpg-engine | ||||||
|   main-is: Main.hs |   main-is: Main.hs | ||||||
|  |  | ||||||
		Reference in a new issue