• Silverlight版拼图游戏


         Silverlight2.0出来也有一段时间了,一直想好好学学,主要是考虑将来使用Silverlight做数据结构方面的动画及课件,这样可以很方便地挂在网上观看。前几天终于下定决心学习。这几天的感觉就是很庆幸之前没有学得太早,测试版跟正式版之前有不少改动,还好没做小白鼠。不过现在学其实还是逃不出小白鼠的命运,感觉Silverlight将来还会有不少改动。

         拼图游戏相信很多人玩过,之前我在《C#程序设计基础教程与实训》中使用WindowForm应用程序实现过,共84行代码,很精简。学了一些Silverlight后,我就迫不急待地想使用Silverlight实现这个游戏,因为我对Silverlight的期待就是可以像WindowForm一样很方便地编程。但实践证明,两者还是有一定差距的,希望Silverlight3.0或4.0版本可以做到这点。

         好,先来看看效果,这里需要注意,必须安装Silverlight 2.0 RTW 才能正常运行游戏,下载地址:http://www.microsoft.com/silverlight/resources/install.aspx?v=2.0

         猜猜她是谁?

        

         在程序中自定义了一个控件Img,也就是C# WindowForm中的Image控件,虽然Silverlight中也有Image控件,但没有ImageList控件,控制起来也不是很方便,所以将Image做进一步地包装可以使代码更容易读懂,看上去更舒服些。

         首先新建一个Silverlight项目,起名为PictureGame。找一张完整的240*240的图片分割分9等份,命名为“pic0”至“pic9”。把这9张图片加入到项目中。在【解决方案资源管理器】中,右击PictureGame项目,在弹出菜单中选中【添加】→【新建项】,在弹出的【添加新项窗口】中选中【Silverlight用户控件】,给控件起名“Img”,点确定。

         【Img.xaml】文件的代码如下所示:

    <UserControl x:Class="PictureGame.Img"
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas x:Name="LayoutRoot" Width="80" Height="80">
    <Image x:Name="image" Width="80" Height="80"/>
    <Rectangle x:Name="border" Stroke="DimGray" StrokeThickness="2"
    Width
    ="80" Height="80"
    Canvas.Left
    ="0" Canvas.Top="0">
    </Rectangle>
    </Canvas>
    </UserControl>
    
    

    这里主要是在Canvas中放一个Image控件,然后加上边框。

          接下来按F7切换到【Img.xaml.cs】文件,输入新代码将如下所示:

    using System;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;

    namespace PictureGame
    {
    public partial class Img : UserControl
    {
    public Img()
    {
    InitializeComponent();
    }
    int index;
    public double Left
    {
    get { return (double)this.GetValue(Canvas.LeftProperty); }
    set { this.SetValue(Canvas.LeftProperty, value); }
    }
    public double Top
    {
    get { return (double)this.GetValue(Canvas.TopProperty); }
    set { this.SetValue(Canvas.TopProperty, value); }
    }
    public bool Visible //是否可见
    {
    get { return image.Opacity == 0.0; }
    set { image.Opacity = value ? 100.0 : 0.0; }
    }
    public bool BorderVisible //边框可见性
    {
    get { return border.Opacity == 0.0; }
    set { border.Opacity = value ? 100.0 : 0.0; }
    }
    public BitmapImage Source //Image中显示的图片
    {
    set { image.Source = value; }
    }
    public int ImageIndex //图片在数组中的索引号
    {
    get { return index; }
    set { index = value; }
    }
    }
    }
    
    
    
    
    这里实际上就是对Image控件做个包装,使得我们可以像在C# WindowForm一样使用控件。有一个问题没弄明白,就是如何使用程序控制控件的可见性,一时没找到,只好使用Opacity属
    
    性来摸拟了。
    接下来更改程序的主xaml文件【Page.xaml】:
    
    
    <UserControl x:Class="PictureGame.Page"
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    FontFamily
    ="微软雅黑" FontSize="12"
    Width
    ="260" Height="315"
    Loaded
    ="UserControl_Loaded">
    <Canvas x:Name="LayoutRoot" Background="Chocolate">
    <Rectangle Stroke="DimGray" StrokeThickness="2"
    Width
    ="244" Height="244"
    Canvas.Left
    ="8" Canvas.Top="8"/>
    <Button x:Name="btnStart" Width="80" Height="23"
    Canvas.Left
    ="90" Canvas.Top="260"
    Content
    ="开始游戏" Click="btnStart_Click"/>
    <TextBlock x:Name="msgBox" Width="260" Height="20"
    Canvas.Left
    ="0" Canvas.Top="288" TextAlignment="Center"
    Foreground
    ="White" Text="http://www.cnblogs.com/abatei"/>
    </Canvas>
    </UserControl>
    
    
    这里画了一个矩形边框,一个按钮和一个用于显示消息的TextBlock。注意在
    Loaded="UserControl_Loaded"
    Click="btnStart_Click"
    两句代码上左击选中【定位到事件处理程序】可以在cs文件中自动生成相应的事件方法,很方便。
    最后在【Page.xaml.cs】文件中输入如下代码:
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media.Imaging;

    namespace PictureGame
    {
    public partial class Page : UserControl
    {
    public Page()
    {
    InitializeComponent();
    }
    Img[,] imgs
    = new Img[3, 3];
    BitmapImage[] bmps
    = new BitmapImage[9];
    int unRow = 0, unCol = 0;
    bool playing = false;
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
    for (int i = 0; i < 9; i++)
    {
    bmps[i]
    = new BitmapImage(new Uri("pic" + i.ToString() + ".jpg", UriKind.Relative));
    }
    for (int i = 0; i < 9; i++)
    {
    Img img
    = new Img();
    img.MouseLeftButtonDown
    += new MouseButtonEventHandler(img_MouseLeftButtonDown);
    img.Left
    = 10.0 + i % 3 * 80.0;
    img.Top
    = 10.0 + i / 3 * 80.0;
    LayoutRoot.Children.Add(img);
    imgs[i
    / 3, i % 3] = img;
    }
    }
    //开始游戏按钮
    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
    imgs[unRow, unCol].Visible
    = true;
    int[] arrNum = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
    Random rm
    = new Random();
    for (int i = 0; i < 8; i++)
    {
    int rmNum = rm.Next(i, 9);
    int temp = arrNum[i];
    arrNum[i]
    = arrNum[rmNum];
    arrNum[rmNum]
    = temp;
    }
    for (int i = 0; i < 9; i++)
    {
    imgs[i
    / 3, i % 3].Source = bmps[arrNum[i]];
    imgs[i
    / 3, i % 3].ImageIndex = arrNum[i];
    imgs[i
    / 3, i % 3].BorderVisible = true;
    }
    int cover = rm.Next(0, 9);
    unRow
    = cover / 3;
    unCol
    = cover % 3;
    imgs[unRow, unCol].Visible
    = false;
    playing
    = true;
    }
    //鼠标单击事件
    void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    if (!playing)
    {
    return;
    }
    int row = (int)((Img)sender).Top / 80;
    int col = (int)((Img)sender).Left / 80;
    if (Math.Abs(row - unRow) + Math.Abs(col - unCol) == 1)
    {
    int temp = imgs[unRow, unCol].ImageIndex;
    imgs[unRow, unCol].ImageIndex
    = imgs[row, col].ImageIndex;
    imgs[unRow, unCol].Source
    = bmps[imgs[row, col].ImageIndex];
    imgs[row, col].ImageIndex
    = temp;
    imgs[row, col].Source
    = bmps[temp];
    imgs[unRow, unCol].Visible
    = true;
    imgs[row, col].Visible
    = false;
    unRow
    = row;
    unCol
    = col;
    }
    for (int i = 0; i < 9; i++)
    {
    if (imgs[i / 3, i % 3].ImageIndex != i)
    {
    break;
    }
    if (i == 8)
    {
    imgs[unRow, unCol].Visible
    = true;
    foreach (Img img in imgs)
    {
    img.BorderVisible
    = false;
    }
    playing
    = false;
    msgBox.Text
    = "恭喜您通过游戏!";
    }
    }
    }
    }
    }
    
    
    大功告成,这里需要注意,有一半的机会会碰到无解的情况,最方便的判断就是如果将两个相邻的图片调换就可以完成游戏,那么这是无解的。
  • 相关阅读:
    JS 跨域问题。。
    LInq 中使用正则表达试
    CreateXMl
    DeleteXMl
    SameNameFile 比较两个文件夹是否同名
    UpdateXML
    AddXML
    AsDataView Dataview ,DataTable 跟linq的相互转化
    AttributeToElement
    WoreTime 计算单词出现的次数
  • 原文地址:https://www.cnblogs.com/abatei/p/1338920.html
Copyright © 2020-2023  润新知