原文:
1、创建游戏界面
编辑MainWindow.xaml,修改代码如下:(1)在Window资源区分别定义了Label和Rectangle的样式,因为接下游戏区的4宫格中使用的主要是对Lebel控件进行显示显示和移动操作的。
(2)另外还添加一个命名为lblAddScore的Lebel控件(其初始透明度为0,即完全透明),用于增加成绩时的动画效果,其中定义了命名为tt的TranslateTransform变换效果。(3)游戏主区控件为Canvas,命名为myCanvas。(4)其他可以根据自己的喜好进行调整。
2、定义几个字段变量
毕竟是小游戏,直接从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、几个开始需要调用的方法
3.1 游戏开始数字板界面中的16个游戏数字为0时,只显示空的16块小板面,其颜色比背景色稍浅。////// 显示背景矩形块/// 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的新数字。////// 重载生成新数/// ///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之一。
3.3 设置Label板背景色和前景字体大小
根据gridData元素值的高低,显示不同的背景色和字体大小////// 根据数值生成方块背景色值/// /// ///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;}/// /// 根据数值设置方块字体大小/// /// ///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控件并添加到游戏板中。////// 重新显示所有Label/// 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]); } } }}
4、初始化游戏数据
////// 初始化数据/// 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的数字,并显示出来。
5、判断游戏是否结束
判断每一行是否存在空位,如果有则未结束。如果该行已满,则看看是否存在相邻是否有相同的数字,如果有则说明可以合并出新空位,即未结束。列判断方式相同。////// 游戏是否结束/// ///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;}/// /// 显示动画结束对话框/// private void ShowGameOver(){ MessageBox.Show("游戏已经结束。", "Game Over", MessageBoxButton.OK, MessageBoxImage.Information); isStarted = false;}
posted on 2019-05-27 17:52 阅读( ...) 评论( ...)