用C#实现的黑客帝国中的字符雨特效

在做一个WinForm登录框时,突然想到,如果有黑客帝国中字符雨的特效做背景,那应该蛮Cool的,所以就有了如下代码,随意写的,有点乱。

 

     public   partial   class  CharacterRain : Component
ExpandedBlockStart.gifContractedBlock.gif    
{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 必需的设计器变量。
        
/// 

        private System.ComponentModel.IContainer components = null;

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**////  
        
/// 清理所有正在使用的资源。
        
/// 

        
/// 如果应释放托管资源,为 true;否则为 false。

        protected override void Dispose(bool disposing)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (RainThread != null && RainThread.IsAlive)
                Stop();

            
if (disposing && (components != null))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                components.Dispose();
            }

            
base.Dispose(disposing);
        }


ContractedSubBlock.gifExpandedSubBlockStart.gif        
组件设计器生成的代码#region 组件设计器生成的代码

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 设计器支持所需的方法 - 不要
        
/// 使用代码编辑器修改此方法的内容。
        
/// 

        private void InitializeComponent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            components 
= new System.ComponentModel.Container();
        }


        
#endregion


        
public CharacterRain()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Initialize();

            InitializeComponent();
        }


        
public CharacterRain(IContainer container)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Initialize();

            container.Add(
this);

            InitializeComponent();
        }


        
private object BMPLock = new object();
        
private Bitmap BMP;
        
private Graphics Graph;

        
private void Initialize()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.DrawRainEvent = new EventHandler(CharacterRainPanel_DrawRainEvent);
            OnPaint 
= new PaintEventHandler(ShowWindow_Paint);
        }


        
private PaintEventHandler OnPaint;

ExpandedSubBlockStart.gifContractedSubBlock.gif        
private char[] CHARACTERS = '`''1''2''3''4''5''6''7''8''9''0''-''=''\\''q''w''e''r''t''y''u''i''o''p''['']''a''s''d''f''g''h''j''k''l'';''\'''z''x''c''v''b''n''m'',''.''/''~''!''@''#''$''%''^''&''*''('')''_''+''|''Q''W''E''R''T''Y''U''I''O''P''{''}''A''S''D''F''G''H''J''K''L'':''"', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?' };
        private static readonly Random Rand = new Random();

        
private Control _ShowWindow = null;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置用于显示字符雨的窗口(或控件)
        
/// 

        public Control ShowWindow
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _ShowWindow; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (_ShowWindow != null)
                    _ShowWindow.Paint 
-= OnPaint;

                _ShowWindow 
= value;

                
if (_ShowWindow != null)
                    _ShowWindow.Paint 
+= OnPaint;
            }

        }


        
void ShowWindow_Paint(object sender, PaintEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//Paint();
            if (BMP != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
lock (BMPLock)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
//e.Graphics.Clear(_ShowWindow.BackColor);
                    try
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        e.Graphics.DrawImage(BMP, 
00);
                    }

                    
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                    }

                }

            }

        }


        
private string _RainCharacters = "`1234567890-=\\qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?";
ExpandedSubBlockStart.gifContractedSubBlock.gif
        /**//// 
        
/// 获取、设置字符雨中可能出现的字符
        
/// 

        public string RainCharacters
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _RainCharacters; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (string.IsNullOrEmpty(value))
                    value 
= "`1234567890-=\\qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?";
                _RainCharacters = value;
                CHARACTERS 
= value.ToCharArray();
            }

        }


        
private Color _RainHeadColor = Color.Lime;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置字符雨头的颜色
        
/// 

        public Color RainHeadColor
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _RainHeadColor; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
                    _RainHeadColor 
= value;
                
else
                    
throw new Exception("运行中不可以更改颜色。");
            }

        }



        
private Color _RainBodyColor = Color.Green;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置字符雨体的颜色
        
/// 

        public Color RainBodyColor
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _RainBodyColor; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
                    _RainBodyColor 
= value;
                
else
                    
throw new Exception("运行中不可以更改颜色。");
            }

        }


        
private Color _RainTailColor = Color.DarkGreen;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置字符雨体的颜色
        
/// 

        public Color RainTailColor
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _RainTailColor; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
                    _RainTailColor 
= value;
                
else
                    
throw new Exception("运行中不可以更改颜色。");
            }

        }



        
private Font _RainFont = new Font(new FontFamily("Consolas"), 12);
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置字符雨的字体样式
        
/// 

        public Font RainFont
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _RainFont; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
                    _RainFont 
= value;
                
else
                    
throw new Exception("运行中不可以更改字体。");
            }

        }


        
private int _StreamsCount = 100;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置字符雨的数量
        
/// 

        public int StreamsCount
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _StreamsCount; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
                    _StreamsCount 
= value;
                
else
                    
throw new Exception("运行中不可以更改数量。");
            }

        }


        
private int _MaxLength = 50;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置每个雨滴的最大字符数
        
/// 

        public int MaxLength
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _MaxLength; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (value >= _MinLength)
                        _MaxLength 
= value;
                    
else
                        
throw new Exception("最大字符数不能小于最小字符数。");
                }

                
else
                    
throw new Exception("运行中不可以更改数量。");
            }

        }


        
private int _MinLength = 20;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 获取、设置每个雨滴的最小字符数
        
/// 

        public int MinLength
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _MinLength; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!Running)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (value <= _MaxLength)
                        _MinLength 
= value;
                    
else
                        
throw new Exception("最小字符数不能大于最大字符数。");
                }

                
else
                    
throw new Exception("运行中不可以更改数量。");
            }

        }


        
public bool Running
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return RainThread != null && RainThread.IsAlive; }
        }


        
private Thread RainThread;
        
private bool RUN;
        
private bool PAUSE;
        
private Brush BackBrush = null;

        
private Brush RainHeadBrush = null;
        
private Brush RainBodyBrush = null;
        
private Brush RainTailBrush = null;

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 开始显示字符雨
        
/// 

        public void Start()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (_ShowWindow == null)
                
throw new Exception("没有用于显示的窗口(或控件)");

            
if (!Running)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                RainThread 
= new Thread(new ParameterizedThreadStart(RainProcess));
                RUN 
= true;
                PAUSE 
= false;
                Ready();
                RainThread.Start();
            }

        }


        
private void Ready()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Rain.RainFont 
= _RainFont;
            Rain.RainHeadColor 
= _RainHeadColor;
            Rain.RainBodyColor 
= _RainBodyColor;
            Rain.RainTailColor 
= _RainTailColor;
            Rain.BackColor 
= _ShowWindow.BackColor;

            
if (RainHeadBrush != null)
                RainHeadBrush.Dispose();
            
if (RainBodyBrush != null)
                RainBodyBrush.Dispose();
            
if (RainTailBrush != null)
                RainTailBrush.Dispose();
            
if (BackBrush != null)
                BackBrush.Dispose();

            RainHeadBrush 
= new SolidBrush(Rain.RainHeadColor);
            RainBodyBrush 
= new SolidBrush(Rain.RainBodyColor);
            RainTailBrush 
= new SolidBrush(Rain.RainTailColor);
            BackBrush 
= new SolidBrush(Rain.BackColor);

            
//RainItems.Clear();

            
using (Graphics g = _ShowWindow.CreateGraphics())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                g.Clear(Rain.BackColor);
            }

        }


        
private EventHandler DrawRainEvent;

        
void CharacterRainPanel_DrawRainEvent(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//foreach (Rain.Item item in e.Items)
            
//{
            
//    _ShowWindow.Invalidate(new Rectangle(item.X, item.Y, item.Width, item.Height));
            
//    _ShowWindow.Update();
            
//}

            
using (Graphics g = _ShowWindow.CreateGraphics())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                g.DrawImage(BMP, 
00);
            }

            
//_ShowWindow.Invalidate(true);
            
//_ShowWindow.Refresh();
        }


        
//private List RainItems = new List();
        private object RainLOCK = new object();

        
private void RainProcess(object Param)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
using (BMP = new Bitmap(_ShowWindow.Width, _ShowWindow.Height))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
using (Graph = Graphics.FromImage(BMP))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{

                    List
<Rain> Rains = new List<Rain>();
                    
for (int i = 0; i < _StreamsCount; i++)
                        Rains.Add(
new Rain(_MinLength + Rand.Next(_MaxLength - _MinLength)));

                    
while (RUN)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
if (PAUSE)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            Thread.Sleep(
300);
                            
continue;
                        }


                        DoRain(Rains);

                        Thread.Sleep(
50);
                    }


                    
foreach (Rain r in Rains)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        r.Uninit();
                    }

                }

            }

        }


        
private void DoRain(List<Rain> Rains)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

            
for (int i = 0; i < Rains.Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Rain rain 
= Rains[i];

                
if (!rain.Inited)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (!rain.Init(_ShowWindow.Width, Rand.Next(_ShowWindow.Height / 3)))
                        
continue;
                }


                Rain.Item item 
= rain.GetItem(CHARACTERS[Rand.Next(CHARACTERS.Length)]);
                Rain.Item prior 
= null;

                
if (item == null)
                    
continue;
                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
lock (BMPLock)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
if (item.Y <= BMP.Height)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            
if (item.Type == Rain.Item.RainItemType.Head && rain.Prior.Type != Rain.Item.RainItemType.Tail)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
{
                                rain.Prior.Type 
= Rain.Item.RainItemType.Body;
                                prior 
= rain.Prior;
                            }


                            
if (item.Type == Rain.Item.RainItemType.Back)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
{
                                prior 
= rain.Prior;
                            }


                            
switch (item.Type)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
{
                                
case Rain.Item.RainItemType.Head:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
{
                                        Graph.DrawString(
new string(item.CH, 1), _RainFont, RainHeadBrush, item.X, item.Y);
                                        
break;
                                    }

                                
case Rain.Item.RainItemType.Body:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
{
                                        Graph.DrawString(
new string(item.CH, 1), _RainFont, RainBodyBrush, item.X, item.Y);
                                        
break;
                                    }

                                
case Rain.Item.RainItemType.Tail:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
{
                                        Graph.DrawString(
new string(item.CH, 1), _RainFont, RainTailBrush, item.X, item.Y);
                                        
break;
                                    }

                                
case Rain.Item.RainItemType.Back:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
{
                                        Graph.FillRectangle(BackBrush, item.X, item.Y, item.Width, item.Height);
                                        
break;
                                    }

                            }


                            
if (prior != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
{
                                
switch (prior.Type)
ExpandedSubBlockStart.gifContractedSubBlock.gif                                
{
                                    
case Rain.Item.RainItemType.Head:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                        
{
                                            Graph.DrawString(
new string(prior.CH, 1), _RainFont, RainHeadBrush, prior.X, prior.Y);
                                            
break;
                                        }

                                    
case Rain.Item.RainItemType.Body:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                        
{
                                            Graph.DrawString(
new string(prior.CH, 1), _RainFont, RainBodyBrush, prior.X, prior.Y);
                                            
break;
                                        }

                                    
case Rain.Item.RainItemType.Tail:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                        
{
                                            Graph.DrawString(
new string(prior.CH, 1), _RainFont, RainTailBrush, prior.X, prior.Y);
                                            
break;
                                        }

                                    
case Rain.Item.RainItemType.Back:
ExpandedSubBlockStart.gifContractedSubBlock.gif                                        
{
                                            Graph.FillRectangle(BackBrush, prior.X, prior.Y, prior.Width, prior.Height);
                                            
break;
                                        }

                                }

                            }

                        }

                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            item.Owner.Way 
= Rain.RainWay.Reverse;
                        }

                    }

                }

            }


            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (!_ShowWindow.Disposing)
                    _ShowWindow.Invoke(DrawRainEvent, 
thisnew EventArgs());
            }

            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 停止显示字符雨
        
/// 

        public void Stop()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            RUN 
= false;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 暂停显示
        
/// 

        public void Pause()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            PAUSE 
= true;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// 
        
/// 恢复暂停
        
/// 

        public void Resume()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            PAUSE 
= false;
        }


        
//protected void Paint()
        
//{
        
//    lock (RainLOCK)
        
//    {
        
//        for (int i = RainItems.Count - 1; i >= 0; i--)
        
//        {
        
//            Rain.Item item = RainItems[i];

        
//            if (item.X < BMP.Width)
        
//            {
        
//                if (item.Y < BMP.Height)
        
//                {
        
//                    //if (e.ClipRectangle.X <= item.X && e.ClipRectangle.Y <= item.Y && e.ClipRectangle.Width >= item.Width && e.ClipRectangle.Height >= item.Height)
        
//                    {
        
//                        switch (item.Type)
        
//                        {
        
//                            case Rain.Item.RainItemType.Head:
        
//                                {
        
//                                    e.Graphics.DrawString(new string(item.CH, 1), _RainFont, RainHeadBrush, item.X, item.Y);
        
//                                    break;
        
//                                }
        
//                            case Rain.Item.RainItemType.Body:
        
//                                {
        
//                                    e.Graphics.DrawString(new string(item.CH, 1), _RainFont, RainBodyBrush, item.X, item.Y);
        
//                                    break;
        
//                                }
        
//                            case Rain.Item.RainItemType.Tail:
        
//                                {
        
//                                    e.Graphics.DrawString(new string(item.CH, 1), _RainFont, RainTailBrush, item.X, item.Y);
        
//                                    break;
        
//                                }
        
//                            case Rain.Item.RainItemType.Back:
        
//                                {
        
//                                    e.Graphics.FillRectangle(BackBrush, item.X, item.Y, item.Width, item.Height);
        
//                                    break;
        
//                                }
        
//                        }
        
//                    }
        
//                }
        
//                else
        
//                {
        
//                    item.Owner.Way = Rain.RainWay.Reverse;
        
//                }
        
//            }

        
//            if (item.Type == Rain.Item.RainItemType.Back)
        
//            {
        
//                RainItems.Remove(item);
        
//            }
        
//        }
        
//    }
        
//}

        
private class Rain
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
private static Font _RainFont;
            
public static Font RainFont
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
get return _RainFont; }
                
set
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    _RainFont 
= value;

                    _RainHeight 
= (int)(value.Size * value.FontFamily.GetLineSpacing(FontStyle.Regular) / value.FontFamily.GetEmHeight(FontStyle.Regular)) + 1;
                }

            }


            
public static Color BackColor;

            
public static Color RainBodyColor;

            
public static Color RainHeadColor;

            
public static Color RainTailColor;

            
private static int _RainHeight;
            
public static int RainHeight
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
get return _RainHeight; }
            }


            
private static object RangeLock = new object();
            
private static List<Rectangle> Ranges = new List<Rectangle>();

            Queue
<Item> Chars = new Queue<Item>();
            
private int _Length;
            
private int _BeginX;
            
private int _BeginY;

            
private RainWay _Way;

            
public RainWay Way
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
get return _Way; }
ExpandedSubBlockStart.gifContractedSubBlock.gif                
set { _Way = value; }
            }


            
private Rectangle Range;

            
public enum RainWay : byte
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//// 
                
/// 正向
                
/// 

                Obverse = 0,

ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//// 
                
/// 反向
                
/// 

                Reverse = 1
            }


            
public bool Inited
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
get return Chars.Count > 0; }
            }


            
public bool Init(int Width, int Y)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
bool Ret = true;

                Uninit();

                
if (Rand.Next(30< 10)
                    
return false;

                _BeginX 
= Rand.Next(Width);

                Size s 
= TextRenderer.MeasureText(" ", _RainFont);

                Range 
= new Rectangle(_BeginX, Y, s.Width, s.Height * _Length);

                
foreach (Rectangle r in Ranges)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (r.Contains(this.Range) || r.IntersectsWith(this.Range))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        Ret 
= false;
                        
break;
                    }

                }


                
if (Ret)
                    Ranges.Add(
this.Range);

                _BeginY 
= Y;
                _Way 
= RainWay.Obverse;
                _Prior 
= null;

                
return Ret;
            }


            
public void Uninit()
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (this.Range != null && Ranges.Contains(this.Range))
                    Ranges.Remove(
this.Range);
            }


ContractedSubBlock.gifExpandedSubBlockStart.gif            
item#region item
            
public class Item
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
private Rain _Owner;
                
public Rain Owner
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _Owner; }
                }


                
public enum RainItemType : byte
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Head 
= 0,
                    Body 
= 1,
                    Tail 
= 2,
                    Back 
= 3
                }


                
private char _CH;
                
public char CH
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _CH; }
                }


                
private int _X;
                
public int X
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _X; }
                }


                
private int _Y;
                
public int Y
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _Y; }
                }


                
private int _Width;
                
public int Width
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _Width; }
                }


                
private int _Height;
                
public int Height
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _Height; }
                }


                
private RainItemType _Type;
                
public RainItemType Type
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
get return _Type; }
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
set { _Type = value; }
                }


                
public Item(Rain Owner, char CH, int X, int Y, RainItemType Type)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
this._Owner = Owner;
                    
this._CH = CH;
                    
this._X = X;
                    
this._Y = Y;
                    Size s 
= TextRenderer.MeasureText(new string(CH, 1), RainFont);
                    
this._Width = s.Width;
                    
this._Height = s.Height;
                    
this._Type = Type;
                }

            }

            
#endregion


            
public Rain(int Length)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _Length 
= Length;
            }


            
public Item GetItem(char CH)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Item Ret 
= null;
                
if (_Way == RainWay.Obverse)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Ret 
= Add(CH);
                    
if (Ret == null)
                        _Way 
= RainWay.Reverse;
                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Ret 
= Remove();
                    
if (Ret == null)
                        _Way 
= RainWay.Obverse;
                }

                
return Ret;
            }


            
private Item _Prior = null;
            
public Item Prior
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
get
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
return _Prior;
                }

            }


            
private Item Add(char CH)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Item Ret 
= null;
                
if (Chars.Count < _Length)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Ret 
= new Item(this, CH, _BeginX, _BeginY + RainHeight * Chars.Count, Chars.Count == 0 ? Item.RainItemType.Tail : Item.RainItemType.Head);
                    
if (Ret.Type == Item.RainItemType.Head)
                        _Prior 
= Chars.Last();
                    Chars.Enqueue(Ret);
                }


                
return Ret;
            }


            
private Item Remove()
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Item Ret 
= null;
                
if (Chars.Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Ret 
= Chars.Dequeue();
                    Ret.Type 
= Item.RainItemType.Back;

                    
if (Chars.Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        _Prior 
= Chars.First();
                        _Prior.Type 
= Item.RainItemType.Tail;
                    }

                    
else
                        _Prior 
= null;
                }

                
return Ret;
            }

        }

    }

 

 

 

测试程序下载 

使用的时候,先设定ShowWindow,这个属性决定在哪个控件上显示字符雨,然后还可以设置如下属性:

MaxLength:每条字符雨的最大字符数量

MinLength:每条字符雨的最小字符数量

RainBodyColor:字符雨中间的颜色

RainCharacters:字符雨可以使用到的字符

FainFont:字体

RainHeadColor:最前面的字符的颜色

RainTailColor:最后面字符的颜色

StreamsCount:字符雨的数量

 

还有如下方法可供调用:

Start:开始显示

Stop:停止显示

Pause:暂停显示

Resume:恢复暂停

转载于:https://www.cnblogs.com/AndyHai/archive/2008/09/28/1301566.html

你可能感兴趣的:(用C#实现的黑客帝国中的字符雨特效)