6 people like it.
Like the snippet!
Flappy Bird clone using WinForms
Flappy bird clone script using WinForms, click the mouse or hit space to flap, no collision detection.
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:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
|
// Flappy bird prototype using Windows Forms
// Note: no collision detection
#if INTERACTIVE
#r "System.Drawing.dll"
#r "System.Windows.Forms.dll"
#endif
open System.IO
open System.Drawing
open System.Windows.Forms
open System.Net
/// Double-buffered form
type CompositedForm () =
inherit Form()
override this.CreateParams =
let cp = base.CreateParams
cp.ExStyle <- cp.ExStyle ||| 0x02000000
cp
/// Loads an image from a file or url
let load (file:string) (url:string) =
let path = Path.Combine(__SOURCE_DIRECTORY__, file)
if File.Exists path then Image.FromFile path
else
let request = HttpWebRequest.Create(url)
use response = request.GetResponse()
use stream = response.GetResponseStream()
Image.FromStream(stream)
let bg = load "bg.png" "http://flappycreator.com/default/bg.png"
let ground = load "ground.png" "http://flappycreator.com/default/ground.png"
let tube1 = load "tube1.png" "http://flappycreator.com/default/tube1.png"
let tube2 = load "tube2.png" "http://flappycreator.com/default/tube2.png"
let bird_sing = load "bird_sing.png" "http://flappycreator.com/default/bird_sing.png"
/// Bird type
type Bird = { X:float; Y:float; VY:float }
/// Respond to flap command
let flap (bird:Bird) = { bird with VY = - System.Math.PI }
/// Applies gravity to bird
let gravity (bird:Bird) = { bird with VY = bird.VY + 0.1 }
/// Applies physics to bird
let physics (bird:Bird) = { bird with Y = bird.Y + bird.VY }
/// Updates bird with gravity & physics
let update = gravity >> physics
/// Paints the game scene
let paint (graphics:Graphics) scroll level (flappy:Bird) =
let draw (image:Image) (x,y) =
graphics.DrawImage(image,x,y,image.Width,image.Height)
draw bg (0,0)
draw bird_sing (int flappy.X, int flappy.Y)
let drawTube (x,y) =
draw tube1 (x-scroll,-320+y)
draw tube2 (x-scroll,y+100)
for (x,y) in level do drawTube (x,y)
draw ground (0,340)
/// Generates the level's tube positions
let generateLevel n =
let rand = System.Random()
[for i in 1..n -> 50+(i*150), 32+rand.Next(160)]
let level = generateLevel 10
let scroll = ref 0
let flappy = ref { X = 30.0; Y = 150.0; VY = 0.0}
let form = new CompositedForm(Text="Flap me",Width=288,Height=440)
form.Paint.Add(fun args ->
flappy := update !flappy
paint args.Graphics !scroll level !flappy;
incr scroll)
let flapme () = flappy := flap !flappy
// Respond to mouse clicks
form.Click.Add(fun args -> flapme())
// Respond to space key
form.KeyDown.Add(fun args -> if args.KeyCode = Keys.Space then flapme())
// Show form
form.Show()
// Update form asynchronously every 18ms
async {
while true do
do! Async.Sleep(18)
form.Invalidate()
} |> Async.StartImmediate
|
namespace System
namespace System.IO
namespace System.Drawing
namespace System.Windows
namespace System.Net
Multiple items
type CompositedForm =
inherit obj
new : unit -> CompositedForm
override CreateParams : 'a
Double-buffered form
--------------------
new : unit -> CompositedForm
val load : file:string -> url:string -> 'a
Loads an image from a file or url
val file : string
Multiple items
val string : value:'T -> string
--------------------
type string = System.String
val url : string
val path : string
type Path =
static val DirectorySeparatorChar : char
static val AltDirectorySeparatorChar : char
static val VolumeSeparatorChar : char
static val PathSeparator : char
static val InvalidPathChars : char[]
static member ChangeExtension : path:string * extension:string -> string
static member Combine : [<ParamArray>] paths:string[] -> string + 3 overloads
static member EndsInDirectorySeparator : path:ReadOnlySpan<char> -> bool + 1 overload
static member GetDirectoryName : path:string -> string + 1 overload
static member GetExtension : path:string -> string + 1 overload
...
Path.Combine([<System.ParamArray>] paths: string []) : string
Path.Combine(path1: string, path2: string) : string
Path.Combine(path1: string, path2: string, path3: string) : string
Path.Combine(path1: string, path2: string, path3: string, path4: string) : string
type File =
static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
static member AppendAllLinesAsync : path:string * contents:IEnumerable<string> * ?cancellationToken:CancellationToken -> Task + 1 overload
static member AppendAllText : path:string * contents:string -> unit + 1 overload
static member AppendAllTextAsync : path:string * contents:string * ?cancellationToken:CancellationToken -> Task + 1 overload
static member AppendText : path:string -> StreamWriter
static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
static member Create : path:string -> FileStream + 2 overloads
static member CreateText : path:string -> StreamWriter
static member Decrypt : path:string -> unit
static member Delete : path:string -> unit
...
File.Exists(path: string) : bool
val request : WebRequest
Multiple items
type HttpWebRequest =
inherit WebRequest
new : unit -> HttpWebRequest
member Abort : unit -> unit
member Accept : string with get, set
member AddRange : range:int -> unit + 7 overloads
member Address : Uri
member AllowAutoRedirect : bool with get, set
member AllowReadStreamBuffering : bool with get, set
member AllowWriteStreamBuffering : bool with get, set
member AutomaticDecompression : DecompressionMethods with get, set
member BeginGetRequestStream : callback:AsyncCallback * state:obj -> IAsyncResult
...
--------------------
HttpWebRequest() : HttpWebRequest
WebRequest.Create(requestUri: System.Uri) : WebRequest
WebRequest.Create(requestUriString: string) : WebRequest
val response : WebResponse
val stream : Stream
val bg : obj
val ground : obj
val tube1 : obj
val tube2 : obj
val bird_sing : obj
type Bird =
{ X: float
Y: float
VY: float }
Bird type
Bird.X: float
Multiple items
val float : value:'T -> float (requires member op_Explicit)
--------------------
type float = System.Double
--------------------
type float<'Measure> = float
Bird.Y: float
Bird.VY: float
val flap : bird:Bird -> Bird
Respond to flap command
val bird : Bird
type Math =
static val E : float
static val PI : float
static member Abs : value:float -> float + 6 overloads
static member Acos : d:float -> float
static member Acosh : d:float -> float
static member Asin : d:float -> float
static member Asinh : d:float -> float
static member Atan : d:float -> float
static member Atan2 : y:float * x:float -> float
static member Atanh : d:float -> float
...
field System.Math.PI: float = 3.14159265359
val gravity : bird:Bird -> Bird
Applies gravity to bird
val physics : bird:Bird -> Bird
Applies physics to bird
val update : (Bird -> Bird)
Updates bird with gravity & physics
val paint : graphics:'a -> scroll:int -> level:seq<int * int> -> flappy:Bird -> 'b
Paints the game scene
val graphics : 'a
val scroll : int
val level : seq<int * int>
val flappy : Bird
val draw : ('c -> 'd * 'e -> 'f)
val image : 'c
val x : 'd
val y : 'e
Multiple items
val int : value:'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val drawTube : (int * int -> 'c)
val x : int
val y : int
val generateLevel : n:int -> (int * int) list
Generates the level's tube positions
val n : int
val rand : System.Random
Multiple items
type Random =
new : unit -> Random + 1 overload
member Next : unit -> int + 2 overloads
member NextBytes : buffer:byte[] -> unit + 1 overload
member NextDouble : unit -> float
--------------------
System.Random() : System.Random
System.Random(Seed: int) : System.Random
val i : int
val level : (int * int) list
val scroll : int ref
Multiple items
val ref : value:'T -> 'T ref
--------------------
type 'T ref = Ref<'T>
val flappy : Bird ref
val form : CompositedForm
val incr : cell:int ref -> unit
val flapme : unit -> unit
val async : AsyncBuilder
Multiple items
type Async =
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
...
--------------------
type Async<'T> =
static member Async.Sleep : millisecondsDueTime:int -> Async<unit>
static member Async.StartImmediate : computation:Async<unit> * ?cancellationToken:System.Threading.CancellationToken -> unit
More information