Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Graphics.Element exposing (..)
- import Graphics.Collage exposing (..)
- import Mouse
- import Color exposing (..)
- import Time
- import Keyboard
- type alias Vec2 = (Float, Float)
- type alias Particle = {pos: Vec2, vel: Vec2, acc: Vec2, color: Color}
- type alias Model = List Particle
- type Action = Step Float Vec2 | AddParticle Vec2 | Explode Vec2
- model: Model
- model = []
- scene: Model -> Element
- scene model =
- collage (fst size) (snd size) (List.map renderParticle model)
- newParticle: Vec2 -> Color -> Particle
- newParticle pos color =
- {pos = pos, vel = (0,0), acc = (1,0), color = (hsla (fst pos) (snd pos) 0.6 0.7)}
- clickPosition: Signal (Float, Float)
- clickPosition = Signal.sampleOn Mouse.clicks realMouse
- renderParticle: Particle -> Form
- renderParticle particle =
- circle 5
- |> filled particle.color
- |> move particle.pos
- size = (500, 500)
- mouseToScene (w,h) (x,y) =
- (toFloat x - w/2, h/2 - toFloat y)
- addVec: Vec2 -> Vec2 -> Vec2
- addVec (a,b) (c,d) = (a + c, b + d)
- mulVec: Vec2 -> Float -> Vec2
- mulVec (a,b) m = (a*m, b*m)
- subVec: Vec2 -> Vec2 -> Vec2
- subVec a b = addVec a (mulVec b -1)
- gravity: Float -> Particle -> Particle
- gravity dt p =
- -- {p | acc = (fst p.acc, -9.8)}
- {p | acc = (fst p.acc, -55.8)}
- physics: Float -> Particle -> Particle
- physics dt p =
- {p | pos = addVec p.pos (mulVec p.vel (1/dt)), vel = addVec p.vel (mulVec p.acc (1/dt)), acc = (0,0)}
- explode: Vec2 -> Model -> Model
- explode pos model =
- List.map (\p -> {p | vel = mulVec (subVec p.pos pos) 2}) model
- slowDown: Particle -> Particle
- slowDown p = {p | vel = mulVec p.vel 0.99}
- mousePull pos dt p =
- {p | acc = addVec p.acc (subVec pos p.pos)}
- stepUpdate dt pos model =
- List.map (\m -> m |> physics dt |> gravity dt |> mousePull pos dt |> slowDown) model
- addParticle: Vec2 -> Model -> Model
- addParticle clickPos model =
- (newParticle clickPos red) :: model
- realMouse = Signal.map (mouseToScene size) Mouse.position
- spaceLocation: Signal Vec2
- spaceLocation = Signal.sampleOn Keyboard.space realMouse
- --timeAndPosition: Signal Step Float Vec2
- timeAndPosition =
- Signal.map2 Step (Time.fps 50) realMouse
- input: Signal Action
- input =
- Signal.mergeMany [
- (Signal.sampleOn (Time.fps 50) timeAndPosition),
- (Signal.map AddParticle clickPosition),
- (Signal.map Explode spaceLocation)]
- update: Action -> Model -> Model
- update action model =
- case action of
- AddParticle pos -> addParticle pos model
- Step dt pos -> stepUpdate dt pos model
- Explode pos -> explode pos model
- modelSignal: Signal Model
- modelSignal =
- Signal.foldp update model input
- main : Signal Element
- main =
- Signal.map scene modelSignal
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement