博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
练手WPF(二)——2048游戏的简易实现(上)
阅读量:5300 次
发布时间:2019-06-14

本文共 7965 字,大约阅读时间需要 26 分钟。

原文:

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 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10932104.html

你可能感兴趣的文章
ASP.NET 会话状态【一】
查看>>
day 38 进程 与 子进程 (开启进程 + 进程中的数据隔离 + 守护进程 + 进程中的其他方法 )...
查看>>
dubbo注册中心介绍
查看>>
在netty3.x中存在两种线程:boss线程和worker线程。
查看>>
1489 蜥蜴和地下室
查看>>
【HTML/XML 10】XML文档中的Schema文件
查看>>
C语言中整型运算取Ceiling问题
查看>>
分治——最近点对
查看>>
Spring中jdbc Template使用
查看>>
什么是你的核心竞争力?
查看>>
Network Monitoring in Software-Defined Networking :A Review(综述)
查看>>
libtiff4.04
查看>>
CentOS 7 下使用 Firewall
查看>>
软件设计原则与模式
查看>>
[微信小程序] 认识微信小程序及开发环境搭建
查看>>
json模块,pickle模块,shelve模块
查看>>
django 分页出现 UnorderedObjectListWarning 错误
查看>>
140711
查看>>
芹菜炒香菇黑木耳
查看>>
[Ynoi2016]谁的梦
查看>>