Silverlight的随机动画效果

1.建立随机粒子类

 public class Cellule
    {
        public Cellule()
        {
            Age = 0;
        }

        public Brush GetBrush()
        {
            if (isLibre() == true) return new SolidColorBrush(Colors.Transparent);
      
            Brush brush = null;

            if (Age == 1)
                brush = new SolidColorBrush(Colors.Yellow);
            else if (Age == 2)
                brush = new SolidColorBrush(Colors.Orange);
            else if (Age == 3)
                brush = new SolidColorBrush(Colors.Magenta);
            else if (Age < 10)
                brush = new SolidColorBrush(Colors.Blue);
            else if (Age < 15)
                brush = new SolidColorBrush(Colors.Green);
            else
                brush = new SolidColorBrush(Colors.Red);

            return brush;
        }

        public void Copy(Cellule src)
        {
            this.Age = src.Age;
        }

        public bool isLibre()
        {
            return (Age == 0);
        }

        public bool isOccupe()
        {
            return (Age > 0);
        }

        public void Naissance()
        {
            Age = 1;
        }

        public void Meurt()
        {
            Age = 0;
        }

        public void Survie()
        {
            Age++;
        }

       public int Age;
  }

2.动画

    public class Automate
    {
        public void CreateDefaultModele()
        {
            CreateCellules(50, 50, false);

            CreateModuleBasculeVertical(2, 2);
            CreateModuleBasculeHorizontal(30, 5);

            CreateModuleStable(6, 2);

            CreateModuleCroix(15, 16);
            CreateModuleCroix(15, 22);
            CreateModuleCroix(20, 22);
            CreateModuleCroix(20, 16);

            CreateModuleNavireNordEst(45, 5);
            CreateModuleNavireNordEst(45, 10);
            CreateModuleNavireNordEst(45, 20);
            CreateModuleNavireNordEst(45, 30);
            CreateModuleNavireNordEst(45, 45);

            CreateModuleNavireSudOuest(5, 45);
            CreateModuleNavireSudOuest(5, 35);
        }

        public void CreateModele2()
        {
            CreateCellules(50, 50, false);

            //CreateModuleCroix(10, 10);
            //CreateModuleCroix(10, 40);
            //CreateModuleCroix(40, 10);
            //CreateModuleCroix(40, 40);

            CreateGun(30, 1);

            //CreateModuleNavireNordEst(21, 21);
            //CreateModuleNavireSudOuest(25, 25);
        }

        private void CreateCellules(int _AutomateWidth, int _AutomateHeight, bool bStateInitale)
        {
            AutomateWidth = _AutomateWidth;
            AutomateHeight = _AutomateHeight;

            Cellules = new Cellule[AutomateWidth, AutomateHeight];
            WorkingCellules = new Cellule[AutomateWidth, AutomateHeight];
            for (int iRow = 0; iRow < AutomateHeight; iRow++)
            {
                for (int iCol = 0; iCol < AutomateWidth; iCol++)
                {
                    Cellules[iRow, iCol] = new Cellule();
                    WorkingCellules[iRow, iCol] = new Cellule();
                }
            }
        }

        public void Generation()
        {
            // Si une cellule est seule ou avec seulement une voisine (dans les 8 directions possibles), elle meurt de solitude. snif.
            // Si une cellule a 2 ou 3 voisines, elle survit.
            // Si une cellule a plus de 3 voisines, elle meurt à cause de la surpopulation.
            // Enfin, si 3 cellules entourent une case vide, elles donnent naissance à un merveilleux petit rejeton !

            // Calcul la prochaine generation
            for (int iRow = 0; iRow < AutomateHeight; iRow++)
            {
                for (int iCol = 0; iCol < AutomateWidth; iCol++)
                {
                    int iNbVoisin = GetCelluleNbVoisin(iRow, iCol);
                    WorkingCellules[iRow, iCol].Copy(Cellules[iRow, iCol]);

                    if (Cellules[iRow, iCol].isOccupe() == true)
                    {
                        // Cellule occupé
                        if (iNbVoisin < 2 || iNbVoisin > 3)
                            WorkingCellules[iRow, iCol].Meurt();
                        else
                            WorkingCellules[iRow, iCol].Survie();
                    }
                    else
                    {
                        // Cellule Libre
                        if (iNbVoisin == 3)
                            WorkingCellules[iRow, iCol].Naissance();
                    }
                }
            }

            // Mise a jour de automate
            for (int iRow = 0; iRow < AutomateHeight; iRow++)
            {
                for (int iCol = 0; iCol < AutomateWidth; iCol++)
                {
                    Cellules[iRow, iCol].Copy(WorkingCellules[iRow, iCol]);
                }
            }
        }

        private int GetCelluleNbVoisin(int iRow, int iCol)
        {
            int iNbVoisin = 0;

            if (CelluleOccupe(iRow - 1, iCol - 1) == true) iNbVoisin++;
            if (CelluleOccupe(iRow - 1, iCol) == true) iNbVoisin++;
            if (CelluleOccupe(iRow - 1, iCol + 1) == true) iNbVoisin++;
            if (CelluleOccupe(iRow, iCol - 1) == true) iNbVoisin++;
            // moi
            if (CelluleOccupe(iRow, iCol + 1) == true) iNbVoisin++;
            if (CelluleOccupe(iRow + 1, iCol - 1) == true) iNbVoisin++;
            if (CelluleOccupe(iRow + 1, iCol) == true) iNbVoisin++;
            if (CelluleOccupe(iRow + 1, iCol + 1) == true) iNbVoisin++;

            return iNbVoisin;
        }

        private bool CelluleOccupe(int iRow, int iCol)
        {
            // la matrice est spherique
            if (iRow < 0) iRow = AutomateHeight - 1;
            if (iRow >= AutomateHeight) iRow = 0;

            if (iCol < 0) iCol = AutomateWidth - 1;
            if (iCol >= AutomateWidth) iCol = 0;

            return Cellules[iRow, iCol].isOccupe();
        }

        public void CreateModuleCroix(int iRow, int iCol)
        {
            Cellules[iRow, iCol - 1].Naissance();
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow - 1, iCol].Naissance();
            Cellules[iRow + 1, iCol].Naissance();
        }

        public void CreateModuleStable(int iRow, int iCol)
        {
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow + 1, iCol].Naissance();
            Cellules[iRow + 1, iCol + 1].Naissance();
        }

        public void CreateModuleBasculeHorizontal(int iRow, int iCol)
        {
            Cellules[iRow, iCol - 1].Naissance();
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
        }

        public void CreateModuleBasculeVertical(int iRow, int iCol)
        {
            Cellules[iRow - 1, iCol].Naissance();
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow + 1, iCol].Naissance();
        }

        public void CreateModuleNavireNordEst(int iRow, int iCol)
        {
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow, iCol + 2].Naissance();
            Cellules[iRow + 1, iCol + 2].Naissance();
            Cellules[iRow + 2, iCol + 1].Naissance();
        }

        public void CreateModuleNavireSudOuest(int iRow, int iCol)
        {
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow, iCol + 2].Naissance();
            Cellules[iRow - 1, iCol].Naissance();
            Cellules[iRow - 2, iCol + 1].Naissance();
        }

        public void CreateGun(int iRow, int iCol)
        {
            //stable gauche
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow + 1, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow + 1, iCol + 1].Naissance();

            iCol += 10;
            // C
            Cellules[iRow - 2, iCol + 3].Naissance();
            Cellules[iRow - 2, iCol + 2].Naissance();
            Cellules[iRow - 1, iCol + 1].Naissance();
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow + 1, iCol].Naissance();
            Cellules[iRow + 2, iCol].Naissance();
            Cellules[iRow + 3, iCol + 1].Naissance();
            Cellules[iRow + 4, iCol + 2].Naissance();
            Cellules[iRow + 4, iCol + 3].Naissance();
            //
            Cellules[iRow + 1, iCol + 4].Naissance();
            //
            Cellules[iRow - 1, iCol + 5].Naissance();
            Cellules[iRow + 3, iCol + 5].Naissance();
            Cellules[iRow, iCol + 6].Naissance();
            Cellules[iRow + 1, iCol + 6].Naissance();
            Cellules[iRow + 2, iCol + 6].Naissance();
            Cellules[iRow + 1, iCol + 7].Naissance();

            iCol += 10;
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow - 1, iCol].Naissance();
            Cellules[iRow - 2, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow - 1, iCol + 1].Naissance();
            Cellules[iRow - 2, iCol + 1].Naissance();
            Cellules[iRow - 3, iCol + 2].Naissance();
            Cellules[iRow - 3, iCol + 4].Naissance();
            Cellules[iRow - 4, iCol + 4].Naissance();

            Cellules[iRow + 1, iCol + 2].Naissance();
            Cellules[iRow + 1, iCol + 4].Naissance();
            Cellules[iRow + 2, iCol + 4].Naissance();

            iCol -= 10;

            //stable droite
            iRow -= 2;
            iCol += 24;
            Cellules[iRow, iCol].Naissance();
            Cellules[iRow + 1, iCol].Naissance();
            Cellules[iRow, iCol + 1].Naissance();
            Cellules[iRow + 1, iCol + 1].Naissance();
        }
        public void CreateRandomModel()
        {
            CreateCellules(50, 50, false);
            Random rnd = new Random();
            for (int i = 0; i < 50; i++)
            {
                for (int j = 0; j < 50; j++)
                {
                    if (rnd.Next(5) == 0)
                    {
                        Cellules[i, j].Naissance();
                    }
                }
            }
        }
        #region ------------- fields ------------------
        public int AutomateWidth;
        public int AutomateHeight;
        public Cellule[,] Cellules = null;
        public Cellule[,] WorkingCellules = null;
        #endregion ------------- fields ------------------


    }

3.实现

<UserControl x:Class="ALife.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid Width="600" Height="550" Background="#3565A2" >
        <Grid.Resources>
            <ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
                <Grid>
                    <Rectangle RadiusX="5" RadiusY="5">
                        <Rectangle.Stroke>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FFB59013" Offset="0"/>
                                <GradientStop Color="#FF900500" Offset="1"/>
                            </LinearGradientBrush>
                        </Rectangle.Stroke>
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FFFFAD00" Offset="0"/>
                                <GradientStop Color="#FFB94A4A" Offset="0.996"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Grid.Resources>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="25"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" >
            <Button Click="Button_Click" Content="Itération" Width="80" Margin="2" Template="{StaticResource ButtonTemplate}"></Button>
            <Button Click="AutomateModele1_Click" Content="Modele 1" Width="80" Margin="2" Template="{StaticResource ButtonTemplate}"></Button>
            <Button Click="AutomateModele2_Click" Content="Gosper Glider Gun" Width="110" Margin="2" Template="{StaticResource ButtonTemplate}"></Button>
            <Button Click="Randon_Click" Content="Random" Template="{StaticResource ButtonTemplate}"/>
            <Button Click="Start_Click" Content="Start" Template="{StaticResource ButtonTemplate}"/>
        </StackPanel>
        <Canvas Grid.Row="1" Grid.Column="0" Name="canvas">
        </Canvas>
    </Grid>


</UserControl>

  public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            CelluleWidth = 8;
            CelluleHeight = 8;
            PaddingX = 2;
            PaddingY = 2;

            Window_Loaded(null, null);
        }

        private void CreatePlateau()
        {
            //$$$Rectangle cellule;
            Ellipse cellule;
            double Y = 5;
            int iName = 1;
            for (int iRow = 0; iRow < m_Automate.AutomateHeight; iRow++)
            {
                double X = 5;
                for (int iCol = 0; iCol < m_Automate.AutomateWidth; iCol++)
                {
                    //$$$cellule = new Rectangle();
                    cellule = new Ellipse();
                    cellule.Width = CelluleWidth;
                    cellule.Height = CelluleHeight;
                    cellule.SetValue(Canvas.TopProperty, Y);
                    cellule.SetValue(Canvas.LeftProperty, X);
                    cellule.Fill = m_Automate.Cellules[iRow, iCol].GetBrush();
                    cellule.DataContext = m_Automate.Cellules[iRow, iCol];
                    cellule.Name = "N" + iName.ToString();


                    canvas.Children.Add(cellule);

                    X += (CelluleWidth + PaddingX);
                    iName++;
                }

                Y += (CelluleHeight + PaddingY);
            }
        }

        private void UpdatePlateau()
        {
            int iIdx = 0;
            //$$$Rectangle cellule = null;
            Ellipse cellule = null;
            for (int iRow = 0; iRow < m_Automate.AutomateHeight; iRow++)
            {
                for (int iCol = 0; iCol < m_Automate.AutomateWidth; iCol++)
                {
                    //$$$cellule = canvas.Children[iIdx] as Rectangle;
                    cellule = canvas.Children[iIdx] as Ellipse;
                    cellule.Fill = m_Automate.Cellules[iRow, iCol].GetBrush();
                    iIdx++;
                }
            }
        }

        #region ------------- Events ------------------
        public void Window_Loaded(object sender, RoutedEventArgs e)
        {
            m_Automate.CreateDefaultModele();
            CreatePlateau();
            UpdatePlateau();
        }

        public void Button_Click(object sender, RoutedEventArgs e)
        {
            int NbIteration = 1;
            for (int i = 0; i < NbIteration; i++)
            {
                m_Automate.Generation();
                UpdatePlateau();
            }
        }
        public void AutomateModele1_Click(object sender, RoutedEventArgs e)
        {
            m_Automate.CreateDefaultModele();
            UpdatePlateau();
        }
        public void AutomateModele2_Click(object sender, RoutedEventArgs e)
        {
            m_Automate.CreateModele2();
            UpdatePlateau();
        }
        public void Randon_Click(object sender, RoutedEventArgs e)
        {
            m_Automate.CreateRandomModel();
            UpdatePlateau();
        }
        public void Start_Click(object sender, RoutedEventArgs e)
        {
            Thread _thread = new Thread(delegate()
            {
                for (int i = 0; i < 50; i++)
                {
                    this.Dispatcher.BeginInvoke(delegate()
                    {
                        m_Automate.Generation();
                        UpdatePlateau();
                    });
                    Thread.Sleep(400);
                }
            });
            _thread.Start();
        }
        #endregion ------------- Events ------------------

        #region ------------- Fields ------------------
        Automate m_Automate = new Automate();
        int CelluleWidth;
        int CelluleHeight;
        int PaddingX;
        int PaddingY;
        #endregion ------------- Events ------------------


    }

4.源码下载:https://files.cnblogs.com/salam/ALife.rar

原文地址:https://www.cnblogs.com/salam/p/1819436.html