昨天逛论坛,看到一个哥们用WPF做了一个9宫的拼图游戏,发现初学WPF的人都很容易犯一个错误(我也犯过):把WPF当WINFORM用!所以想写一个比较符合WPF风格的版本,于是就抽工作的空余时间做了一个,其实就是很久没写博客了,写个出来凑数o(╯□╰)o。效果如下:

(图片为:阿普利亚GPR125)

  代码简要解释:主窗口,只是生成核心类,和绑定主要事件(比较简单,就没有使用什么Command之类的了),主要逻辑都在VM类里面

    public partial class MainWindow : Window
{
PicManager manager; public MainWindow()
{
InitializeComponent();
manager = new PicManager("", , );
} private void Window_Loaded(object sender, RoutedEventArgs e)
{
DataContext = manager;
} private void Kong_KeyDown(object sender, KeyEventArgs e)
{
switch(e.Key)
{
case Key.Up:
manager.MovePic(Direction.D_Up);
break;
case Key.Down:
manager.MovePic(Direction.D_Down);
break;
case Key.Left:
manager.MovePic(Direction.D_Left);
break;
case Key.Right:
manager.MovePic(Direction.D_Right);
break;
case Key.R:
manager.Random();
break;
} if (manager.Step!=&&manager.CheckOVER())
{
MessageBox.Show("YOU WIN!");
manager.Step = ;
}
}
}
PicModel:小拼图模型类,只有一个ID,用于保存数据。
    class PicMod
{
public int ID { set; get; } public PicMod(int i)
{
ID = i;
}
}
PicViewMod:是每一个小拼图model的视图viewmodel封装类,当小拼图ID变化,会通过WPF的绑定功能,自动更新界面的图片,而不是用事件去刷新重绘!这是WPF和WINFROM之间的一个最大区别!
    class PicViewMod : INotifyPropertyChanged
{
PicMod pic;
public event PropertyChangedEventHandler PropertyChanged; public PicViewMod(int i)
{
pic = new PicMod(i);
}
public int ID
{
set
{
if (pic.ID != value)
{
pic.ID = value;
PropertyChanged(this, new PropertyChangedEventArgs("ID"));
}
} get
{
return pic.ID;
}
}
}
PicManager :主要封装了9个小拼图块,和一些操作函数,包括移动块,生成随机拼图(只是循环模拟调用了移动块的函数)
  //拼图面板VM
class PicManager : INotifyPropertyChanged
{
public ObservableCollection<PicViewMod> Pics { set; get; }
public event PropertyChangedEventHandler PropertyChanged;
int _step;
int _pos;//空白块当前位置
int _colum, _row;//行列数
public int Step
{
set
{
if (_step != value)
{
_step = value;
PropertyChanged(this, new PropertyChangedEventArgs("Step"));
}
} get
{
return _step;
}
}
public PicViewMod Ori { set; get; }//原图
public PicManager(string path, int col, int row)
{
Pics = new ObservableCollection<PicViewMod>();
_colum = col;
_row = row;
_pos = ;
_step = ;
Ori = new PicViewMod(col * row);
for (int x = ; x < _colum; x++)
{
for (int y = ; y < _row; y++)
{
Pics.Add(new PicViewMod(x * _row + y));
}
}
} void ClipPic(string path)
{ } public void MovePic(Direction dir)
{
switch (dir)
{
case Direction.D_Up://键盘的向上,实际就是空白块的向下
{
if (_pos / _colum < _row - )
{
int id = Pics[_pos + _colum].ID;
Pics[_pos + _colum].ID = Pics[_pos].ID;
Pics[_pos].ID = id;
_pos += _colum;
Step++;
}
}
break;
case Direction.D_Down:
{
if (_pos / _colum > )
{
int id = Pics[_pos - _colum].ID;
Pics[_pos - _colum].ID = Pics[_pos].ID;
Pics[_pos].ID = id;
_pos -= _colum;
Step++;
}
}
break;
case Direction.D_Left:
{
if (_pos % _colum < _colum - )
{
int id = Pics[_pos + ].ID;
Pics[_pos + ].ID = Pics[_pos].ID;
Pics[_pos].ID = id;
_pos += ;
Step++;
}
}
break;
case Direction.D_Right:
{
if (_pos % _colum > )
{
int id = Pics[_pos - ].ID;
Pics[_pos - ].ID = Pics[_pos].ID;
Pics[_pos].ID = id;
_pos -= ;
Step++;
}
}
break;
} }
public bool CheckOVER()
{
for (int i = ; i < _row * _colum; i++)
{
if (Pics[i].ID != i)
return false;
}
return true;
}
public void Random(int count)
{
System.Random rand = new System.Random((int)DateTime.Now.Ticks);
for (int i = ; i < count; i++)
{
int d = rand.Next(, );
MovePic((Direction)d);
}
Step = ;
}
} }

 VIEW的XAML定义:使用ItemsContrl来展示Image

