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