C #, WPF - 1523
Не очень серьезно; это была в основном попытка, работало ли это на самом деле.
Здесь я использую ItemsControl (Menu, поскольку он короче) в WPF для отображения частиц с помощью привязки данных и шаблонов. Шаблон данных контролирует, как выглядят частицы (в данном случае простой круг), а привязка данных контролирует цвет и положение частиц.
Каждая частица имеет позицию, цвет и направление, которые обновляются таймером. Первоначально группа частиц генерируется в центре окна с (нормально распределенными) случайными направлениями. Эта коллекция получает привязку к данным для ItemsControl, который затем автоматически обрабатывает отображение частиц при каждом обновлении свойств. Частицы тянутся вниз под действием силы тяжести.
Это стало немного длинным, по общему признанию. Но, по крайней мере, это выглядит красиво:

Конечно, это можно сделать короче, пропустив:
- гравитация, заставляющая частицы равномерно расширяться во все стороны;
- нормальное распределение для начальных векторов, заставляющее частицы расширяться в разреженном «ящике»;
- изменение яркости, оставляя частицы черного цвета.
Я решил не делать этого в интересах эстетики. Это решение намного дольше, чем все остальное, независимо от того, Подход к привязке данных и шаблонам может быть элегантным, но он также довольно многословен по сравнению с простым обновлением растрового изображения. (Примечание: я сократил его до 1356 года, исключив все вышеперечисленное, но тогда это выглядит ужасно.)
Код распространяется в трех файлах, которые приведены здесь в отформатированном виде для удобочитаемости:
App.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" StartupUri="W.xaml"/>
W.xaml
<Window x:Class="W" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Menu Name="i">
<Menu.ItemTemplate>
<DataTemplate>
<Ellipse Width="2" Height="2" Fill="#000" Opacity="{Binding O}">
<Ellipse.RenderTransform>
<TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
</Ellipse.RenderTransform>
</Ellipse>
</DataTemplate>
</Menu.ItemTemplate>
<Menu.Template>
<ControlTemplate>
<ItemsPresenter/>
</ControlTemplate>
</Menu.Template>
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
</Menu>
</Window>
W.xaml.cs
using M = System.Math;
using T = System.Timers.Timer;
using System;
using System.ComponentModel;
partial class W
{
int a;
T t = new T(99);
public W()
{
InitializeComponent();
Height = Width = 500;
var r = new Random();
Func<double> n = () => 2 * (M.Sqrt(-2 * M.Log(r.NextDouble())) * M.Sin(6 * r.NextDouble()));
var l = new System.Collections.Generic.List<P>();
for (; a++ < 300; )
l.Add(new P { X = 250, Y = 250, f = n(), g = n() });
i.ItemsSource = l;
t.Elapsed += delegate
{
foreach (P x in l)
{
x.X += x.f;
x.Y += x.g += .2;
x.O = M.Max(1 - M.Sqrt(M.Pow(250 - x.X, 2) + M.Pow(250 - x.Y, 2)) / 250, 0);
}
};
t.Start();
}
}
class P : System.Windows.ContentElement, INotifyPropertyChanged
{
public double y, f, g;
public double X { get; set; }
public double O { get; set; }
public double Y
{
get { return y; }
set
{
y = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(""));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}