Search code examples
c#winformsprocessing-ide

Purple Rain in C#


I'm Trying to make a purple rain in c# windows forms, just like the one in this video https://www.youtube.com/watch?v=KkyIDI6rQJI Hes using an ide called processing with java programming language.

Here's my code so far:

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace PurpleRain
{

public partial class MainForm : Form
{
    public MainForm()
    {

    }
    float x=150;
    float y=1;
    float yspeed=1;

    public void fall()
    {
        y=y+yspeed;
        if (y>=350)
        {
            y=0;
        }
    }
    public void show(float a,float b)
    {
        Graphics g;
        g = this.CreateGraphics();
        Pen myPen = new Pen(Color.MediumPurple);
        myPen.Width = 2;
        Pen myErase = new Pen(Color.Lavender);
        myErase.Width = 2;
        g.DrawLine(myErase, a, b-1, a, b+15);
        g.DrawLine(myPen, a, b, a, b+15);
    }

    void draw()
    {
        for (int i=0;i<10;i++){
            show(x,y);
            fall(); 
        }
    }   

    void Timer1Tick(object sender, EventArgs e)
    {
        draw();
    }
}

What this code does is draw a single purple line and make it fall to the bottom by erasing the previous drawn line. My problem is adding this purple line maybe a hundred to simulate a rain like in the video and having them start at random x and y positions as well. I've tried loops, list to no avail.


Solution

  • Not the best code, but it can be a good start for something better:

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            List<Drop> rain = new List<Drop> (); // keeps all drops in one place
            Random rnd = new Random ();          // for generating random numbers
    
    
            public Form1 ()
            {
                InitializeComponent ();
    
                for (int i = 0; i < 100; i++) // creates 100 drops at random position and with random speed
                    rain.Add (CreateRandomDrop ());
            }
    
    
            private Drop CreateRandomDrop ()
            {
                return new Drop // create drop with random position and speed
                {
                    Position = new PointF (rnd.Next (this.Width), rnd.Next (this.Height)),
                    YSpeed   = (float) rnd.NextDouble () * 3 + 2 // 2..5
                };
            }
    
    
            private void UpdateRain () // changes Y position for each drop (falling), also checks if a drop is outside Main form, if yes, resets position to 0
            {
                foreach (var drop in rain)
                {
                    drop.Fall ();
    
                    if (drop.Position.Y > this.Height)
                        drop.Position.Y = 0;
                }
            }
    
    
            private void RenderRain ()
            {
                using (var grp = this.CreateGraphics ()) // using will call IDisposable.Dispose
                {
                    grp.Clear (Color.DarkBlue);
    
                    foreach (var drop in rain)
                        grp.DrawLine (Pens.White, drop.Position, new PointF (drop.Position.X, drop.Position.Y + 3));
                }
            }
    
    
            private void timer1_Tick (object sender, EventArgs e)
            {
                UpdateRain ();
                RenderRain ();
            }
        }
    
    
        class Drop
        {
            public PointF Position;
            public float  YSpeed;
    
            public void Fall () => Position.Y += YSpeed;
        }
    }