Untitled
unknown
plain_text
5 months ago
2.5 kB
4
Indexable
#r "nuget:DIKU.Canvas" open Canvas open Color open System open Asteroids.Vectors open Asteroids.RandomGenerator open Asteroids.Asteroids let width = 400 let height = 400 let center = (200.0, 200.0) let speed = 5.0 type Vec = float * float type Moth(pos: Vec, hdng: float) = member val pos = pos with get, set member val heading = hdng with get, set member this.draw = let x, y = this.pos filledEllipse yellow 5.0 5.0 |> translate x y let randomHeadingChange () = (Random().NextDouble() * 20.0 - 10.0) * Math.PI / 180.0 let wrap (x: float) (y: float) = let x' = if x < 0.0 then float width + x elif x > float width then x - float width else x let y' = if y < 0.0 then float height + y elif y > float height then y - float height else y (x', y') let move (pos: Vec) (heading: float) : Vec = let dx = Math.Cos(heading) * speed let dy = Math.Sin(heading) * speed let x, y = pos wrap (x + dx) (y + dy) let adjustHeadingToLight (pos: Vec) (target: Vec) : float = let x, y = pos let tx, ty = target Math.Atan2(ty - y, tx - x) type State = { lamp: bool; moths: Moth list } let initialMoths = [ Moth((5.0, 7.0), randomHeadingChange()) Moth((100.0, 100.0), randomHeadingChange()) Moth((50.0, 50.0), randomHeadingChange()) Moth((100.0, 50.0), randomHeadingChange()) Moth((50.0, 100.0), randomHeadingChange()) ] let draw (state: State) = let lamplight = if state.lamp then filledEllipse white 10.0 10.0 |> translate 200.0 200.0 else filledEllipse blue 10.0 10.0 |> translate 200.0 200.0 let mothDrawings = state.moths |> List.map (fun m -> m.draw) make (List.fold onto lamplight mothDrawings) let react (state: State) (ev: Event) : State option = match ev with | Key ' ' -> { state with lamp = not state.lamp } | TimerTick -> let target = (200.0, 200.0) let updatedMoths = state.moths |> List.map (fun m -> if state.lamp then m.heading <- adjustHeadingToLight m.pos target else m.heading <- m.heading + randomHeadingChange() m.pos <- move m.pos m.heading m) { state with moths = updatedMoths } | _ -> state |> Some let interval = Some 100 let initialstate = { lamp = false; moths = initialMoths } interact "moth sim" width height interval draw react initialstate
Editor is loading...
Leave a Comment