dev #25
					 17 changed files with 401 additions and 34 deletions
				
			
		
							
								
								
									
										34
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										34
									
								
								README.md
									
										
									
									
									
								
							|  | @ -64,7 +64,7 @@ TODO | ||||||
| 
 | 
 | ||||||
| - An example playthrough, with pictures and explanations | - An example playthrough, with pictures and explanations | ||||||
| 
 | 
 | ||||||
| \pagebreak | <div style="page-break-after: always; visibility: hidden">\pagebreak</div> | ||||||
| 
 | 
 | ||||||
| ## Writing your own stages | ## Writing your own stages | ||||||
| 
 | 
 | ||||||
|  | @ -250,10 +250,22 @@ If we look at the example, all the objects are | ||||||
|                         Entry = empty ConditionList + Action ('leave()') |                         Entry = empty ConditionList + Action ('leave()') | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| \pagebreak | <div style="page-break-after: always; visibility: hidden">\pagebreak</div> | ||||||
| 
 | 
 | ||||||
| ## Development notes | ## Development notes | ||||||
| 
 | 
 | ||||||
|  | ### Engine architecture | ||||||
|  | 
 | ||||||
|  | <mark>TODO</mark> | ||||||
|  | 
 | ||||||
|  | #### Monads/Monad stack | ||||||
|  | 
 | ||||||
|  | <mark>TODO</mark> | ||||||
|  | 
 | ||||||
|  | ### Tests | ||||||
|  | 
 | ||||||
|  | <mark>TODO</mark> | ||||||
|  | 
 | ||||||
| ### Assets & dependencies | ### Assets & dependencies | ||||||
| 
 | 
 | ||||||
| The following assets were used (and modified if specified): | The following assets were used (and modified if specified): | ||||||
|  | @ -268,6 +280,7 @@ The following assets were used (and modified if specified): | ||||||
| 
 | 
 | ||||||
| RPG-Engine makes use of the following libraries: | RPG-Engine makes use of the following libraries: | ||||||
| 
 | 
 | ||||||
