Skip to content

Instantly share code, notes, and snippets.

@ptrelford
Created December 15, 2015 22:40
Show Gist options
  • Save ptrelford/7f8044514e92f513179d to your computer and use it in GitHub Desktop.
Save ptrelford/7f8044514e92f513179d to your computer and use it in GitHub Desktop.
Snowflakes falling using MonoGame
#r "System.Drawing.dll"
#r "System.Windows.Forms.dll"
#r @"./packages/MonoGame.Framework.WindowsDX.3.4.0.459/lib/net40/MonoGame.Framework.dll"
open Microsoft.Xna.Framework
open Microsoft.Xna.Framework.Graphics
open Microsoft.Xna.Framework.Input
module Text =
open System.IO
open System.Drawing
open System.Windows.Forms
let toBitmapStream text =
use font = new Font(FontFamily.GenericMonospace, 16.0f)
let size = TextRenderer.MeasureText(text, font)
use bitmap = new Bitmap(size.Width, size.Height)
use g = Graphics.FromImage(bitmap)
g.SmoothingMode <- Drawing2D.SmoothingMode.AntiAlias
g.TextRenderingHint <- Text.TextRenderingHint.ClearTypeGridFit
g.Clear(Color.Transparent)
TextRenderer.DrawText(g, text, font, new Point(0, 0), Color.White)
let stream = new System.IO.MemoryStream()
bitmap.Save(stream, Imaging.ImageFormat.Png)
stream.Position <- 0L
stream
let w, h = 800.0, 600.0
let rnd = System.Random()
type flake = { mutable X:float; mutable Y:float; V:float; A:float }
type Snowflakes () as this =
inherit Game ()
let graphics = new GraphicsDeviceManager(this)
do graphics.PreferredBackBufferWidth <- 800
do graphics.PreferredBackBufferHeight <- 600
let mutable spriteBatch : SpriteBatch = null
let mutable textTexture : Texture2D = null
let flakes = ResizeArray<_>()
override this.LoadContent() =
spriteBatch <- new SpriteBatch(this.GraphicsDevice)
let textStream = Text.toBitmapStream "F#"
textTexture <- Texture2D.FromStream(this.GraphicsDevice, textStream)
override this.Update(gameTime) =
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 * System.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
override this.Draw(gameTime) =
this.GraphicsDevice.Clear Color.Black
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied)
let origin = System.Nullable(Vector2(float32 textTexture.Width/2.0f, float32 textTexture.Height/2.0f))
for flake in flakes do
let position = System.Nullable(Vector2(float32 flake.X,float32 flake.Y))
let r = flake.A * System.Math.PI / 180.0
spriteBatch.Draw(textTexture, position=position, rotation=float32 r)
spriteBatch.End()
do
use game = new Snowflakes()
game.Run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment