111 lines
No EOL
4.7 KiB
Haskell
111 lines
No EOL
4.7 KiB
Haskell
module RPGEngine.Render.Playing
|
|
( renderPlaying
|
|
) where
|
|
|
|
import RPGEngine.Render.Core (Renderer, getRender, setRenderPos, overlay)
|
|
|
|
import RPGEngine.Config (resolution, zoom, uizoom)
|
|
import RPGEngine.Data (State(..), Player (..), Game (..), Level (..), Layout, Physical (..), Item (..), Entity (..), HP)
|
|
|
|
import Data.Maybe ( fromJust )
|
|
import Graphics.Gloss ( pictures, Picture, translate, white )
|
|
import Graphics.Gloss.Data.Picture ( blank, text, color, scale )
|
|
|
|
------------------------------ Exported ------------------------------
|
|
|
|
renderPlaying :: Renderer State
|
|
renderPlaying Playing { level = lvl, player = player } = pictures [
|
|
renderLevel lvl,
|
|
renderPlayer player,
|
|
renderInventory player
|
|
]
|
|
renderPlaying _ = blank
|
|
|
|
------------------------------- Player -------------------------------
|
|
|
|
renderPlayer :: Renderer Player
|
|
renderPlayer Player{ position = (x, y), playerHp = playerHp } = move picture
|
|
where move = setRenderPos x y
|
|
picture = withHealthBar playerHp $ getRender "player"
|
|
|
|
-- Center the player in the middle of the screen.
|
|
-- Not in use at the moment, might be useful later.
|
|
focusPlayer :: Game -> Picture -> Picture
|
|
focusPlayer Game{ state = Playing{ player = Player{ position = (x, y) }}} = move
|
|
where move = translate centerX centerY
|
|
centerX = resolution * zoom * fromIntegral (negate x)
|
|
centerY = resolution * zoom * fromIntegral (negate y)
|
|
focusPlayer _ = id
|
|
|
|
------------------------------- Level --------------------------------
|
|
|
|
renderLevel :: Renderer Level
|
|
renderLevel Level{ layout = l, items = i, entities = e } = level
|
|
where level = pictures [void, layout, items, entities]
|
|
void = createVoid
|
|
layout = renderLayout l
|
|
items = renderItems i
|
|
entities = renderEntities e
|
|
|
|
renderLayout :: Layout -> Picture
|
|
renderLayout strips = pictures [setRenderPos 0 (count - y) (renderStrip (strips !! y)) | y <- [0 .. count]]
|
|
where count = length strips - 1
|
|
|
|
renderStrip :: [Physical] -> Picture
|
|
renderStrip list = pictures physicals
|
|
where physicals = [setRenderPos x 0 (image (list !! x)) | x <- [0 .. count]]
|
|
image Void = getRender "void"
|
|
image Walkable = getRender "tile"
|
|
image Blocked = getRender "wall"
|
|
image Entrance = pictures [getRender "tile", getRender "entrance"]
|
|
image Exit = pictures [getRender "tile", getRender "exit"]
|
|
count = length list - 1
|
|
|
|
createVoid :: Picture
|
|
createVoid = setRenderPos offX offY $ pictures voids
|
|
where voids = [setRenderPos x y void | x <- [0 .. width], y <- [0 .. height]]
|
|
void = getRender "void"
|
|
intZoom = round zoom :: Int
|
|
height = round $ 4320 / resolution / zoom
|
|
width = round $ 7680 / resolution / zoom
|
|
offX = negate (width `div` 2)
|
|
offY = negate (height `div` 2)
|
|
|
|
-------------------------- Items & Entities --------------------------
|
|
|
|
renderItems :: [Item] -> Picture
|
|
renderItems list = pictures $ map renderItem list
|
|
|
|
renderItem :: Item -> Picture
|
|
renderItem Item{ itemId = id, itemX = x, itemY = y} = setRenderPos x y image
|
|
where image = getRender id
|
|
|
|
renderEntities :: [Entity] -> Picture
|
|
renderEntities list = pictures $ map renderEntity list
|
|
|
|
renderEntity :: Entity -> Picture
|
|
renderEntity Entity{ entityId = id, entityX = x, entityY = y, entityHp = hp} = setRenderPos x y image
|
|
where image = withHealthBar hp $ getRender id
|
|
|
|
renderInventory :: Player -> Picture
|
|
renderInventory Player{ showInventory = False } = blank
|
|
renderInventory Player{ inventory = list } = pictures [overlay, title, items]
|
|
where title = translate 0 (offset (-1)) $ scale uizoom uizoom $ color white $ text "Inventory"
|
|
items = pictures $ zipWith (curry move) [0::Int ..] (map (getRender . itemId) list)
|
|
move (i, pic) = translate 0 (offset i) pic
|
|
offset i = negate (zoom * resolution * fromIntegral i)
|
|
|
|
withHealthBar :: HP -> Picture -> Picture
|
|
withHealthBar Nothing renderedEntity = renderedEntity
|
|
withHealthBar (Just hp) renderedEntity = pictures [renderedEntity, positionedBar]
|
|
where positionedBar = scale smaller smaller $ translate left up renderedBar
|
|
renderedBar = pictures [heart, counter]
|
|
heart = scale by by $ getRender "health"
|
|
counter = translate right down $ scale scaler scaler $ color white $ text $ show hp
|
|
left = negate $ uizoom * resolution * scaler
|
|
right = uizoom * resolution * 0.05
|
|
up = uizoom * resolution
|
|
down = negate $ resolution * uizoom * 0.15
|
|
smaller = resolution * uizoom
|
|
by = uizoom * 0.1
|
|
scaler = by * 0.5 |