|  | - [directory](https://hackage.haskell.org/package/directory) for listing levels in a directory | ||||||
| - [gloss](https://hackage.haskell.org/package/gloss) for game rendering | - [gloss](https://hackage.haskell.org/package/gloss) for game rendering | ||||||
| - [gloss-juicy](https://hackage.haskell.org/package/gloss-juicy) for rendering images | - [gloss-juicy](https://hackage.haskell.org/package/gloss-juicy) for rendering images | ||||||
| - [hspec](https://hackage.haskell.org/package/hspec) for testing | - [hspec](https://hackage.haskell.org/package/hspec) for testing | ||||||
|  | @ -278,12 +291,23 @@ RPG-Engine makes use of the following libraries: | ||||||
| 
 | 
 | ||||||
| The following ideas could (or should) be implemented in the future of this project. | The following ideas could (or should) be implemented in the future of this project. | ||||||
| 
 | 
 | ||||||
| - [ ] Entity system: With en ES, you can implement moving entities and repeated input. It also resembles the typical | - [ ] **Entity system:** With en ES, you can implement moving entities and repeated input. It also resembles the typical | ||||||
|  game loop more closely which can make it easier to implement other ideas in the future. |  game loop more closely which can make it easier to implement other ideas in the future. | ||||||
|  | - [ ] **Game music:** Ambient game music and sound effects can improve the gaming experience I think. | ||||||
|  | - [ ] **Expand configuration file:** Implement the same methods for parsing stage description files to a configuration file, | ||||||
|  |  containing keybinds, dimension sizes, even window titles, making this a truly customizable engine. | ||||||
|  | - [ ] **Camera follows player:** The camera should follow the player, making it always center. This allows for larger levels | ||||||
|  |  increases the immersion of the game. | ||||||
| 
 | 
 | ||||||
| - [ ] Game music: Ambient game music and sound effects can improve the gaming experience I think. | <div style="page-break-after: always; visibility: hidden">\pagebreak</div> | ||||||
| 
 | 
 | ||||||
| \pagebreak | ## Conclusion  | ||||||
|  | 
 | ||||||
|  | Parsing was way harder than I initially expected. About half of my time on this project was spent writing the parser. | ||||||
|  | 
 | ||||||
|  | <mark>TODO</mark> | ||||||
|  | 
 | ||||||
|  | <div style="page-break-after: always; visibility: hidden">\pagebreak</div> | ||||||
| 
 | 
 | ||||||
| ## References | ## References | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								assets/environment/overlay.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/environment/overlay.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 494 B | 
| After Width: | Height: | Size: 870 B | 
|  | @ -19,8 +19,8 @@ levels: [ | ||||||
|         items: [ |         items: [ | ||||||
|             { |             { | ||||||
|                 id: "key", |                 id: "key", | ||||||
|                 x: 1, |                 x: 0, | ||||||
|                 y: 2, |                 y: 1, | ||||||
|                 name: "Sleutel", |                 name: "Sleutel", | ||||||
|                 description: "Deze sleutel kan een deur openen", |                 description: "Deze sleutel kan een deur openen", | ||||||
|                 useTimes: 1, |                 useTimes: 1, | ||||||
|  | @ -35,8 +35,8 @@ levels: [ | ||||||
|         entities: [ |         entities: [ | ||||||
|             { |             { | ||||||
|                 id: "door", |                 id: "door", | ||||||
|                 x: 1, |                 x: 0, | ||||||
|                 y: 4, |                 y: 3, | ||||||
|                 name: "Deur", |                 name: "Deur", | ||||||
|                 description: "Deze deur kan geopend worden met een sleutel", |                 description: "Deze deur kan geopend worden met een sleutel", | ||||||
|                 direction: up, |                 direction: up, | ||||||
|  |  | ||||||
|  | @ -69,8 +69,8 @@ levels: [ | ||||||
| 
 | 
 | ||||||
|                 actions: { |                 actions: { | ||||||
|                     [inventoryContains(potion)] increasePlayerHp(potion), |                     [inventoryContains(potion)] increasePlayerHp(potion), | ||||||
|                     [inventoryContains(sword)] decreaseHp(m1, sword), |                     [inventoryContains(sword)] decreaseHp(devil, sword), | ||||||
|                     [] decreaseHp(m1, dagger), |                     [] decreaseHp(devil, dagger), | ||||||
|                     [] leave() |                     [] leave() | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
							
								
								
									
										134
									
								
								levels/level4.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								levels/level4.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,134 @@ | ||||||
|  | player: { | ||||||
|  |     hp: 50, | ||||||
|  |     inventory: [ | ||||||
|  |         { | ||||||
|  |             id: "dagger", | ||||||
|  |             x: 0, | ||||||
|  |             y: 0, | ||||||
|  |             name: "Dolk", | ||||||
|  |             description: "Basis schade tegen monsters", | ||||||
|  |             useTimes: infinite, | ||||||
|  |             value: 10, | ||||||
|  | 
 | ||||||
|  |             actions: {} | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | levels: [ | ||||||
|  |     { | ||||||
|  |         layout: { | ||||||
|  |             | * * * * * * | ||||||
|  |             | * s . . e * | ||||||
|  |             | * * * * * * | ||||||
|  |         }, | ||||||
|  |          | ||||||
|  |         items: [], | ||||||
|  | 
 | ||||||
|  |         entities: [] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         layout: { | ||||||
|  |             | * * * | ||||||
|  |             | * e * | ||||||
|  |             | * . * | ||||||
|  |             | * . * | ||||||
|  |             | * . * | ||||||
|  |             | * . * | ||||||
|  |             | * s * | ||||||
|  |             | * * * | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         items: [ | ||||||
|  |             { | ||||||
|  |                 id: "key", | ||||||
|  |                 x: 0, | ||||||
|  |                 y: 1, | ||||||
|  |                 name: "Sleutel", | ||||||
|  |                 description: "Deze sleutel kan een deur openen", | ||||||
|  |                 useTimes: 1, | ||||||
|  |                 value: 0, | ||||||
|  |                 actions: { | ||||||
|  |                     [not(inventoryFull())] retrieveItem(key), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  | 
 | ||||||
|  |         entities: [ | ||||||
|  |             { | ||||||
|  |                 id: "door", | ||||||
|  |                 x: 0, | ||||||
|  |                 y: 3, | ||||||
|  |                 name: "Deur", | ||||||
|  |                 description: "Deze deur kan geopend worden met een sleutel", | ||||||
|  |                 direction: up, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [inventoryContains(key)] useItem(key), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         layout: { | ||||||
|  |             | * * * * * * * * | ||||||
|  |             | * . . . . . . * | ||||||
|  |             | * s . . . . . * | ||||||
|  |             | * . . . . . e * | ||||||
|  |             | * . . . . . . * | ||||||
|  |             | * * * * * * * * | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         items: [ | ||||||
|  |             { | ||||||
|  |                 id: "sword", | ||||||
|  |                 x: 2, | ||||||
|  |                 y: 3, | ||||||
|  |                 name: "Zwaard", | ||||||
|  |                 description: "Meer schade tegen monsters", | ||||||
|  |                 useTimes: infinite, | ||||||
|  |                 value: 25, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [not(inventoryFull())] retrieveItem(sword), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 id: "potion", | ||||||
|  |                 x: 3, | ||||||
|  |                 y: 1, | ||||||
|  |                 name: "Levensbrouwsel", | ||||||
|  |                 description: "Geeft een aantal levenspunten terug", | ||||||
|  |                 useTimes: 1, | ||||||
|  |                 value: 50, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [not(inventoryFull())] retrieveItem(potion), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  | 
 | ||||||
|  |         entities: [ | ||||||
|  |             { | ||||||
|  |                 id: "devil", | ||||||
|  |                 x: 4, | ||||||
|  |                 y: 3, | ||||||
|  |                 name: "Duivel", | ||||||
|  |                 description: "Een monster uit de hel", | ||||||
|  |                 hp: 50, | ||||||
|  |                 value: 5, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [inventoryContains(potion)] increasePlayerHp(potion), | ||||||
|  |                     [inventoryContains(sword)] decreaseHp(devil, sword), | ||||||
|  |                     [] decreaseHp(devil, dagger), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  | ] | ||||||
							
								
								
									
										138
									
								
								levels/level_more_levels.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								levels/level_more_levels.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,138 @@ | ||||||
|  | # Dit gehele bestand is een Block | ||||||
|  | 
 | ||||||
|  | # Dit is een entry: key + value | ||||||
|  | player: { # Value is hier een block | ||||||
|  |     hp: 50, | ||||||
|  |     inventory: [ # BlockList | ||||||
|  |         { | ||||||
|  |             id: "dagger", | ||||||
|  |             x: 0, | ||||||
|  |             y: 0, | ||||||
|  |             name: "Dolk", | ||||||
|  |             description: "Basis schade tegen monsters", | ||||||
|  |             useTimes: infinite, | ||||||
|  |             value: 10, | ||||||
|  | 
 | ||||||
|  |             actions: {} | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # Dit is een entry | ||||||
|  | levels: [ | ||||||
|  |     { | ||||||
|  |         layout: { | ||||||
|  |             | * * * * * * | ||||||
|  |             | * s . . e * | ||||||
|  |             | * * * * * * | ||||||
|  |         }, | ||||||
|  |          | ||||||
|  |         items: [], | ||||||
|  | 
 | ||||||
|  |         entities: [] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         layout: { | ||||||
|  |             | * * * | ||||||
|  |             | * e * | ||||||
|  |             | * . * | ||||||
|  |             | * . * | ||||||
|  |             | * . * | ||||||
|  |             | * . * | ||||||
|  |             | * s * | ||||||
|  |             | * * * | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         items: [ | ||||||
|  |             { | ||||||
|  |                 id: "key", | ||||||
|  |                 x: 1, | ||||||
|  |                 y: 2, | ||||||
|  |                 name: "Sleutel", | ||||||
|  |                 description: "Deze sleutel kan een deur openen", | ||||||
|  |                 useTimes: 1, | ||||||
|  |                 value: 0, | ||||||
|  |                 actions: { | ||||||
|  |                     [not(inventoryFull())] retrieveItem(key), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  | 
 | ||||||
|  |         entities: [ | ||||||
|  |             { | ||||||
|  |                 id: "door", | ||||||
|  |                 x: 1, | ||||||
|  |                 y: 4, | ||||||
|  |                 name: "Deur", | ||||||
|  |                 description: "Deze deur kan geopend worden met een sleutel", | ||||||
|  |                 direction: up, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [inventoryContains(key)] useItem(key), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         layout: { | ||||||
|  |             | * * * * * * * * | ||||||
|  |             | * . . . . . . * | ||||||
|  |             | * s . . . . . * | ||||||
|  |             | * . . . . . e * | ||||||
|  |             | * . . . . . . * | ||||||
|  |             | * * * * * * * * | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         items: [ | ||||||
|  |             { | ||||||
|  |                 id: "sword", | ||||||
|  |                 x: 2, | ||||||
|  |                 y: 3, | ||||||
|  |                 name: "Zwaard", | ||||||
|  |                 description: "Meer schade tegen monsters", | ||||||
|  |                 useTimes: infinite, | ||||||
|  |                 value: 25, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [not(inventoryFull())] retrieveItem(sword), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 id: "potion", | ||||||
|  |                 x: 3, | ||||||
|  |                 y: 1, | ||||||
|  |                 name: "Levensbrouwsel", | ||||||
|  |                 description: "Geeft een aantal levenspunten terug", | ||||||
|  |                 useTimes: 1, | ||||||
|  |                 value: 50, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [not(inventoryFull())] retrieveItem(potion), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  | 
 | ||||||
|  |         entities: [ | ||||||
|  |             { | ||||||
|  |                 id: "devil", | ||||||
|  |                 x: 4, | ||||||
|  |                 y: 3, | ||||||
|  |                 name: "Duivel", | ||||||
|  |                 description: "Een monster uit de hel", | ||||||
|  |                 hp: 50, | ||||||
|  |                 value: 5, | ||||||
|  | 
 | ||||||
|  |                 actions: { | ||||||
|  |                     [inventoryContains(potion)] increasePlayerHp(potion), | ||||||
|  |                     [inventoryContains(sword)] decreaseHp(m1, sword), | ||||||
|  |                     [] decreaseHp(m1, dagger), | ||||||
|  |                     [] leave() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  | ] | ||||||
|  | @ -48,6 +48,7 @@ instance Living Player where | ||||||
| 
 | 
 | ||||||
| -- Current state of the game. | -- Current state of the game. | ||||||
| data State = Menu | data State = Menu | ||||||
|  |            | LvlSelect | ||||||
|            | Playing |            | Playing | ||||||
|            | Pause |            | Pause | ||||||
|            | Win |            | Win | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ import RPGEngine.Data | ||||||
| 
 | 
 | ||||||
| -- Get the next state based on the current state | -- Get the next state based on the current state | ||||||
| nextState :: State -> State | nextState :: State -> State | ||||||
| nextState Menu = Playing | nextState Menu = LvlSelect | ||||||
| nextState Playing = Pause | nextState Playing = Pause | ||||||
| nextState Pause = Playing | nextState Pause = Playing | ||||||
| nextState _ = Menu | nextState _ = Menu | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import Graphics.Gloss.Interface.IO.Game | ||||||
| -- Handle all input for RPG-Engine | -- Handle all input for RPG-Engine | ||||||
| handleAllInput :: InputHandler Game | handleAllInput :: InputHandler Game | ||||||
| handleAllInput ev g@Game{ state = Playing   } = handlePlayInputs ev g | handleAllInput ev g@Game{ state = Playing   } = handlePlayInputs ev g | ||||||
|  | handleAllInput ev g@Game{ state = LvlSelect } = handleLvlSelectInput ev g | ||||||
| handleAllInput ev g                           = handleAnyKey setNextState ev g | handleAllInput ev g                           = handleAnyKey setNextState ev g | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
|  | @ -38,6 +39,10 @@ handlePlayInputs = composeInputHandlers [ | ||||||
|     handleKey (Char 'a') $ movePlayer West |     handleKey (Char 'a') $ movePlayer West | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
|  | -- Input for selection a level to load | ||||||
|  | handleLvlSelectInput :: InputHandler Game | ||||||
|  | handleLvlSelectInput = composeInputHandlers [] | ||||||
|  | 
 | ||||||
| -- Go to the next stage of the Game | -- Go to the next stage of the Game | ||||||
| setNextState :: Game -> Game | setNextState :: Game -> Game | ||||||
| setNextState game = game{ state = newState } | setNextState game = game{ state = newState } | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								lib/RPGEngine/Input/LvlSelect.hs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lib/RPGEngine/Input/LvlSelect.hs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | module RPGEngine.Input.LvlSelect | ||||||
|  | ( getLvlList | ||||||
|  | ) where | ||||||
|  | 
 | ||||||
|  | import GHC.IO (unsafePerformIO) | ||||||
|  | import System.Directory (getDirectoryContents) | ||||||
|  | 
 | ||||||
|  | lvlFolder :: FilePath | ||||||
|  | lvlFolder = "levels" | ||||||
|  | 
 | ||||||
|  | getLvlList :: [FilePath] | ||||||
|  | getLvlList = unsafePerformIO $ getDirectoryContents lvlFolder | ||||||
|  | @ -9,14 +9,24 @@ module RPGEngine.Render | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data | import RPGEngine.Data | ||||||
|     ( State(..), |     ( State(..), | ||||||
|       Game(..) ) |       Game(..), Player (..) ) | ||||||
| import RPGEngine.Render.Level | import RPGEngine.Render.Level | ||||||
|     ( renderLevel ) |     ( renderLevel ) | ||||||
| 
 |  | ||||||
| import Graphics.Gloss | import Graphics.Gloss | ||||||
|     ( white, pictures, text, Display(InWindow), Color, Picture ) |     ( white, | ||||||
| import RPGEngine.Render.Player (renderPlayer) |       pictures, | ||||||
|  |       text, | ||||||
|  |       Display(InWindow), | ||||||
|  |       Color, | ||||||
|  |       Picture, | ||||||
|  |       scale, | ||||||
|  |       translate ) | ||||||
|  | import RPGEngine.Render.Player (renderPlayer, focusPlayer) | ||||||
| import RPGEngine.Render.GUI (renderGUI) | import RPGEngine.Render.GUI (renderGUI) | ||||||
|  | import Graphics.Gloss.Data.Picture (color) | ||||||
|  | import RPGEngine.Render.Core (overlay) | ||||||
|  | import RPGEngine.Input.LvlSelect (getLvlList) | ||||||
|  | import RPGEngine.Render.LvlSelect (renderLvlList) | ||||||
| 
 | 
 | ||||||
| ----------------------------- Constants ------------------------------ | ----------------------------- Constants ------------------------------ | ||||||
| 
 | 
 | ||||||
|  | @ -33,6 +43,7 @@ initWindow = InWindow | ||||||
| -- Render the game | -- Render the game | ||||||
| render :: Game -> Picture | render :: Game -> Picture | ||||||
| render g@Game{ state = Menu      } = renderMenu g | render g@Game{ state = Menu      } = renderMenu g | ||||||
|  | render g@Game{ state = LvlSelect } = renderLevelSelection g | ||||||
| render g@Game{ state = Playing   } = renderPlaying g | render g@Game{ state = Playing   } = renderPlaying g | ||||||
| render g@Game{ state = Pause     } = renderPause g | render g@Game{ state = Pause     } = renderPause g | ||||||
| render g@Game{ state = Win       } = renderWin g | render g@Game{ state = Win       } = renderWin g | ||||||
|  | @ -44,6 +55,10 @@ render g@Game{ state = Lose    } = renderLose g | ||||||
| renderMenu :: Game -> Picture | renderMenu :: Game -> Picture | ||||||
| renderMenu _ = text "[Press any key to start]" | renderMenu _ = text "[Press any key to start]" | ||||||
| 
 | 
 | ||||||
|  | -- TODO | ||||||
|  | renderLevelSelection :: Game -> Picture | ||||||
|  | renderLevelSelection _ = renderLvlList getLvlList | ||||||
|  | 
 | ||||||
| renderPlaying :: Game -> Picture | renderPlaying :: Game -> Picture | ||||||
| renderPlaying g@Game{ playing = lvl, player = player } = pictures [ | renderPlaying g@Game{ playing = lvl, player = player } = pictures [ | ||||||
|     renderLevel lvl, |     renderLevel lvl, | ||||||
|  | @ -51,9 +66,12 @@ renderPlaying g@Game{ playing = lvl, player = player } = pictures [ | ||||||
|     renderGUI g |     renderGUI g | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
| -- TODO |  | ||||||
| renderPause :: Game -> Picture | renderPause :: Game -> Picture | ||||||
| renderPause _ = text "[Press any key to continue]" | renderPause g = pictures [renderPlaying g, pause] | ||||||
|  |     where pause = pictures [ | ||||||
|  |             overlay, | ||||||
|  |             color white $ scale 0.5 0.5 $ text "[Press any key to continue]" | ||||||
|  |             ] | ||||||
| 
 | 
 | ||||||
| -- TODO | -- TODO | ||||||
| renderWin :: Game -> Picture | renderWin :: Game -> Picture | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| module RPGEngine.Render.Core where | module RPGEngine.Render.Core where | ||||||
| 
 | 
 | ||||||
| import Graphics.Gloss ( Picture, translate ) | import Graphics.Gloss ( Picture, translate, pictures ) | ||||||
| import GHC.IO (unsafePerformIO) | import GHC.IO (unsafePerformIO) | ||||||
| import Graphics.Gloss.Juicy (loadJuicyPNG) | import Graphics.Gloss.Juicy (loadJuicyPNG) | ||||||
| import Data.Maybe (fromJust) | import Data.Maybe (fromJust) | ||||||
|  | @ -21,7 +21,7 @@ assetsFolder :: FilePath | ||||||
| assetsFolder = "assets/" | assetsFolder = "assets/" | ||||||
| 
 | 
 | ||||||
| unknownImage :: FilePath | unknownImage :: FilePath | ||||||
| unknownImage = "unkown.png" | unknownImage = "unknown.png" | ||||||
| 
 | 
 | ||||||
| allEntities :: [(String, FilePath)] | allEntities :: [(String, FilePath)] | ||||||
| allEntities = [ | allEntities = [ | ||||||
|  | @ -32,6 +32,7 @@ allEntities = [ | ||||||
| allEnvironment :: [(String, FilePath)] | allEnvironment :: [(String, FilePath)] | ||||||
| allEnvironment = [ | allEnvironment = [ | ||||||
|     ("void",     "void.png"), |     ("void",     "void.png"), | ||||||
|  |     ("overlay",  "overlay.png"), | ||||||
|     ("tile",     "tile.png"), |     ("tile",     "tile.png"), | ||||||
|     ("wall",     "wall.png"), |     ("wall",     "wall.png"), | ||||||
|     ("entrance", "entrance.png"), |     ("entrance", "entrance.png"), | ||||||
|  | @ -47,7 +48,7 @@ allItems = [ | ||||||
| -- Map of all renders | -- Map of all renders | ||||||
| library :: [(String, Picture)] | library :: [(String, Picture)] | ||||||
| library = unknown:entities ++ environment ++ gui ++ items | library = unknown:entities ++ environment ++ gui ++ items | ||||||
|     where unknown     = ("unkown", renderPNG (assetsFolder ++ unknownImage)) |     where unknown     = ("unknown", renderPNG (assetsFolder ++ unknownImage)) | ||||||
|           entities    = map (\(f, s) -> (f, renderPNG (assetsFolder ++ "entities/" ++ s))) allEntities |           entities    = map (\(f, s) -> (f, renderPNG (assetsFolder ++ "entities/" ++ s))) allEntities | ||||||
|           environment = map (\(f, s) -> (f, renderPNG (assetsFolder ++ "environment/" ++ s))) allEnvironment |           environment = map (\(f, s) -> (f, renderPNG (assetsFolder ++ "environment/" ++ s))) allEnvironment | ||||||
|           gui         = [] |           gui         = [] | ||||||
|  | @ -72,3 +73,13 @@ setRenderPos :: Int -> Int -> Picture -> Picture | ||||||
| setRenderPos x y = translate floatX floatY | setRenderPos x y = translate floatX floatY | ||||||
|     where floatX = fromIntegral x * zoom * resolution |     where floatX = fromIntegral x * zoom * resolution | ||||||
|           floatY = fromIntegral y * zoom * resolution |           floatY = fromIntegral y * zoom * resolution | ||||||
|  | 
 | ||||||
|  | overlay :: Picture | ||||||
|  | overlay = setRenderPos offX offY $ pictures voids | ||||||
|  |     where voids = [setRenderPos x y void | x <- [0 .. width], y <- [0 .. height]] | ||||||
|  |           void  = getRender "overlay" | ||||||
|  |           intZoom = round zoom :: Int | ||||||
|  |           height = round $ 4320 / resolution / zoom | ||||||
|  |           width  = round $ 7680 / resolution / zoom | ||||||
|  |           offX   = negate (width `div` 2) | ||||||
|  |           offY   = negate (height `div` 2) | ||||||
							
								
								
									
										15
									
								
								lib/RPGEngine/Render/LvlSelect.hs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lib/RPGEngine/Render/LvlSelect.hs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | module RPGEngine.Render.LvlSelect | ||||||
|  | ( renderLvlList | ||||||
|  | ) where | ||||||
|  | 
 | ||||||
|  | import Graphics.Gloss ( Picture, pictures, translate, scale ) | ||||||
|  | import Graphics.Gloss.Data.Picture (blank, text) | ||||||
|  | import RPGEngine.Render.Core (resolution, zoom) | ||||||
|  | 
 | ||||||
|  | -- Render all level names, under each other. | ||||||
|  | renderLvlList :: [FilePath] -> Picture | ||||||
|  | renderLvlList list = pictures $ map render entries | ||||||
|  |     where entries           = zip [0::Int .. ] list | ||||||
|  |           render  (i, path) = scale zoomed zoomed $ translate 0 (offset i) $ text path | ||||||
|  |           zoomed            = 0.1 * zoom | ||||||
|  |           offset  i         = negate (2 * resolution * zoom * fromIntegral i) | ||||||
|  | @ -1,11 +1,17 @@ | ||||||
| module RPGEngine.Render.Player  | module RPGEngine.Render.Player  | ||||||
| ( renderPlayer | ( renderPlayer | ||||||
|  | , focusPlayer | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import RPGEngine.Data (Player(..)) | import RPGEngine.Data (Player(..), Game(..)) | ||||||
| 
 |  | ||||||
| import Graphics.Gloss (Picture, text) | import Graphics.Gloss (Picture, text) | ||||||
| import RPGEngine.Render.Core (getRender, setRenderPos) | import RPGEngine.Render.Core (getRender, setRenderPos, zoom, resolution) | ||||||
|  | import Graphics.Gloss.Data.Picture (translate) | ||||||
| 
 | 
 | ||||||
| renderPlayer :: Player -> Picture | renderPlayer :: Player -> Picture | ||||||
| renderPlayer Player{ position = (x, y) } = setRenderPos x y $ getRender "player" | renderPlayer Player{ position = (x, y) } = setRenderPos x y $ getRender "player" | ||||||
|  | 
 | ||||||
|  | focusPlayer :: Game -> Picture -> Picture | ||||||
|  | focusPlayer Game{ player = Player{ position = (x, y)}} = translate centerX centerY | ||||||
|  |     where centerX = resolution * zoom * fromIntegral (negate x) | ||||||
|  |           centerY = resolution * zoom * fromIntegral (negate y) | ||||||
|  | @ -8,6 +8,7 @@ library | ||||||
|   hs-source-dirs: lib |   hs-source-dirs: lib | ||||||
|   build-depends: |   build-depends: | ||||||
|     base >= 4.7 && <5, |     base >= 4.7 && <5, | ||||||
|  |     directory >= 1.3.6.0, | ||||||
|     gloss >= 1.11 && < 1.14, gloss-juicy >= 0.2.3, |     gloss >= 1.11 && < 1.14, gloss-juicy >= 0.2.3, | ||||||
|     parsec >= 3.1.15.1 |     parsec >= 3.1.15.1 | ||||||
|   exposed-modules: |   exposed-modules: | ||||||
|  | @ -20,6 +21,7 @@ library | ||||||
|     RPGEngine.Input |     RPGEngine.Input | ||||||
|     RPGEngine.Input.Core |     RPGEngine.Input.Core | ||||||
|     RPGEngine.Input.Level |     RPGEngine.Input.Level | ||||||
|  |     RPGEngine.Input.LvlSelect | ||||||
|     RPGEngine.Input.Player |     RPGEngine.Input.Player | ||||||
| 
 | 
 | ||||||
|     RPGEngine.Parse |     RPGEngine.Parse | ||||||
|  | @ -31,6 +33,7 @@ library | ||||||
|     RPGEngine.Render.Core |     RPGEngine.Render.Core | ||||||
|     RPGEngine.Render.GUI |     RPGEngine.Render.GUI | ||||||
|     RPGEngine.Render.Level |     RPGEngine.Render.Level | ||||||
|  |     RPGEngine.Render.LvlSelect | ||||||
|     RPGEngine.Render.Player |     RPGEngine.Render.Player | ||||||
| 
 | 
 | ||||||
| executable rpg-engine | executable rpg-engine | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								verslag.pdf
									
										
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								verslag.pdf
									
										
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in a new issue