练手WPF(二)——2048游戏的简易实现(下)
接着上一篇继续~~~
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游戏的简易实现(下)的更多相关文章
- 练手WPF(三)——扫雷小游戏的简易实现(中)
八.随机布雷 /// <summary> /// 随机布地雷 /// </summary> /// <param name="mineNum"> ...
- 练手WPF(一)——模拟时钟与数字时钟的制作(上)
一.Visual Studio创建一个WPF项目. 简单调整一下MainWindow.xaml文件.主要使用了两个Canvas控件,分别用于显示模拟和数字时钟,命名为AnalogCanvas.digi ...
- 练手WPF(二)——2048游戏的简易实现(上)
1.创建游戏界面编辑MainWindow.xaml,修改代码如下: <Window.Resources> <Style TargetType="Label"> ...
- 练手WPF(三)——扫雷小游戏的简易实现(上)
一.创建项目1.创建WPF项目,设置初始化窗口大小(初级难度):高x宽为430x350.2.添加文件夹Images,并添加相关图片. 3.xaml中引入图片资源. <Window.Resourc ...
- 练手WPF(四)——贪吃蛇小游戏的简易实现(上)
一. 游戏界面首先,按照惯例,编辑MainWindow.xaml,先将游戏界面制作好.非常简单:(1)主游戏区依然使用我们熟悉的Canvas控件,大小为640X480像素,设定每小格子为20px,所以 ...
- 练手WPF(三)——扫雷小游戏的简易实现(下)
十四.响应鼠标点击事件 (1)设置对应坐标位置为相应的前景状态 /// <summary> /// 设置单元格图样 /// </summary> /// <para ...
- 练手WPF(四)——贪吃蛇小游戏的简易实现(下)
八.生成新的单节蛇身我们这里先说说游戏小原理好了,游戏运行后,通过计时器事件不断生成新的单节蛇身类SnakeNode,添加到List中的0位置,原来的蛇头变成了第二节.该节新蛇头的坐标通过蛇头前进方向 ...
- 微信小程序框架分析小练手(二)——天气微信小程序制作
简单的天气微信小程序. 一.首先,打开微信开发者工具,新建一个项目:weather.如下图: 二.进入app.json中,修改导航栏标题为“贵州天气网”. 三.进入index.wxml,进行当天天气情 ...
- 练手WPF(一)——模拟时钟与数字时钟的制作(中)
今天接着制作数字时钟 数字时钟主要用到Path控件,主要用于定义数字笔划的形状. (1)添加一个DigitLine类 数字时钟的数字8由7笔组成,看如下定义的字段字符串数组PathDatas,每个st ...
随机推荐
- C++ 流插入"<<"和流提取">>"运算符的重载
01 流插入<<运算符的重载 C++ 在输出内容时,最常用的方式: std::cout << 1 <<"hello"; 问题: 那这条语句为什么 ...
- react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN ...
- Linux下用户管理:删除用户
基本语法: userdel 用户名 但是我们在删除用户的时候很显然需要利用root用户权限来进行删除才是可以的.但是利用这种方法进行删除的话是会保留家目录的,意思是该用户所对应的家目录不会被删除. 不 ...
- LayoutSubviews的调用
1.当view被添加到另一个view上时调用 2.布局子控件时调用 3.屏幕旋转的时候调用 4.当view的尺寸大小改变的时候调用
- 版本管理·玩转git(分支管理)
在开发中,遇到这样的情况怎么办? 网站已有支付宝在线支付功能,要添加"微信支付",修改了两个文件,wechat.php.pay.php. 刚做到一半,突然有个紧急bug:支付宝支付 ...
- jqs实现图片轮播--通过点击按钮来实现
<!-- 布局思路:一个大的div,中有一个ul.和一个箭头的div css样似描述: 整个盒子距离顶部100px,又水平居中 盒子的宽高为图片的实际宽高 由于每次都是看见了一张图片:有两种方式 ...
- 初学JavaScript正则表达式(十)
前瞻与后顾 断言 === assert 符合断言为正向,不符合为负向 例 'a2*3'.replace(/\w(?=\d)/g,'x') ------- x2*3 看看'\d'前面是不是'\w',如果 ...
- 数据库连接池 DBUtils:
import pymysqlfrom DBUtils.PooledDB import PooledDB, SharedDBConnectionPOOL = PooledDB ( creator=pym ...
- Spring配置文件中的那些标签
1. context:annotation-config 它的作用是隐式地向Spring容器注册AutowiredAnnotationBeanPostProcessor,CommonAnnotatio ...
- 洛谷 P5596 【XR-4】题
洛谷 P5596 [XR-4]题 洛谷传送门 题目描述 小 X 遇到了一道题: 给定自然数 a,ba,b,求满足下列条件的自然数对 (x,y)(x,y) 的个数: y^2 - x^2 = ax + b ...