randomfox: (Default)
[personal profile] randomfox

screenshot

// firework - Fireworks graphics
// Author: Po Shan Cheah
// Last updated: August 18, 2003
// 
// Compile with: csc /doc:firework.xml /t:winexe firework.cs

namespace FireWork {

using System;
using System.Drawing;
using System.Windows.Forms;

/// <summary>Keeps track of one of the fireworks.</summary>
class FireWork {
    /// <summary>Maximum number of rays</summary>
    const int MaxRays = 10;

    /// <summary>Where the rays begin.</summary>
    double start;

    /// <summary>Where the rays end.</summary>
    double stop;

    /// <summary>Maximum length of the rays.</summary>
    double len;

    /// <summary>Current position in the iteration.</summary>
    double curpos;

    SolidBrush brush;

    /// <summary>Number of rays.</summary>
    int nrays;

    /// <summary>Center. X coord.</summary>
    int cx;
    
    /// <summary>Center. Y coord.</summary>
    int cy;

    /// <summary>Cached values of the sin of the angle of each
    /// ray.</summary>
    double[] sintab;

    /// <summary>Cached values of the cos of the angle of each
    /// ray.</summary>
    double[] costab;

    /// <summary>This determines how much faster each ray falls because of
    /// gravity.</summary>
    double descent;

    static Random rand = new Random();

    /// <summary>How much the fireworks should advance on each
    /// step.</summary>
    const double Step = 0.5;

    /// <summary>Advance by one position.</summary>
    /// <returns>False if this fireworks has gone away.</returns>
    public bool Update() {
	curpos += Step;
	return curpos <= stop + len;
    }

    /// <summary>Paint this fireworks</summary>
    /// <remarks>The fireworks should be drawn from max(curpos-len,start)
    /// to min(curpos,stop).</remarks>
    /// <param name="g">Graphics context</param>
    public void Paint(Graphics g) {
	double lower = Math.Max(curpos - len, start);
	double upper = Math.Min(curpos, stop);

	for (double pos = lower; pos < upper; pos += Step) {
	    // The quad squared component simulates some additional
	    // downward movement due to gravity.
	    double quad = descent * pos;
	    double quadsq = quad * quad;

	    for (int i = 0; i < nrays; ++i)
		g.FillRectangle(brush,
				(int) (cx + pos * costab[i]),
				(int) (cy + pos * sintab[i] + quadsq),
				1, 1);
	}
    } // Paint

    /// <summary>Initialize fireworks.</summary>
    /// <param name="xsize">Width of drawing area</param>
    /// <param name="ysize">Height of drawing area</param>
    public FireWork(int xsize, int ysize) {
	cx = rand.Next(xsize);
	cy = rand.Next(ysize);
	descent = rand.NextDouble() * 0.1 + 0.05;

	start = rand.NextDouble() * 10 + 5;
	stop = rand.NextDouble() * 50 + 50;
	len = rand.NextDouble() * 50 + 25;

	curpos = start;

	brush = new SolidBrush(Color.FromArgb(rand.Next(128, 256),
					      rand.Next(128, 256),
					      rand.Next(128, 256)));

	nrays = rand.Next(5, MaxRays + 1);

	double angleInc = 2 * Math.PI / nrays;
	double angle = rand.NextDouble() * angleInc;

	costab = new double[nrays];
	sintab = new double[nrays];
	for (int i = 0; i < nrays; ++i, angle += angleInc) {
	    costab[i] = Math.Cos(angle);
	    sintab[i] = Math.Sin(angle);
	}
    }
} // class FireWork

/// <summary>Tracks all the fireworks</summary>
class FireWorks : Form {
    /// <summary>Maximum number of fireworks.</summary>
    const int MaxFireWorks = 10;

    FireWork[] fireworks = new FireWork[MaxFireWorks];

    static Random rand = new Random();

    /// <summary>Timer event handler. Will be called periodically to update
    /// and redraw the fireworks.</summary>
    void Tick(Object o, EventArgs e) {
	// Update all fireworks.
	for (int i = 0; i < MaxFireWorks; ++i)
	    if (fireworks[i] != null)
		if (!fireworks[i].Update())
		    // If this fireworks has ended, remove it.
		    fireworks[i] = null;

	// Create a new fireworks randomly if there's an open slot.
	if (rand.Next(10) == 0)
	    for (int i = 0; i < MaxFireWorks; ++i)
		if (fireworks[i] == null) {
		    fireworks[i] = new FireWork(ClientRectangle.Width,
						ClientRectangle.Height);
		    break;
		}
	
	Invalidate();
	// Invalidate() by itself does not trigger a repaint.
	Update();
    } // Tick

    /// <summary>Paint event handler.</summary>
    protected override void OnPaint(PaintEventArgs e) {
	e.Graphics.Clear(Color.Black);
	foreach (FireWork fw in fireworks)
	    if (fw != null)
		fw.Paint(e.Graphics);
    }

    /// <summary>Milliseconds between each update.</summary>
    const int UpdateInterval = 25;

    FireWorks() {
	Text = "Fireworks";
	Name = "Fireworks";

	// Activate double-buffering.
	SetStyle(ControlStyles.UserPaint, true);
	SetStyle(ControlStyles.AllPaintingInWmPaint, true);
	SetStyle(ControlStyles.DoubleBuffer, true);

	ClientSize = new Size(700, 600);

	// Create a timer for updating the display.
	Timer timer = new Timer();
	timer.Tick += new EventHandler(Tick);
	timer.Interval = UpdateInterval;
	timer.Start();	
    }

    static int Main() {
	Application.Run(new FireWorks());
	return 0;
    }
} // class FireWorks

} // namespace FireWork

// The End

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

randomfox: (Default)
randomfox

November 2012

S M T W T F S
    123
45678910
11121314151617
18192021222324
25262728 2930 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 27th, 2025 12:48 am
Powered by Dreamwidth Studios