Skip to content

Instantly share code, notes, and snippets.

@fredguth
Created January 19, 2016 17:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fredguth/72f8c8b8ae387c4c154b to your computer and use it in GitHub Desktop.
Save fredguth/72f8c8b8ae387c4c154b to your computer and use it in GitHub Desktop.
Part 3: Following Elm Tutorial
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