一、建立遊戲界面
編輯MainWindow.xaml,修改代碼以下:數組
<Window.Resources> <Style TargetType="Label"> <Setter Property="Height" Value="105" /> <Setter Property="Width" Value="105" /> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Opacity" Value="0.7" /> </Style> <Style TargetType="Rectangle"> <Setter Property="Width" Value="105"/> <Setter Property="Height" Value="105"/> <Setter Property="Fill" Value="#ccc0b2"/> </Style> </Window.Resources> <Grid HorizontalAlignment="Left"> <Grid.RowDefinitions> <RowDefinition Height="100"/> <RowDefinition Height="500"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="20"/> <ColumnDefinition Width="500"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Image Grid.Row="0" Grid.Column="1" Source="/Images/title2048.png"/> <Canvas x:Name="myCanvas" Grid.Row="1" Grid.Column="1" Width="495" Height="495" Background="#b8af9e"/> <StackPanel Grid.Row="0" Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center"> <Button x:Name="btnNewGame" Content="新的起點" Width="80" Margin="8" Height="30" Click="BtnNewGame_Click" Focusable="False" /> <Button x:Name="btnOldGame" Content="舊的征程" Width="80" Margin="8" Height="30" Focusable="False"/> </StackPanel> <Grid Grid.Row="1" Grid.Column="2" Margin="10" > <Grid.RowDefinitions> <RowDefinition Height="0.5*"/> <RowDefinition Height="*"/> <RowDefinition Height="0.5*"/> <RowDefinition Height="*"/> <RowDefinition Height="0.5*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Text="當前得分: " Width="210" FontSize="20" VerticalAlignment="Bottom"/> <Label x:Name="lblCurrScore" Grid.Row="1" Content="2048" Width="210" FontSize="40" Foreground="Maroon" Opacity="1" /> <Label x:Name="lblAddScore" Grid.Row="1" Content="0" Width="210" FontSize="20" Foreground="Chocolate" Opacity="0" > <Label.RenderTransform> <TranslateTransform x:Name="tt" X="0" Y="0"/> </Label.RenderTransform> </Label> <TextBlock Text="最高記錄: " Grid.Row="2" Width="210" FontSize="20" VerticalAlignment="Bottom"/> <Label x:Name="lblBastScore" Grid.Row="3" Content="0" Width="210" FontSize="35" Foreground="DarkGray" Opacity="1" /> <Button x:Name="btnShowTopScore" Grid.Row="4" Content="排行榜" Width="80" Margin="8" Height="25" HorizontalAlignment="Right" Focusable="False"/> <Button x:Name="btnExitGame" Grid.Row="5" Content="退出遊戲" Width="80" Margin="8" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" Focusable="False" Click="BtnExitGame_Click"/> </Grid> </Grid>
(1)在Window資源區分別定義了Label和Rectangle的樣式,由於接下來遊戲區的4宮格中使用的主要是對Lebel控件進行顯示和移動操做的。
(2)另外還添加一個命名爲lblAddScore的Lebel控件(其初始透明度爲0,即徹底透明),用於增長成績時的動畫效果,其中定義了命名爲tt的TranslateTransform變換效果。
(3)遊戲主區控件爲Canvas,命名爲myCanvas。
(4)其餘能夠根據本身的喜愛進行調整。dom
二、定義幾個字段變量
畢竟是小遊戲,直接從MainWindow.xaml.cs開始下手了。字體
int lblWidth = 105; // 方塊大小 int lblPadding = 15; // 方塊間隙 int[,] gridData = null; // 遊戲主數據數組 Label[,] lblArray = null; // 用於顯示成方塊的Label數組 int currScore = 0; // 當前成績 bool isStarted = false; // 遊戲是否已開始 Random rnd = new Random(); // 隨機數
三、幾個開始須要調用的方法
3.1 遊戲開始數字板
界面中的16個遊戲數字爲0時,只顯示空的16塊小板面,其顏色比背景色稍淺。動畫
/// <summary> /// 顯示背景矩形塊 /// </summary> private void ShowBackRect() { for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { Rectangle rect = new Rectangle(); rect.SetValue(Canvas.LeftProperty, (double)((x + 1) * lblPadding + x * lblWidth)); rect.SetValue(Canvas.TopProperty, (double)((y + 1) * lblPadding + y * lblWidth)); myCanvas.Children.Add(rect); } } }
3.2 生成新數
遊戲開始後,須要隨機生成值爲2或4的兩個新數字。以後,每上、下、左、右移動其中一次界面中的數字後,若是還有空位,又須要隨機生成一個2或4的新數字。spa
/// <summary> /// 重載生成新數 /// </summary> /// <returns></returns> private bool NewNum() { int num = rnd.Next(0, 9) > 2 ? 2 : 4; int nullnum = 0; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { if (gridData[y, x] == 0) nullnum++; } } if (nullnum < 1) { return false; } int index = rnd.Next(1, nullnum); nullnum = 0; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { if (gridData[y, x] == 0) { nullnum++; if (nullnum != index) continue; gridData[y, x] = num; } } } return true; }
先統計出界面中剩餘空格數,再從空格數中獲取隨機數做爲新數位置,賦值2或4之一。
code
3.3 設置Label板背景色和前景字體大小
根據gridData元素值的高低,顯示不一樣的背景色和字體大小orm
/// <summary> /// 根據數值生成方塊背景色值 /// </summary> /// <param name="num"></param> /// <returns></returns> private Brush SetBackground(int num) { Brush backColor; switch (num) { case 2: backColor = new SolidColorBrush(Color.FromRgb(0xee, 0xe4, 0xda)); break; case 4: backColor = new SolidColorBrush(Color.FromRgb(0xec, 0xe0, 0xc8)); break; case 8: backColor = new SolidColorBrush(Color.FromRgb(0xf2, 0xb1, 0x79)); break; case 16: backColor = new SolidColorBrush(Color.FromRgb(0xf5, 0x95, 0x63)); break; case 32: backColor = new SolidColorBrush(Color.FromRgb(0xf5, 0x7c, 0x5f)); break; case 64: backColor = new SolidColorBrush(Color.FromRgb(0xf6, 0x5d, 0x3b)); break; case 128: backColor = new SolidColorBrush(Color.FromRgb(0xed, 0xce, 0x71)); break; case 256: backColor = new SolidColorBrush(Color.FromRgb(0xed, 0xcc, 0x61)); break; case 512: backColor = new SolidColorBrush(Color.FromRgb(0xec, 0xc8, 0x50)); break; case 1024: backColor = new SolidColorBrush(Color.FromRgb(0xed, 0xc5, 0x3f)); break; case 2048: backColor = new SolidColorBrush(Color.FromRgb(0xee, 0xc2, 0x2e)); break; case 4096: backColor = new SolidColorBrush(Color.FromRgb(0xef, 0x85, 0x9c)); break; default: backColor = new SolidColorBrush(Color.FromRgb(0xcc, 0xc0, 0xb2)); break; } return backColor; } /// <summary> /// 根據數值設置方塊字體大小 /// </summary> /// <param name="num"></param> /// <returns></returns> private int SetFontSize(int num) { int iFontsize; switch (num) { case 2: case 4: case 8: iFontsize = 55; break; case 16: case 32: case 64: iFontsize = 50; break; case 128: case 256: case 512: iFontsize = 40; break; case 1024: case 2048: case 4096: iFontsize = 33; break; default: iFontsize = 30; break; } return iFontsize; }
3.4 顯示遊戲區的全部Label控件
若是gridData元素值不爲0的話,生成Label控件並添加到遊戲板中。blog
/// <summary> /// 從新顯示全部Label /// </summary> private void ShowAllLabel() { myCanvas.Children.Clear(); ShowBackRect(); for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { if (gridData[y, x] != 0) { lblArray[y, x] = new Label(); lblArray[y, x].SetValue(Canvas.LeftProperty, lblPadding * (x + 1) + (double)(x * lblWidth)); lblArray[y, x].SetValue(Canvas.TopProperty, lblPadding * (y + 1) + (double)(y * lblWidth)); lblArray[y, x].SetValue(Label.ContentProperty, gridData[y, x].ToString()); lblArray[y, x].SetValue(Label.BackgroundProperty, SetBackground(gridData[y, x])); lblArray[y, x].SetValue(Label.FontSizeProperty, (double)SetFontSize(gridData[y, x])); myCanvas.Children.Add(lblArray[y, x]); } } } }
四、初始化遊戲數據遊戲
/// <summary> /// 初始化數據 /// </summary> private void InitData() { if (gridData != null) // 初始化主數據數組 gridData = null; gridData = new int[4, 4] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; if (lblArray != null) // 初始化顯示用Label數組 lblArray = null; lblArray = new Label[4, 4]; if (myCanvas.Children.Count > 0) myCanvas.Children.Clear(); // 清除界面 NewNum(); // 生成兩個新數 NewNum(); ShowAllLabel(); // 刷新遊戲方塊 isStarted = true; currScore = 0; // 初始化當前成績爲0 lblCurrScore.Content = currScore.ToString();// 更新當前成績顯示 }
將InitData()方法添加到BtnNewGame_Click按鈕事件方法中。
如今運行遊戲,不斷點擊開始新遊戲按鈕,會在不一樣位置生成兩個2或4的數字,並顯示出來。事件
五、判斷遊戲是否結束
判斷每一行是否存在空位,若是有則未結束。若是該行已滿,則看看是否存在相鄰是否有相同的數字,若是有則說明能夠合併出新空位,即未結束。
列判斷方式相同。
/// <summary> /// 遊戲是否結束 /// </summary> /// <returns></returns> private bool isGameOver() { for (int row = 0; row < 4; row++) { for (int i = 0; i < 4; i++) { if (gridData[row, i] == 0) // 是否有空位 { return false; } } for (int i = 0; i < 3; i++) { if (gridData[row, i] == gridData[row, i + 1]) { return false; } } } for (int col = 0; col < 4; col++) { for (int i = 0; i < 4; i++) { if (gridData[i, col] == 0) { return false; } } for (int i = 0; i < 3; i++) { if (gridData[i, col] == gridData[i + 1, col]) { return false; } } } return true; } /// <summary> /// 顯示動畫結束對話框 /// </summary> private void ShowGameOver() { MessageBox.Show("遊戲已經結束。", "Game Over", MessageBoxButton.OK, MessageBoxImage.Information); isStarted = false; }