接着上一篇继续~~~

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. SpringBoot(七) SpringBoot整合Log4j

    第一种打印debug日志方式: logging.level.com.demo.mapper: debug 第二种打印debug日志方式: 在resource文件夹下新建:logback.xml < ...

  2. maven新建项目的几种方式和启动

    方式一: 第1步:转到 New 菜单 Other.. -> Maven -> Maven Project ,然后单击 Next .如下图所示 - 第2步:在New Maven Projec ...

  3. Spring Boot的注解,你知道或者不知道的都在这里!

    1.1 定义 Annotation(注解),用于为Java代码提供元数据.简单理解注解可以看做是一个个标签,用来标记代码.是一种应用于类.方法.参数.变量.构造器及包的一种特殊修饰符. 1.2 注解的 ...

  4. python web框架Django入门

    Django 简介 背景及介绍 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以 ...

  5. JS基础语法---分支语句总结

    分支语句: if语句:一个分支 if-else语句:两个分支,最终只执行一个分支 if-else if-else if...语句: 多个分支,也是只会执行一个 switch-case语句:多分支语句, ...

  6. JavaScript操作数据库JS操作Access数据库

    avaScript操作数据库JS操作Access数据库,跟其他语言操作差不多,总结了一下习惯代码,仅供参考学习.现在在F盘有文件abc.mdf,表名为Student,一共2个字段,Id数字类型主键,s ...

  7. 使用Wireshark进行DNS协议解析

    - 域名及解析过程 域名由一系列 - DNS协议报文格式 一次DNS过程包含一对请求报文和响应报文.请求和响应报文有统一的报文格式如下图: - DNS报文例子 一次DNS请求的过程: 包括请求和响应, ...

  8. LayoutSubviews的调用

    1.当view被添加到另一个view上时调用 2.布局子控件时调用 3.屏幕旋转的时候调用 4.当view的尺寸大小改变的时候调用

  9. Oracle有哪些诊断事件

    作者:eygle | [转载请注出处]链接:https://www.eygle.com/archives/2004/12/oracle_diagnostics_events_list.html 经常有 ...

  10. nginx 文件服务器配置,模板配置文件,有注释

    # For more information on configuration, see: # * Official English Documentation: http://nginx.org/e ...