Last active
December 15, 2015 19:01
-
-
Save ptrelford/85195fd40b67984a9c1d to your computer and use it in GitHub Desktop.
Falling Snowflakes F# script using WriteableBitmapEx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#r "PresentationCore.dll" | |
#r "PresentationFramework.dll" | |
#r "WindowsBase.dll" | |
#r "WriteableBitmapEx.Wpf.dll" // requires custom version with DrawString | |
open System | |
open System.Windows | |
open System.Windows.Controls | |
open System.Windows.Media | |
open System.Windows.Media.Imaging | |
open System.Windows.Threading | |
let w, h = 800.0, 600.0 | |
let rnd = Random() | |
type flake = { mutable X:float; mutable Y:float; V:float; A:float } | |
let render (context:BitmapContext) flakes = | |
let bitmap = context.WriteableBitmap | |
bitmap.Clear() | |
let color = Colors.Gray | |
let fontSize = 16 | |
let font = PortableFontDesc("Arial", fontSize, true, false,false) | |
for flake in flakes do | |
bitmap.DrawString(int flake.X, int flake.Y, color, font, "F#") |> ignore | |
let draw (bitmap:WriteableBitmap) flakes = | |
using (bitmap.GetBitmapContext()) (fun context -> render context flakes) | |
let update (flakes:ResizeArray<_>) = | |
if (rnd.Next(5)= 0) then | |
let x, y = rnd.NextDouble() * w, -16.0 | |
let a = 45.0 + rnd.NextDouble() * 90.0 | |
let v = (0.5 + rnd.NextDouble())*2.0 | |
let flake = { X=x; Y=y; V=v; A=a } | |
flakes.Add(flake) | |
let onScreen, offScreen = flakes |> Seq.toList |> List.partition (fun flake -> flake.Y < h) | |
for flake in onScreen do | |
let r = flake.A * Math.PI / 180.0 | |
flake.X <- flake.X + ((cos r) * flake.V) | |
flake.Y <- flake.Y + ((sin r) * flake.V) | |
for flake in offScreen do | |
flakes.Remove(flake) |> ignore | |
do | |
let window = Window(SizeToContent = SizeToContent.WidthAndHeight) | |
let view = Image(Width=w,Height=h) | |
window.Content <- view | |
let dispatcherTimer = new DispatcherTimer() | |
dispatcherTimer.Interval <- new TimeSpan(0, 0, 0, 0, 15) | |
dispatcherTimer.Start() | |
let flakes = ResizeArray<_>() | |
window.Loaded.Add(fun _ -> | |
let bitmap = BitmapFactory.New(int w, int h) | |
view.Source <- bitmap | |
dispatcherTimer.Tick.Add(fun _ -> | |
update flakes | |
draw bitmap flakes | |
) | |
) | |
window.Show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment