edge-0.8: Display.hs
{-# LANGUAGE ExistentialQuantification #-}
module Display (displayUniverse) where
import Animation
import Universe
import Lance
import Data.Maybe
import Moving
import Star
import Data.WrapAround
import Graphics.Gloss.Interface.IO.Game
import GHC.Float
import Combat
import AfterEffect ( AfterEffect ( AfterEffect ) )
import Unit
import Item
import ResourceTracker
data Displayable = forall a. (Locatable a, Animation a) => Displayable a
displayUniverse u
= let arena' = arena u in
let wmap = Universe.wrapMap arena' in
let pship = do lance' <- lance arena'
Just (image lance' undefined) in
let pship' = fromMaybe Blank pship in
let viewCenterWp = case lance arena' of
Just x -> Moving.center x
Nothing -> lastFocus arena' in
let displayables =
do (Displayable displayable)
<- map Displayable (stars arena')
++ map Displayable (asteroids arena')
++ [ Displayable a
| Projectile a <- lanceProjectiles arena'
++ unitProjectiles arena'
]
++ [ case effect of
AfterEffect a -> Displayable a
| effect <- afterFX arena' ]
++ [ Displayable a | SimpleUnit a <- simpleUnits arena' ]
++ [ Displayable a | SmartUnit a <- smartUnits arena' ]
++ [ Displayable a | a <- items arena' ]
let wp = Moving.center displayable in
let (x, y) = vectorRelation wmap wp viewCenterWp in
let pic = image displayable undefined in
[ Translate (double2Float x) (double2Float y) pic ] in
let deflectorBar' = Translate 65.0 370.0
(case lance arena' of
Just x -> deflectorBar (deflectorCharge x)
Nothing -> deflectorBar 0.8
) in
let deflectorText' = Translate (-65.0) 365.0 deflectorText in
let levelText = Translate 140.0 365.0
(Color white
(Scale 0.14 0.14
(Text ("level " ++ show (level u + 1))))) in
let livesText = Translate (-140.0) 365.0
(Color white
(Scale 0.14 0.14
(Text (show (lives u) ++ " lives")))) in
let godText = case lance arena' of
Nothing -> Blank
Just l -> if not (godMode l)
then Blank
else Translate (-20.0) 335.0
(Color yellow
(Scale 0.14 0.14
(Text "god mode"))) in
let integrityText = Translate (-500.0) 365.0
(Color white
(Scale 0.14 0.14
(Text "structural integrity"))) in
let integrityAssessment =
case lance arena' of
Nothing -> Blank
Just l -> if integrity l >= 3.0
then Color green (Text "optimal")
else if integrity l >= 2.0
then Color yellow (Text "light damage")
else Color red (Text "heavy damage") in
let integrityTextL2 = Translate (-330.0) 365.0
(Scale 0.14 0.14
integrityAssessment) in
let sP = Translate 450.0 330.0
(sensorPanel arena' (100.0, 100.0)) in
return $ Pictures $ displayables
++ [ pship'
, deflectorText'
, deflectorBar'
, levelText
, livesText
, sP
, godText
, integrityText
, integrityTextL2
, Translate (-400.0) 340.0 (inventoryDisplay
(lance arena')
(resourceTracker u))
]
inventoryDisplay :: Maybe Lance -> ResourceTracker -> Picture
inventoryDisplay mLance rt =
let spacing = 40.0 in
case mLance of
Nothing -> Blank
Just l -> let i = inventory l in
let pFourWay =
if not (i !! 0)
then Blank
else let p = fromMaybe Blank
(getImage rt "item-fourway.bmp") in
Translate ((-2.0) * spacing) 0.0 p in
let pCannon =
if not (i !! 1)
then Blank
else let p = fromMaybe Blank
(getImage rt "item-cannon.bmp") in
Translate ((-1.0) * spacing) 0.0 p in
let pSpread =
if not (i !! 2)
then Blank
else let p = fromMaybe Blank
(getImage rt "item-spread.bmp") in
p in
let pRapidFire =
if not (i !! 3)
then Blank
else let p = fromMaybe Blank
(getImage rt "item-rapidfire.bmp") in
Translate spacing 0.0 p in
let pNuke =
if not (i !! 4)
then Blank
else let p = fromMaybe Blank
(getImage rt "item-nuke.bmp") in
Translate (2.0 * spacing) 0.0 p in
let c = currentWeapon l in
let pSelected =
if c == 0
then Blank
else Translate
((fromIntegral c - 3.0) * spacing) 0.0
(Line [ (12.0, 13.0)
, (12.0, -12.0)
, (-13.0, -12.0)
, (-13.0, 13.0)
, (12.0, 13.0)
]) in
Pictures [ pFourWay
, pCannon, pSpread, pRapidFire, pNuke, pSelected]
sensorPanel :: Arena -> (Double, Double) -> Picture
sensorPanel arena (w, h) =
let wmap = wrapmap w h in
let (w', h') = (double2Float w, double2Float h) in
let (w'', h'') = (w' * 0.5, h' * 0.5) in
-- let outline = Color white (Line [ (w' * 0.5, h' * 0.5)
-- , (w' * 0.5, (-h') * 0.5)
-- , ((-w') * 0.5,(-h') * 0.5)
-- , ((-w') * 0.5, h' * 0.5)
-- , (w' * 0.5, h' * 0.5)
-- ]) in
let outline = Color white
(Pictures
[ (Line [ (w'' - 4.0, h'')
, (w'', h'')
, (w'', h'' - 4.0)
])
, (Line [ (w'', (-h'') + 4.0)
, (w'', (-h''))
, (w'' - 4.0, (-h''))
])
, (Line [ ((-w''), (-h'') + 4.0)
, ((-w''), (-h''))
, ((-w'') + 4.0, (-h''))
])
, (Line [ ((-w''), h'' - 4.0)
, ((-w''), h'')
, ((-w'') + 4.0, h'')
])
]) in
let focalPoint = Color white (Line [ (2.0, 0.0)
, (0.0, 2.0)
, (-2.0, 0.0)
, (0.0, -2.0)
, (2.0, 0.0)
]) in
let unitDots =
[ let cp = case lance arena of
Nothing -> lastFocus arena
Just l -> Moving.center l in
let (x, y) = vectorRelation wmap cp c in
Translate
(double2Float (-x))
(double2Float (-y))
(Color white (Polygon [ (2.0, 0.0)
, (0.0, 2.0)
, (-2.0, 0.0)
, (0.0, -2.0)
]))
| c <- map Moving.center (simpleUnits arena)
++ map Moving.center (smartUnits arena)
] in
let itemDots =
[ let cp = case lance arena of
Nothing -> lastFocus arena
Just l -> Moving.center l in
let (x, y) = vectorRelation wmap cp c in
Translate
(double2Float (-x))
(double2Float (-y))
(Color cyan (Polygon [ (2.0, 0.0)
, (0.0, 2.0)
, (-2.0, 0.0)
, (0.0, -2.0)
]))
| c <- map Moving.center (items arena)
] in
Pictures $ [ outline
, focalPoint
] ++ unitDots ++ itemDots
deflectorText = Color white (Scale 0.14 0.14 (Text "deflector"))
deflectorBar charge =
let width = 100.0 in
let height = 20.0 in
let outline = Line [ ((-width) / 2.0, height / 2.0)
, (width / 2.0, height / 2.0)
, (width / 2.0, (-height) / 2.0)
, ((-width) / 2.0, (-height) / 2.0)
, ((-width) / 2.0, height / 2.0)
] in
let portion = (double2Float charge - 0.8) / (2.0 - 0.8) in
let barColor = if charge < 1.0 then red
else white in
let bar = Polygon [ ((-width) / 2.0, height / 2.0)
, ((-width) / 2.0 + portion * width, height / 2.0)
, ((-width) / 2.0 + portion * width, (-height) / 2.0)
, ((-width) / 2.0, (-height) / 2.0)
] in
Pictures [Color barColor bar
, Color white outline
]