接着上一篇继续~~~

6、动画显示增加分数

/// <summary>
/// 动画显示增加得分
/// </summary>
/// <param name="addScore"></param>
private void ShowAddScore(int addScore)
{
lblAddScore.Content = "+" + addScore.ToString(); DoubleAnimation top = new DoubleAnimation();
DoubleAnimation opacity = new DoubleAnimation();
opacity.AutoReverse = true;
opacity.From = ;
opacity.To = ;
top.From = ;
top.To = -;
Duration duration = new Duration(TimeSpan.FromMilliseconds());
top.Duration = duration;
opacity.Duration = duration; tt.BeginAnimation(TranslateTransform.YProperty, top);
lblAddScore.BeginAnimation(Label.OpacityProperty, opacity);
}

该动画通过位置向上移动和透明度变化实现。

7、移动操作
  7.1 移动操作方法
每按下一次上下左右键,则调用相应的移动操作方法。以前实现的,代码比较繁琐,这次没去精简清理,看看就好。这是左移操作方法:

/// <summary>
/// 左移
/// </summary>
private void MoveLeft()
{
int score = ; Storyboard sb1 = new Storyboard(); // 移去左侧和中间的空块(左移)
for (int y = ; y < ; y++)
{
for (int x = ; x < ; x++)
{
for (int i = x + ; i < ; i++)
{
if (gridData[y, i] != && gridData[y, x] == )
{
gridData[y, x] = gridData[y, i]; if (lblArray[y, i] == null)
{
lblArray[y, i] = new Label();
lblArray[y, i].SetValue(Canvas.LeftProperty, lblPadding * ((i) + ) + (double)((i) * lblWidth));
lblArray[y, i].SetValue(Canvas.TopProperty, lblPadding * (y + ) + (double)(y * lblWidth));
lblArray[y, i].SetValue(Label.ContentProperty, gridData[y, i].ToString());
lblArray[y, i].SetValue(Label.BackgroundProperty, SetBackground(gridData[y, i]));
lblArray[y, i].SetValue(Button.FontSizeProperty, (double)SetFontSize(gridData[y, i]));
} // 左移方块动画
DoubleAnimation da1 = null;
double from = (double)lblArray[y, i].GetValue(Canvas.LeftProperty);
double to = (x + ) * lblPadding + x * lblWidth;
da1 = new DoubleAnimation(
from,
to,
new Duration(TimeSpan.FromMilliseconds()));
da1.AccelerationRatio = 0.1;
da1.DecelerationRatio = 0.1; Storyboard.SetTarget(da1, lblArray[y, i]);
Storyboard.SetTargetProperty(da1, new PropertyPath("(Canvas.Left)"));
sb1.Children.Add(da1); gridData[y, i] = ;
}
}
}
} // 相邻相同方块合并后加到左侧
for (int y = ; y < ; y++)
{
for (int x = ; x < ; x++)
{
if (x + < && gridData[y, x] == gridData[y, x + ])
{
// 如果右侧的方块未及时生成
if (gridData[y, x + ] != )// && gridData[y,x]!=0)
{
if (lblArray[y, x + ] == null)
{
lblArray[y, x + ] = new Label();
lblArray[y, x + ].SetValue(Canvas.LeftProperty, lblPadding * ((x + ) + ) + (double)((x + ) * lblWidth));
lblArray[y, x + ].SetValue(Canvas.TopProperty, lblPadding * (y + ) + (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(Button.FontSizeProperty, (double)SetFontSize(gridData[y, x + ]));
} // 左移动画
DoubleAnimation da2 = null;
double from = (double)lblArray[y, x + ].GetValue(Canvas.LeftProperty);
double to = from - lblWidth - lblPadding;
da2 = new DoubleAnimation(
from,
to,
new Duration(TimeSpan.FromMilliseconds()));
da2.AccelerationRatio = 0.1;
da2.DecelerationRatio = 0.1;
Storyboard.SetTarget(da2, lblArray[y, x + ]);
Storyboard.SetTargetProperty(da2, new PropertyPath("(Canvas.Left)"));
sb1.Children.Add(da2);
}
gridData[y, x] *= ;
gridData[y, x + ] = ; score += gridData[y, x];
}
}
} if (score != )
{
ShowAddScore(score);
currScore += score;
lblCurrScore.Content = currScore.ToString();
} // 将合并后出现的中间空方块移去(再次左移一次)
for (int y = ; y < ; y++)
{
for (int x = ; x < ; x++)
{
for (int i = x + ; i < ; i++)
{
if (gridData[y, i] != && gridData[y, x] == )
{
gridData[y, x] = gridData[y, i]; if (lblArray[y, i] == null)
{
lblArray[y, i] = new Label();
lblArray[y, i].SetValue(Canvas.LeftProperty, lblPadding * ((i) + ) + (double)((i) * lblWidth));
lblArray[y, i].SetValue(Canvas.TopProperty, lblPadding * (y + ) + (double)(y * lblWidth));
lblArray[y, i].SetValue(Label.ContentProperty, gridData[y, i].ToString());
lblArray[y, i].SetValue(Label.BackgroundProperty, SetBackground(gridData[y, i]));
lblArray[y, i].SetValue(Button.FontSizeProperty, (double)SetFontSize(gridData[y, i]));
} // 左移动画
DoubleAnimation da = null;
double from = (double)lblArray[y, i].GetValue(Canvas.LeftProperty);
double to = (x + ) * lblPadding + x * lblWidth;
da = new DoubleAnimation(
from,
to,
new Duration(TimeSpan.FromMilliseconds()));
da.AccelerationRatio = 0.1;
da.DecelerationRatio = 0.1;
Storyboard.SetTarget(da, lblArray[y, i]);
Storyboard.SetTargetProperty(da, new PropertyPath("(Canvas.Left)"));
sb1.Children.Add(da); gridData[y, i] = ; // isMove = true;
}
}
}
} sb1.Completed += Sb1_Completed; // 所有动画完成后执行事件
sb1.Begin();
} /// <summary>
/// 动画完成后运行事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Sb1_Completed(object sender, EventArgs e)
{
// 检查游戏是否结束
if (isGameOver())
{
ShowGameOver();
}
else
{
NewNum();
ShowAllLabel();
}
}

向右、向上和向下的方法类似。

  7.2 xaml文件中添加Window控件的keyDown事件
KeyDown="Window_KeyDown"
对应的cs代码如下:

private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (!isStarted)
return; switch (e.Key)
{
case Key.Left:
if (!isGameOver())
MoveLeft();
else
ShowGameOver();
break; case Key.Right:
if (!isGameOver())
MoveRight();
else
ShowGameOver(); break; case Key.Up:
if (!isGameOver())
MoveUp();
else
ShowGameOver(); break; case Key.Down:
if (!isGameOver())
MoveDown();
else
ShowGameOver();
break;
}
}

大致如此。最后看看效果图吧~~

练手WPF(二)——2048游戏的简易实现(下)的更多相关文章

  1. 练手WPF(三)——扫雷小游戏的简易实现(中)

    八.随机布雷 /// <summary> /// 随机布地雷 /// </summary> /// <param name="mineNum"> ...

  2. 练手WPF(一)——模拟时钟与数字时钟的制作(上)

    一.Visual Studio创建一个WPF项目. 简单调整一下MainWindow.xaml文件.主要使用了两个Canvas控件,分别用于显示模拟和数字时钟,命名为AnalogCanvas.digi ...

  3. 练手WPF(二)——2048游戏的简易实现(上)

    1.创建游戏界面编辑MainWindow.xaml,修改代码如下: <Window.Resources> <Style TargetType="Label"> ...

  4. 练手WPF(三)——扫雷小游戏的简易实现(上)

    一.创建项目1.创建WPF项目,设置初始化窗口大小(初级难度):高x宽为430x350.2.添加文件夹Images,并添加相关图片. 3.xaml中引入图片资源. <Window.Resourc ...

  5. 练手WPF(四)——贪吃蛇小游戏的简易实现(上)

    一. 游戏界面首先,按照惯例,编辑MainWindow.xaml,先将游戏界面制作好.非常简单:(1)主游戏区依然使用我们熟悉的Canvas控件,大小为640X480像素,设定每小格子为20px,所以 ...

  6. 练手WPF(三)——扫雷小游戏的简易实现(下)

    十四.响应鼠标点击事件    (1)设置对应坐标位置为相应的前景状态 /// <summary> /// 设置单元格图样 /// </summary> /// <para ...

  7. 练手WPF(四)——贪吃蛇小游戏的简易实现(下)

    八.生成新的单节蛇身我们这里先说说游戏小原理好了,游戏运行后,通过计时器事件不断生成新的单节蛇身类SnakeNode,添加到List中的0位置,原来的蛇头变成了第二节.该节新蛇头的坐标通过蛇头前进方向 ...

  8. 微信小程序框架分析小练手(二)——天气微信小程序制作

    简单的天气微信小程序. 一.首先,打开微信开发者工具,新建一个项目:weather.如下图: 二.进入app.json中,修改导航栏标题为“贵州天气网”. 三.进入index.wxml,进行当天天气情 ...

  9. 练手WPF(一)——模拟时钟与数字时钟的制作(中)

    今天接着制作数字时钟 数字时钟主要用到Path控件,主要用于定义数字笔划的形状. (1)添加一个DigitLine类 数字时钟的数字8由7笔组成,看如下定义的字段字符串数组PathDatas,每个st ...

随机推荐

  1. 最全的.NET Core跨平台微服务学习资源

    一.Asp.net Core基础 微软中文官网:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/ 微软英文官网:https:/ ...

  2. 浅谈Java面向对象思想

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  3. 为Dynamics CRM注释的图片附件做个预览功能

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复163或者20151017可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! Dynamics CRM中注释可 ...

  4. Linux下用户管理:创建用户指定密码

    首先我们来了解下Linux下用户管理的概念: 如上图所示,左边的一列表示用户名,中间的一列表示用户组,最右边的一列表示的是家目录.用户名我们这里处于简单就,添加了root,xm,xh三个用户.用户组和 ...

  5. Android apk签名方法介绍

    还望支持个人博客站:http://www.enjoytoday.cn 参考博客:http://www.enjoytoday.cn/posts/203 为什么要签名 在介绍签名方法之前,首先我们来了解下 ...

  6. Python类的定义、方法和属性使用

    类用来描述具有相同的属性和方法的对象的集合.对于在类中定义的函数,称为方法.类变量不直接叫做类变量,称为属性. 1.类的定义 例子: class User(): pass 说明: (1)定义了一个类名 ...

  7. Element-ui中为上传组件添加表单校验

    vue所依赖的Element的UI库在使用其中的upload组件时,可能很大几率会遇到这个题,需要给upload组件添加表单校验 大家这里直接看代码就可以 <el-form-item class ...

  8. Sublime操作

    快速搭建HTML模版:左下角的纯文本编程HTML语言,然后输出!(感叹号)或者html:5,再按Tab键. 快速创建html标签: div#top>(div.top-left>div.li ...

  9. postman---postman自动发博客

    前面写了一篇如何通过Cookies值去登录博客园,今天我们来通过登录博客园之后,我们进行通过Postman自动写博客 自动写博客 1.打开Postman.填写博客园对应的Cookies: 2.抓取编写 ...

  10. 2019.6.13_MySQL简单命令的使用

    1.show databases; -- 显示当前连接下的数据库 2.use db_name;   -- 使用当前数据库db_name 3.show tables;      -- 显示当前数据库下数 ...