这是我用C#做的第一款小游戏,算法有点复杂,当我移植到 IOS 中的时候,我发现了一个更简单的算法.这个以后再讲.

先看一下这个Winform程序

游戏的界面是这样的,看着很简单

  wKiom1RNtD-gZxrnAAHDceR-M_Y750.jpg

 1.左侧显示分割后的图片的,第一个为空

 2.右侧上部是选择你要生成的 图像距阵

 3.右侧中部是切换拼图使用的图片,可以选择系统自带的,也可以自定义

 4.下边有一个状态栏,主要显示是否开始,以及所走的步数,

 5.当你拼图完成的时候,就会弹出一个提示对话框


下面开始介绍一下算法思路:用 a ,s ,d,w 来控制方向

  1. 先定义一个p_w_picpath 的集合,用来存储分割后的图片

  2. 定义一个图片位置Dictionary,用来存储 小图位置与小图资源

  3. 定义初始位置PointX,PointY,因为第一个图片为空,所以初始值为0

  4. 当你按下A的时候,PointX向右移动一位,将右边的图片赋值给左边,当前位置设置为空,这样就实现了图片的向左移动

  5. 当你按下S键的时候,PointY向上移动一位,将上面的图片给下边,当前位置设置为空,这样就实现了图片的向下移动

  6. 当你按下D的时候,与A的恰好相反,按下W时,与S的算法相反(注意PointX,PointY的大小,不能越界)

  7. 状态检测,每走一步就检测一下是否完成,我这里用的是判断图片是否与集合中同样下标的图片数据相等来检测的,


下面贴一下代码:


开始按钮:

//开始按钮
        private void btnStart_Click(object sender, EventArgs e)
        {
            PointX = 0;
            PointY = 0;
            stepCount = 0;
            Dictionary<string, Image> dic = new Dictionary<string, Image>();
            Random random = new Random();
            int diccount = 0;
            int c = random.Next(0, Imagecol);
            int r = random.Next(0, Imagerow);
            while (dic.Count < (Imagecol * Imagerow - 1))
            {
                if (c == 0 && r == 0)
                {
                    c = random.Next(0, Imagecol);
                    r = random.Next(0, Imagerow);
                    continue;
                }
                if (!dic.ContainsValue(p_w_picpaths[r, c]))
                {
                    dic.Add(diccount.ToString(), p_w_picpaths[r, c]);
                    diccount++;
                }
                c = random.Next(0, Imagecol);
                r = random.Next(0, Imagerow);
            }
            //布局
            for (int i = 0; i < panel1.Controls.Count; i++)
            {
                PictureBox p = panel1.Controls[i] as PictureBox;
                p.Image = null;
                if (i != 0)
                {
                    p.Image = dic[(i - 1).ToString()];
                }
            }
            toolStripStatusLabel1.Text = "你共走了 " + stepCount.ToString() + " 步!";
        }

分割图像算法:

 public static Image[,] GetImages(Image img, int col, int row, int width, int height)
        {
            Image[,] imgs = new Image[row, col];
            int iwidth = width / col;//每块多宽
            int iheight = height / row;//每块多高
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    #region
                    /*
                    //先初始化一个位图对象,来存储截取后的图像
                    Bitmap bmpDest = new Bitmap(iwidth, iheight, PixelFormat.Format32bppRgb);
                    //这个矩形定义了,你将要在被截取的图像上要截取的图像区域的左顶点位置和截取的大小
                    Rectangle rectSource = new Rectangle(j * iwidth, i * iheight, iwidth, iheight);
                    //这个矩形定义了,你将要把 截取的图像区域 绘制到初始化的位图的位置和大小
                    //我的定义,说明,我将把截取的区域,从位图左顶点开始绘制,绘制截取的区域原来大小
                    Rectangle rectDest = new Rectangle(0, 0, iwidth, iheight);
                    //第一个参数就是加载你要截取的图像对象,第二个和第三个参数及如上所说定义截取和绘制图像过程中的相关属性,第四个属性定义了属性值所使用的度量单位
                    // g.DrawImage(img, rectDest, rectSource, GraphicsUnit.Pixel);*/
                    #endregion
                    Bitmap bm = new Bitmap(iwidth, iheight, PixelFormat.Format24bppRgb);
                    Graphics g = Graphics.FromImage(bm);
                    g.DrawImage(img, new Rectangle(0, 0, iwidth, iheight), new Rectangle(j * iwidth, i * iheight, iwidth, iheight), GraphicsUnit.Pixel);
                    imgs[i, j] = (Image)bm;
                    g.Dispose();
                }
            }
            p_w_picpaths = imgs;
            return imgs;
        }

检测是否完成游戏:(遍历panel 中所有的控件,判断他们的p_w_picpath 是否和集合中对应的p_w_picpath相等)

  public static bool CheckImageGamesComplate(Panel panel, int row, int col)
        {
            bool win = false;
            try
            {
                int pStart = 0;
                for (int i = 0; i < row; i++)
                {
                    for (int j = 0; j < col; j++)
                    {
                        PictureBox pic = panel.Controls.Find(pStart.ToString(), true)[0] as PictureBox;
                        if (i == 0 && j == 0)
                        {
                            if (pic.Image != null)
                            {
                                return false;
                            }
                        }
                        else if (pic.Image == p_w_picpaths[i, j])
                        {
                            win = true;
                        }
                        else
                        {
                            return false;
                        }
                        pStart++;
                    }
                }
            }
            catch
            {
                return false;
            }
            return win;
        }

具体的源码请到 http://down.51cto.com/data/1889879 下载