<Window x:Class="NineKong.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NineKong"
Title="拼图游戏" Height="494" Width="849" Loaded="Window_Loaded" KeyDown="Kong_KeyDown">
<Window.Resources>
<local:DataConverter x:Key="conver"></local:DataConverter>
</Window.Resources>
<Canvas Name ="Kong">
<ItemsControl Height="454" Width="607" Name ="Nine" ItemsSource="{Binding Pics}" Background="Cyan">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemHeight="135" ItemWidth="200"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Margin="2" Source="{Binding ID,Converter={StaticResource conver}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Image Height="145" Width="219" Canvas.Left="612" Source="{Binding Ori.ID ,Converter={StaticResource conver}}" Canvas.Top="10"/>
<TextBlock Canvas.Left="726" TextWrapping="Wrap" Text="{Binding Step}" FontSize="35" Canvas.Top="160" Width="105" Height="42"/>
</Canvas> </Window>

   其他具体实现请查看源代码,代码比较简单,所以并没有什么注释。总的来说个人觉得WINFORM和WPF的主要差别:一个是事件驱动,一个是数据驱动!由于时间比较仓促,然后对WPF其实也不是很熟练(很早以前自学过2个月,然后基本没用过了,其实这是写的第一个比较完整的WPF程序),很多东西概念知道,但是真的用起来发现比较吃力,边百度边实验,对图片的操作和GDI+模式差别比较大,所以没有实现通过指定的图片按指定大小切图来自定义游戏。。。不过这篇博客主要是想演示一下WPF和WINFORM差别,真的非常大!所以也就不要太在意某些细节。。。

九宫拼图源码 下载

9宫拼图小游戏(WPF MVVM实现)的更多相关文章

  1. JavaScript版拼图小游戏

    慕课网上准备开个新的jQuery教程,花了3天空闲时间写了一个Javascript版的拼图小游戏,作为新教程配套的分析案例 拼图游戏网上有不少的实现案例了,但是此源码是我自己的实现,所以不做太多的比较 ...

  2. 使用NGUI实现拖拽功能(拼图小游戏)

    上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...

  3. jQuery实现拼图小游戏

    小熊维尼拼图                                                                                    2017-07-23 ...

  4. jQuery拼图小游戏

    jQuery拼图小游戏 最后样式 核心代码部分 <script type="text/javascript" > $(function () { $("td& ...

  5. 在HTML页面中有jQuery实现实现拼图小游戏

    1.用jQuery实现拼图小游戏 2.首先获得td的点击事件.再进行交换位置 3.下面这种仅供参考 4.下面这些是HTMl标签 当这个世界变得越来越复杂的时候,内心最需保持一份简单一份纯真:

  6. 仿苹果电脑任务栏菜单&&拼图小游戏&&模拟表单控件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. swift 拼图小游戏

    依据这位朋友的拼图小游戏改编 http://tangchaolizi.blog.51cto.com/3126463/1571616 改编主要地方是: 原本着我仁兄的代码时支持拖动小图块来移动的,我參照 ...

  8. 教你用Python自制拼图小游戏,一起来制作吧

    摘要: 本文主要为大家详细介绍了python实现拼图小游戏,文中还有示例代码介绍,感兴趣的小伙伴们可以参考一下. 开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Pyt ...

  9. 打造专属自己的html5拼图小游戏

    最近公司刚好有个活动是要做一版 html5的拼图小游戏,于是自己心血来潮,自己先实现了一把,也算是尝尝鲜了.下面就把大体的思路介绍一下,希望大家都可以做出一款属于自己的拼图小游戏,必须是更炫酷,更好玩 ...

随机推荐

  1. 最近因为突然喜欢这方面的ui设计,所以搜刮了很多我试过可用性强的界面,又可爱又实用···分享给大家咯

    最近因为突然喜欢这方面的ui设计,所以搜刮了很多我试过可用性强的界面,又可爱又实用···分享给大家咯 1.Side-Menu.Android 分类侧滑菜单,Yalantis 出品. 项目地址:http ...

  2. python与html5 websocket开发聊天对话窗

    1.下载必须的包 https://github.com/Pithikos/python-websocket-server,解压缩并把文件夹名‘python-websocket-server-maste ...

  3. 商家中心FAQ

    1.订购的账号为什么不生成子账号,生成了一个主账号,进店铺里面看子账号也没有 原因:授权失败了,数据库没有生成店铺授权信息 解决方案:重新授权

  4. Bresenham算法的实现思路

    条件已知两个点的坐标p1(x0,y0),p2(x1,y1)要求画出这条直线 之后的e代表每次的误差积累,初始值为0,可以计算出斜率为k=dy/dx=(y0-y1)/(x0-x1) 1.x为阶跃步长(直 ...

  5. jQuery ajax()使用serialize()提交form数据到后台

    1.选中要删除的学生信息 2.点击 删除选中 按钮,把复选框中的值取出提交到后台 3.后台获取选中的id 4.前端也跟着删除数据 示例代码: 前端代码: <!DOCTYPE html> & ...

  6. List删除

    使用for循环,倒序删除: ; i >= ; i--) { var item = list[i]; ") { list.Remove(item); } }

  7. 简单易懂的程序语言入门小册子(5):基于文本替换的解释器,递归,不动点,fix表达式,letrec表达式

    这个系列有个显著的特点,那就是标题越来越长.忽然发现今天是读书节,读书节多读书. ==下面是没有意义的一段话============================================== ...

  8. C# -- 索引器、枚举类型

    C# -- 索引器.枚举类型 索引器允许类或结构的实例就像数组一样进行索引. 无需显式指定类型或实例成员,即可设置或检索索引值. 索引器类似于属性,不同之处在于它们的访问器需要使用参数. 1. 索引器 ...

  9. 4.4Python数据处理篇之Matplotlib系列(四)---plt.bar()与plt.barh条形图

    目录 目录 前言 (一)竖值条形图 (二)水平条形图 1.使用bar()绘制: 2.使用barh()绘制: (三)复杂的条形图 1.并列条形图: 2.叠加条形图: 3.添加图例于数据标签的条形图: 目 ...

  10. 【算法】LeetCode算法题-Maximum Subarray

    这是悦乐书的第154次更新,第156篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第13题(顺位题号是53).给定一个整数数组nums,找出一个最大和,此和是由数组中索引 ...