#3 #2 Player render and movement

This commit is contained in:
Tibo De Peuter 2022-12-20 22:52:06 +01:00
parent de02c7113f
commit fb4bc5bb36
12 changed files with 158 additions and 9 deletions

BIN
assets/entities/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/unkown.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

View file

@ -7,7 +7,8 @@ data Game = Game {
-- Current state of the game
state :: State,
playing :: Level,
levels :: [Level]
levels :: [Level],
player :: Player
}
------------------------------- Level --------------------------------
@ -30,9 +31,13 @@ data Physical = Void
------------------------------- Player -------------------------------
type X = Int
type Y = Int
data Player = Player {
playerHp :: Maybe Int,
inventory :: [Item]
inventory :: [Item],
coord :: (X, Y)
} deriving (Eq, Show)
instance Living Player where

View file

@ -18,9 +18,10 @@ defaultEntity = Entity {
-- Initialize the game
initGame :: Game
initGame = Game {
state = defaultState,
state = defaultState,
playing = defaultLevel,
levels = [defaultLevel]
levels = [defaultLevel],
player = defaultPlayer
}
defaultItem :: Item
@ -51,8 +52,9 @@ defaultLevel = Level {
defaultPlayer :: Player
defaultPlayer = Player {
playerHp = Prelude.Nothing, -- Compares to infinity
inventory = []
playerHp = Prelude.Nothing, -- Compares to infinity
inventory = [],
coord = (0, 0)
}
-- Default state of the game, Menu

View file

@ -7,6 +7,7 @@ module RPGEngine.Input
import RPGEngine.Data
import RPGEngine.Data.State
import RPGEngine.Input.Core
import RPGEngine.Input.Player
import Graphics.Gloss.Interface.IO.Game
@ -22,7 +23,19 @@ handleAllInput ev g = handleAnyKey setNextState ev g
-- Input for 'Playing' state
handlePlayInputs :: InputHandler Game
handlePlayInputs = composeInputHandlers [
handleKey (Char 'p') (\game -> game{ state = Pause })
-- Pause the game
handleKey (Char 'p') (\game -> game{ state = Pause }),
-- 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
]
-- Go to the next stage of the Game

View file

@ -0,0 +1,19 @@
module RPGEngine.Input.Player
( movePlayer
) where
import RPGEngine.Data (Game(..), Direction(..), Player(..), X, Y)
movePlayer :: Direction -> Game -> Game
movePlayer dir g@Game{ player = p@Player{ coord = (x, y) }} = newGame
where newGame = g{ player = newPlayer }
newPlayer = p{ coord = newCoord }
newCoord = (x + xD, y + yD)
(xD, yD) = diffs dir
diffs :: Direction -> (X, Y)
diffs North = (0, 1)
diffs East = (1, 0)
diffs South = (0, -1)
diffs West = (-1, 0)
diffs Center = (0, 0)

View file

@ -8,7 +8,15 @@ module RPGEngine.Render
) where
import RPGEngine.Data
( State(..),
Game(..) )
import RPGEngine.Render.Level
( renderLevel )
import Graphics.Gloss
( white, pictures, text, Display(InWindow), Color, Picture )
import RPGEngine.Render.Player (renderPlayer)
import RPGEngine.Render.GUI (renderGUI)
----------------------------- Constants ------------------------------
@ -36,9 +44,12 @@ render g@Game{ state = Lose } = renderLose g
renderMenu :: Game -> Picture
renderMenu _ = text "[Press any key to start]"
-- TODO
renderPlaying :: Game -> Picture
renderPlaying _ = text "Playing"
renderPlaying g@Game{ playing = lvl, player = player } = pictures [
renderLevel lvl,
renderPlayer player,
renderGUI g
]
-- TODO
renderPause :: Game -> Picture

View file

@ -0,0 +1,63 @@
module RPGEngine.Render.Core where
import Graphics.Gloss ( Picture, translate )
import GHC.IO (unsafePerformIO)
import Graphics.Gloss.Juicy (loadJuicyPNG)
import Data.Maybe (fromJust)
import Graphics.Gloss.Data.Picture (scale)
----------------------------- Constants ------------------------------
-- Default scale
zoom :: Float
zoom = 5.0
-- Resolution of the texture
resolution :: Float
resolution = 16
assetsFolder :: FilePath
assetsFolder = "assets/"
unknownImage :: FilePath
unknownImage = "unkown.png"
allEntities :: [(String, FilePath)]
allEntities = [
("player", "player.png"),
("door", "door.png")
]
allItems :: [(String, FilePath)]
allItems = [
("dagger", "dagger.png"),
("key", "key.png" )
]
-- Map of all renders
library :: [(String, Picture)]
library = unknown:entities ++ environment ++ gui ++ items
where unknown = ("unkown", renderPNG (assetsFolder ++ unknownImage))
entities = map (\(f, s) -> (f, renderPNG (assetsFolder ++ "entities/" ++ s))) allEntities
environment = []
gui = []
items = map (\(f, s) -> (f, renderPNG (assetsFolder ++ "items/" ++ s))) allItems
----------------------------------------------------------------------
-- Turn a path to a .png file into a Picture.
renderPNG :: FilePath -> Picture
renderPNG path = scale zoom zoom $ fromJust $ unsafePerformIO $ loadJuicyPNG path
-- Retrieve an image from the library. If the library does not contain
-- the requested image, a default is returned.
getRender :: String -> Picture
getRender id = get filtered
where filtered = filter ((== id) . fst) library
get [] = snd $ head library
get ((_, res):_) = res
setRenderPos :: Int -> Int -> Picture -> Picture
setRenderPos x y = translate floatX floatY
where floatX = fromIntegral x * zoom * resolution
floatY = fromIntegral y * zoom * resolution

View file

@ -0,0 +1,10 @@
module RPGEngine.Render.GUI
( renderGUI
) where
import RPGEngine.Data (Game)
import Graphics.Gloss (Picture, blank)
-- TODO
renderGUI :: Game -> Picture
renderGUI _ = blank

View file

@ -0,0 +1,10 @@
module RPGEngine.Render.Level
( renderLevel
) where
import Graphics.Gloss
import RPGEngine.Data
-- TODO
renderLevel :: Level -> Picture
renderLevel _ = text "Level"

View file

@ -0,0 +1,11 @@
module RPGEngine.Render.Player
( renderPlayer
) where
import RPGEngine.Data (Player(..))
import Graphics.Gloss (Picture, text)
import RPGEngine.Render.Core (getRender, setRenderPos)
renderPlayer :: Player -> Picture
renderPlayer Player{ coord = (x, y) } = setRenderPos x y $ getRender "player"

View file

@ -19,6 +19,7 @@ library
RPGEngine.Input
RPGEngine.Input.Core
RPGEngine.Input.Player
RPGEngine.Parse
RPGEngine.Parse.Core
@ -26,6 +27,10 @@ library
RPGEngine.Parse.StructElement
RPGEngine.Render
RPGEngine.Render.Core
RPGEngine.Render.GUI
RPGEngine.Render.Level
RPGEngine.Render.Player
executable rpg-engine
main-is: Main.hs