Silverlight的随机动画效果
时间:2010-09-06 来源:永恒的记忆
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.源码下载:http://files.cnblogs.com/salam/ALife.rar