simple-particles.elm

pasted by anders [options]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import Window
import Random

type Particle = {x:Float, y:Float, v:Float, dir:Float, age:Float}

centeredParticle = {x = 0.0, y = 0.0, v=1.0, dir=0.0, age=0}

transform : Float -> [Particle] -> [Particle]
transform randval prevState =
  case prevState of
    [] -> []
    x::xs -> if | .age x < 300 -> (transformOne randval x)::(transform (cos 100*randval) xs)
                | otherwise    ->                           (transform randval xs)
    
transformOne : Float -> Particle -> Particle
transformOne randval old =
  {old | x <- .x old + .v old * sin (.dir old),
         y <- .y old + .v old * cos (.dir old),
         v <- .v old * 0.992,
         dir <- .dir old + (0.5-randval)/10,
         age <- .age old + 1.0}
  
updateState : Float -> [Particle] -> [Particle]
updateState randval prevState =
  case prevState of
    [] -> [centeredParticle]
    x -> if | randval > 0.1 -> {centeredParticle | v <- randval*5, dir <- randval*31.4}::(transform randval x)
            | otherwise     -> (transform randval x)


grad = radial (0,0) 1 (0,0) 10
       [(0, rgba  255 255 255 0.5), (0.25, rgba  255 255 255 0.5), (1, rgba 255 255 255 0)]

sprite = circle 10 |> gradient grad


render (w, h) sprites =
  collage w h ((filled black (rect (toFloat w) (toFloat h))
                       )::map (\{x, y, age} -> sprite |> move (x, y) |> alpha ((300 - age)/300.0)) sprites)

main = render <~ Window.dimensions ~ foldp updateState [] (Random.float (foldp (+) 0 (fps 30)))