• 9宫拼图小游戏(WPF MVVM实现)


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

    (图片为:阿普利亚GPR125)

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

        public partial class MainWindow : Window
        {
            PicManager manager;
    
            public MainWindow()
            {
                InitializeComponent();
                manager = new PicManager("", 3, 3);
            }
    
            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(50);
                        break;
                }
    
                if (manager.Step!=0&&manager.CheckOVER())
                {
                    MessageBox.Show("YOU WIN!");
                    manager.Step = 0;
                }
            }
        }
    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 = 0;
                _step = 0;
                Ori = new PicViewMod(col * row);
                for (int x = 0; x < _colum; x++)
                {
                    for (int y = 0; 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 - 1)
                            {
                                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 > 0)
                            {
                                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 - 1)
                            {
                                int id = Pics[_pos + 1].ID;
                                Pics[_pos + 1].ID = Pics[_pos].ID;
                                Pics[_pos].ID = id;
                                _pos += 1;
                                Step++;
                            }
                        }
                        break;
                    case Direction.D_Right:
                        {
                            if (_pos % _colum > 0)
                            {
                                int id = Pics[_pos - 1].ID;
                                Pics[_pos - 1].ID = Pics[_pos].ID;
                                Pics[_pos].ID = id;
                                _pos -= 1;
                                Step++;
                            }
                        }
                        break;
                }
    
            }
            public bool CheckOVER()
            {
                for (int i = 0; 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 = 0; i < count; i++) { int d = rand.Next(0, 4); MovePic((Direction)d); } Step = 0; } } }

     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差别,真的非常大!所以也就不要太在意某些细节。。。

    九宫拼图源码 下载

  • 相关阅读:
    js 正则表达式
    JAVA jdk环境搭建
    VMWareStation10 密钥
    linux xshell jdk hadoop(环境搭建) 虚拟机 安装(大数据搭建环境)
    linux hadoop jdk虚拟机下配置
    Linux shell基础(四)
    Linux shell基础(二)
    Linux shell基础(三)
    Linux shell基础(一)
    html
  • 原文地址:https://www.cnblogs.com/HelliX/p/5737194.html
Copyright © 2020-2023  润新知