Created
January 19, 2016 17:38
-
-
Save fredguth/72f8c8b8ae387c4c154b to your computer and use it in GitHub Desktop.
Part 3: Following Elm Tutorial
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Graphics.Element exposing (..) | |
import Graphics.Collage exposing (..) | |
import Color exposing (..) | |
import Mouse | |
import Window | |
import Time exposing (..) | |
import Signal exposing (foldp) | |
--Model | |
(width, height) = (400, 400) | |
(hWidth, hHeight) = | |
(width/2, height/2) | |
type alias Vec = | |
(Float, Float) | |
type alias Pill = | |
{ pos : Vec | |
, vel : Vec | |
, rad : Float | |
, col : Color | |
} | |
type alias Game = | |
{ player : Pill | |
, pills : List Pill } | |
defaultGame = | |
{ player = defaultPlayer | |
, pills = List.map (\i -> {defaultPill|pos = (i*50, hHeight)}) [0..3]} | |
vecAdd : Vec -> Vec -> Vec | |
vecAdd (ax, ay) (bx, by) = | |
(ax + bx, ay + by) | |
vecSub : Vec -> Vec -> Vec | |
vecSub (ax, ay) (bx, by) = | |
(ax - bx, ay - by) | |
vecLen : Vec -> Float | |
vecLen (x, y) = | |
sqrt (x * x + y * y ) | |
vecMulS : Vec -> Time -> Vec | |
vecMulS (x, y) t = | |
(x*t, y*t) | |
defaultPill = | |
{ pos = (0,hHeight) | |
, vel = (0,-30) | |
, rad = 15 | |
, col = lightRed | |
} | |
defaultPlayer = | |
{defaultPill | pos = (0,0) | |
, col = black} | |
-- Update | |
stepGame : (Time, (Int, Int)) -> Game -> Game | |
stepGame (t,mp) ({player, pills} as g) = | |
let | |
hit pill= (vecLen (vecSub player.pos pill.pos)) < (player.rad + pill.rad) | |
untouched = List.filter (not << hit) pills | |
in | |
{g|pills = List.map (stepPill t) untouched | |
,player = stepPlayer mp player} | |
stepPill : Time -> Pill -> Pill | |
stepPill t p = | |
{p|pos = vecAdd p.pos (vecMulS p.vel t)} | |
-- in the future, maybe it is a good idea to have a type Player. | |
-- For now, we are using Pill as player type. | |
stepPlayer : (Int, Int) -> Pill -> Pill | |
stepPlayer (x, y) p = | |
{p|pos = (toFloat x, toFloat y)} | |
-- View | |
render : (Int, Int) -> Game -> Element | |
render (w,h) game = | |
let formPill {rad, col, pos} = circle rad | |
|> filled col | |
|> move pos | |
forms = formPill game.player ::List.map formPill game.pills | |
in | |
color lightGray <| container w h middle | |
<| color white | |
<| collage width height forms | |
-- Input | |
relativeMouse : (Int, Int) -> (Int, Int) -> (Int, Int) | |
relativeMouse (origin_x, origin_y) (x, y) = | |
(x-origin_x, origin_y - y) | |
center : (Int, Int) -> (Int, Int) | |
center (w,h) = | |
(w//2, h//2) | |
mouseSignal = | |
Signal.map2 relativeMouse (Signal.map center Window.dimensions) Mouse.position | |
input : Signal (Time, (Int, Int)) | |
input = | |
let time = Signal.map inSeconds (fps 30) | |
mouse = Signal.sampleOn time (Signal.map2 relativeMouse (Signal.map center Window.dimensions) Mouse.position) | |
in Signal.map2 (,) time mouse | |
main = | |
Signal.map2 render | |
Window.dimensions | |
(foldp stepGame defaultGame input) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment