zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    webgl变换:深入图形平移
    webgl基础:顶点到片元的联动
    webgl基础:绘制多边形
    webgl初章:进入3D世界
    canvas动画实战与性能优化
    初识canvas(二)
    初识canvas(一)
    SQL换行符
    正则表达式校验
    2019.7.2 JQ
  • 原文地址:https://www.cnblogs.com/salam/p/1819436.html
Copyright © 2011-2022 走看看