Created
January 24, 2016 00:49
-
-
Save fredguth/cf37d01a9d7b4f0f1f9d to your computer and use it in GitHub Desktop.
Part4: 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 Random | |
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 = []} | |
newPill : Float -> Pill | |
newPill x = | |
{ defaultPill | pos = (x, hHeight)} | |
type Event = Tick (Time, (Int, Int)) | Add Pill | |
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} | |
gen = Random.float -hWidth hWidth | |
seed0 = Random.initialSeed 12 | |
-- Update | |
stepGame : Event -> Game -> Game | |
stepGame event ({player, pills} as g) = | |
case event of | |
Tick (t, mp) -> | |
let | |
hit pill= (vecLen (vecSub player.pos pill.pos)) < (player.rad + pill.rad) | |
unculled = List.filter (\{pos} -> snd pos > -hHeight) pills | |
untouched = List.filter (not << hit) unculled | |
in | |
{g|pills = List.map (stepPill t) untouched | |
,player = stepPlayer mp player} | |
Add p -> | |
{g|pills = p :: g.pills} | |
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 | |
-- Random Signal | |
type alias State = | |
{value: Float | |
,seed: Random.Seed} | |
state0 = State 0 (Random.initialSeed 42) | |
rstep : a -> State -> State | |
rstep _ state = | |
let (value', seed') = Random.generate gen state.seed | |
in State value' seed' | |
state : Signal Pill | |
state = | |
let | |
statesig = Signal.foldp rstep state0 (fps 1) | |
floatsig = Signal.map .value statesig | |
in | |
Signal.map newPill floatsig | |
event = | |
let t = Signal.map inSeconds (fps 30) | |
in | |
Signal.merge | |
(Signal.map Tick input) | |
(Signal.map Add state) | |
main = | |
Signal.map2 render | |
Window.dimensions | |
(foldp stepGame defaultGame event) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment