gloss-game-0.3.0.0: examples/bounce/Main.hs
-- Very simple example of bouncing and jumping character.
import Data.Maybe
import Graphics.Gloss.Game
creeperSprite :: Picture
creeperSprite = bmp "Creeper.bmp"
platformSprite :: Picture
platformSprite = bmp "Platform.bmp"
gravitationalConstant :: Float
gravitationalConstant = -0.5
creeperWidth, creeperHeight :: Float
(_, (creeperWidth, creeperHeight)) = boundingBox (scale 0.5 0.5 creeperSprite)
platformPos :: Point
platformPos = (-200, -150)
platformWidth, platformHeight :: Float
(_, (platformWidth, platformHeight)) = boundingBox (scale 0.5 0.5 platformSprite)
data World = World {creeperPos :: Point, creeperVelocity :: Float}
initialWorld :: World
initialWorld = World {creeperPos = (-200, 0), creeperVelocity = 0}
main = play (InWindow "Bouncy Creeper" (600, 400) (50, 50)) white 30 initialWorld draw handle [applyVelocity, applyGravity]
where
draw (World {creeperPos = (x, y)})
= pictures [ translate x y (scale 0.5 0.5 creeperSprite)
, translate (fst platformPos) (snd platformPos) (scale 0.5 0.5 platformSprite)
]
handle (EventKey (Char 'a') Down _ _) world = world {creeperPos = moveX (creeperPos world) (-10)}
handle (EventKey (Char 'd') Down _ _) world = world {creeperPos = moveX (creeperPos world) 10}
handle (EventKey (SpecialKey KeySpace) Down _ _) world = world {creeperVelocity = 10}
handle _event world = world
applyVelocity _ world
= world {creeperPos = moveY (creeperPos world) (creeperVelocity world)}
applyGravity _ world
| onTheFloor world
|| onThePlatform world = world {creeperVelocity = creeperVelocity world * (-0.5)}
| otherwise = world {creeperVelocity = creeperVelocity world + gravitationalConstant}
onTheFloor world = snd (creeperPos world) <= (-200) + creeperHeight / 2
onThePlatform world = snd (creeperPos world) <= snd platformPos + creeperHeight / 2 + platformHeight / 2
&& fst (creeperPos world) + creeperWidth / 2 > fst platformPos - platformWidth / 2
&& fst (creeperPos world) - creeperWidth / 2 < fst platformPos + platformWidth / 2
moveX :: Point -> Float -> Point
moveX (x, y) offset = if x + offset > 300 - creeperWidth / 2
then (300 - creeperWidth / 2, y)
else if x + offset < (-300) + creeperWidth / 2
then ((-300) + creeperWidth / 2, y)
else (x + offset, y)
moveY :: Point -> Float -> Point
moveY (x, y) offset = if y + offset > 200 - creeperHeight / 2
then (x, 200 - creeperHeight / 2)
else if y + offset < (-200) + creeperHeight / 2
then (x, (-200) + creeperHeight / 2)
else if y + offset < snd platformPos + creeperHeight / 2 + platformHeight / 2
&& x + creeperWidth / 2 > fst platformPos - platformWidth / 2
&& x - creeperWidth / 2 < fst platformPos + platformWidth / 2
then (x, snd platformPos + creeperHeight / 2 + platformHeight / 2)
else (x, y + offset)