C# Falling Snowflakes on Desktop
Since it’s winter, I decided to write about how to create an application that makes snowflakes fall on your desktop. It’s just like snowing on your desktop, but the application is pretty basic so there’s space for improvements - I tried to write a short code so it’s easier to understand.
1.How to?
It’s quite simple:
- create a transparent form the same size as your desktop (you can still use other programs while this form is running)
- on this form you add about 40-50
PictureBox
es - each one will contain a snowflake image - finally you’ll have to use a timer to constantly change their position in the form, so the snowflakes will look like they’re slowly falling
The program presented in this tutorial has 2 parts:
- a class called snowflake
- the main program
2.Creating a Snowflake (class/image)
First, try drawing a white snowflake on a black background. Why? We’ll set the black background as transparent so only the true snowflake will be shown.
For my application I used the following image:
Next is the coding part: I created a separate class called snowflake (inherits from PictureBox class).
It contains 3 methods:
create()
- sets the PictureBox’s image and also its position in the form
move()
- creates a Timer that changes the snowflake’s position
t_tick()
- changes the snowflake’s position each 40ms
Note that using a class makes everything much easier.
The code for the class:
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
class snowflake : PictureBox
{
public snowflake()
{
create();
move();
}
Random r = new Random();
private void create()
{
//the line below sets a random point to the newly created snowflake
this.Location = new Point(r.Next(-Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Width), r.Next(-Screen.PrimaryScreen.Bounds.Height, Screen.PrimaryScreen.Bounds.Height));
//here we define the picturebox's size & the image
this.MinimumSize = new Size(7, 7);
this.Size = new Size(10, 10);
this.BackgroundImage = Image.FromFile("snowflake.jpg");
}
private void move()
{
//a snowflake has a timer that moves it on the screen
Timer t = new Timer();
t.Interval = 40;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
//moves the snowflake by constantly adding a values to its location
this.Location += new Size(1, 3);
//checking if the snowflake isn't going out of the visible area
//if it goes out we reset its location to a random one.
if (this.Location.X > Screen.PrimaryScreen.Bounds.Width || this.Location.Y > Screen.PrimaryScreen.Bounds.Height)
this.Location = new Point(r.Next(-Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Width), r.Next(-Screen.PrimaryScreen.Bounds.Height, Screen.PrimaryScreen.Bounds.Height));
}
}
3. Creating the main program
We want the main program (the form) to be transparent so we’ll make it black and setting its size equal to Screen.PrimaryScreen.Bounds.Size. After we must set the TransparencyKey to black.
Finally, we’ll create an array of snowflake(class), that will contain all the snowflakes we want. When an element from that array is instantiated, a new snowflake will spawn and will start falling.
Note: we must use a timer and not a repetitive structure when we create snowflakes - that’s because our instructions run on the UI Thread.
The sourcecode of the main program:
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
public partial class main : Form
{
public main()
{
InitializeComponent();
}
int i = 0;
Timer t;
snowflake[] snowflakes;
private void Form1_Load(object sender, EventArgs e)
{
this.TopMost = true; //makes snowflakes show over other programs
this.Size = Screen.PrimaryScreen.Bounds.Size + (new Size(20, 20));
this.Location = new Point(0, 0);
this.FormBorderStyle = FormBorderStyle.None; //also necessary so no borders will be shown
this.BackColor = Color.Black;
this.TransparencyKey = Color.Black; //mandatory, it makes black color transparent (won't be shown)
snowflakes = new snowflake[40]; //we want 40 snowflakes
t = new Timer(); //this timer creates a snowflake each second
t.Interval = 1000;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
if (i >= 40) //if we go over 40 snowflakes
{
t.Stop(); //we can stop creating new ones
return;
}
snowflakes[i] = new snowflake();
Controls.Add(snowflakes[i]); //each picturebox (snowflake) created must be added to the form
i++;
}
}
The Complete Code
Here’s the complete code:
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
88
89
90
using System;
using System.Drawing;
using System.Windows.Forms;
namespace FallingSnowFlakes
{
public partial class main : Form
{
public main()
{
InitializeComponent();
}
int i = 0;
Timer t;
snowflake[] snowflakes;
private void Form1_Load(object sender, EventArgs e)
{
this.TopMost = true;
this.Size = Screen.PrimaryScreen.Bounds.Size + (new Size(20, 20));
this.Location = new Point(0, 0);
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Black;
this.TransparencyKey = Color.Black;
snowflakes = new snowflake[40];
t = new Timer();
t.Interval = 1000;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
if (i >= 40)
{
t.Stop();
return;
}
snowflakes[i] = new snowflake();
Controls.Add(snowflakes[i]);
i++;
}
}
class snowflake : PictureBox
{
public snowflake()
{
create();
move();
}
Random r = new Random();
private void create()
{
this.Location = new Point(r.Next(-Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Width), r.Next(-Screen.PrimaryScreen.Bounds.Height, Screen.PrimaryScreen.Bounds.Height));
this.MinimumSize = new Size(7, 7);
this.Size = new Size(10, 10);
this.BackgroundImage = Image.FromFile("snowflake.jpg");
}
private void move()
{
//this.Location += new Size(1, 3);
Timer t = new Timer();
t.Interval = 40;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
this.Location += new Size(1, 3);
if (this.Location.X > Screen.PrimaryScreen.Bounds.Width || this.Location.Y > Screen.PrimaryScreen.Bounds.Height)
this.Location = new Point(r.Next(-Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Width), r.Next(-Screen.PrimaryScreen.Bounds.Height, Screen.PrimaryScreen.Bounds.Height));
}
}
}