Untitled
unknown
plain_text
a year ago
2.5 kB
5
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 initialstateEditor is loading...
Leave a Comment