zoukankan      html  css  js  c++  java
  • windows phone7 项目一连连看源码 及说明

                   连连看游戏是老少爷们喜爱玩的游戏,   因此  我就 写了 连连看游戏。   

            要完成一个连连看游戏,以面向对象的思想 来思考这个游戏。首先, 我需要一个类

            每个连连看的需要 连连看的画框, 由于要设置不同级别,因此要 一个游戏级别的类。

            你怎么能确保正确的开展游戏 因此  需要游戏的引擎。  

              他的类图如下:

             

                                               你会问我GameConfig 这个类究竟是干什么的,英译过来就是游戏的配置的类,简而言之,就是放游戏的配置文件的类吗,这是

    放游戏更加的有趣,加载相应的背景音乐和背景图片的效果 。 那startMenu 又是什么啊,加载的开始的窗口 进行一些游戏参数配置的页面。

    那topMenu 只不过是顶级的菜单,

    相当于显示栏与游戏重置栏把 

      各行各业的软件有不同的侧重点把,比如 普通系统的软件侧重点是业务知识的精通把,而互联网网站也分成几个层次,首先网站的都要侧重的是性能的优化,而像google,度娘

    这样的搜索引擎他更突出与算法是别致,而像facebook,人人网这样的社交网络更倾向与社会工程学的展示。游戏的核心是巧夺天工的算法与别出心裁的玩法设置。 

         而 我这是一个简单的游戏,  麻雀虽小五脏俱全,  他有一个相应的算法     

        游戏要将  相应的 图片杂乱无章展示出来,此时需要一个FillBoard(初始化砖块)方法      

        首先 确定这是在相应的画布上来作图,产生相应级别的所产生数目一半组数的砖块(譬如说这个级别的产生60个图片,我此时就通过这个方法产生30组相应配对的图片)。再通过相应的随机的函数来放在画布不同的位置。你会问我怎么能使游戏可连。因为能确定相应的边线 ,底线可连。根据相应的数学知识证明之,此游戏是可玩的

      最终的效果图如下

    相应的源代码如下:

    public static void FillGrid()
    {
    GameBackGrid.Width = CurLevel.Backgrid.X * ItemSize.Width;
    GameBackGrid.Height = CurLevel.Backgrid.Y * ItemSize.Height;

    List<ImgItem> CreatedItems = new List<ImgItem>();
    Random rand = new Random();

    for (int i = 0; i < ItemCount / 2; i++)
    {
    int index = rand.Next(CurLevel.BackGrid.Length - 1);
    ImgItem item = new ImgItem();

    item.ItemImg = CurLevel.BackGrid[index];

    ImgItem item2 = new ImgItem() { ItemImg = item.ItemImg };
    item.SelectIt += item_SelectIt;
    item2.SelectIt += item_SelectIt;

    CreatedItems.Add(item);
    CreatedItems.Add(item2);
    }

    for (int i = 0; i < ItemCount; i++)
    {
    int x = (int)(i % CurLevel.Backgrid.X);
    int y = (int)(i / CurLevel.Backgrid.X);

    int index = rand.Next(CreatedItems.Count - 1);
    ImgItem item = CreatedItems[index];
    item.Width = ItemSize.Width;
    item.Height = ItemSize.Height;
    item.Location = new Point(x, y);
    item.Parent = GameBackGrid;
    item.Show();
    AllItems[x][y] = item;
    CreatedItems.Remove(item);
    }
    }

    连连看 中最关键,最核心的算法就是  相连的算法  一般底线,边线的方块上的图片和相邻方块上的图片是可以相连的。如果两张方块上的图片是没有其他方块相连的。

    我这里是由于十字形的上没有相隔的头像相同的图片是可以相连的。  相连就是用以循环来遍历周围图片是否有间隔图片,如果没有相应的间隔是可以相连的。

    相应算法的源代码如下:

    #region 二点是否可连算法

    /// <summary>
    /// 判断二个点是否可以连
    /// </summary>
    /// <param name="item1"></param>
    /// <param name="item2"></param>
    /// <returns></returns>
    public static bool IsCanLink(ImgItem item1, ImgItem item2)
    {
    //如果二个图片不相同。则直接返回否.且如果二个为同一个也不可连
    if (item1.ItemImg != item2.ItemImg || item1 == item2) return false;

    ItemDer itemder = GetItemDer(item1, item2);
    switch (itemder)
    {
    case ItemDer.LineX://二点在同一X轴上
    {
    return CheckLineX(item1, item2);
    }
    case ItemDer.LineY://二点在同一Y轴上
    {
    return CheckLineY(item1, item2);
    }
    }
    return false;
    }

    /// <summary>
    /// 在同一X轴上的判断
    /// </summary>
    /// <param name="item1"></param>
    /// <param name="item2"></param>
    /// <returns></returns>
    private static bool CheckLineX(ImgItem item1, ImgItem item2)
    {
    //判断二点间的直线是否可连,或为最顶部点,或为最底部点
    if (CheckInPointsIsEmpty(item1.Location, item2.Location, ItemDer.LineX) || (item1.Location.Y == 0 && item2.Location.Y == 0) ||
    (item1.Location.Y == CurLevel.Backgrid.Y - 1 && item2.Location.Y == CurLevel.Backgrid.Y - 1))
    {
    return true;
    }

    //向上开始判断
    //每次向上伸一个编移量,如果有连通的则可以连
    for (int i = (int)item1.Location.Y - 1; i >= 0; i--)
    {
    Point p1 = new Point(item1.Location.X, i);
    Point p2 = new Point(item2.Location.X, i);
    //如果这二点有任意一点不为空
    //则向上的方向不可行
    if (!CheckPointIsEmpty(p1) || !CheckPointIsEmpty(p2)) break;

    if (CheckInPointsIsEmpty(p1, p2, ItemDer.LineX)) //如果它们之间为空
    {
    return true;
    }

    if (i == 0)//如果这二点为最顶部,所以可以连
    {
    return true;
    }
    }

    //向上开始判断
    //每次向下伸一个编移量,如果有连通的则可以连
    for (int i = (int)item1.Location.Y + 1; i <= CurLevel.Backgrid.Y - 1; i++)
    {
    Point p1 = new Point(item1.Location.X, i);
    Point p2 = new Point(item2.Location.X, i);
    //如果这二点有任意一点不为空
    //则向下的方向不可行
    if (!CheckPointIsEmpty(p1) || !CheckPointIsEmpty(p2)) break;

    if (CheckInPointsIsEmpty(p1, p2, ItemDer.LineX)) //如果它们之间为空
    {
    return true;
    }

    if (i == CurLevel.Backgrid.Y - 1)//如果这二点为最底部,所以可以连
    {
    return true;
    }
    }

    return false;
    }

    /// <summary>
    /// 在同一Y轴上的判断
    /// </summary>
    /// <param name="item1"></param>
    /// <param name="item2"></param>
    /// <returns></returns>
    private static bool CheckLineY(ImgItem item1, ImgItem item2)
    {
    //判断二点间的直线是否可连,或为最左边,或为最右边
    if (CheckInPointsIsEmpty(item1.Location, item2.Location, ItemDer.LineY) || (item1.Location.X == 0 && item2.Location.X == 0) ||
    (item1.Location.X == CurLevel.Backgrid.X - 1 && item2.Location.X == CurLevel.Backgrid.X - 1))
    {
    return true;
    }

    //向左开始判断
    //每次向左伸一个编移量,如果有连通的则可以连
    for (int i = (int)item1.Location.X - 1; i >= 0; i--)
    {
    Point p1 = new Point(i, item1.Location.Y);
    Point p2 = new Point(i, item2.Location.Y);
    //如果这二点有任意一点不为空
    //则向左的方向不可行
    if (!CheckPointIsEmpty(p1) || !CheckPointIsEmpty(p2)) break;

    if (CheckInPointsIsEmpty(p1, p2, ItemDer.LineY)) //如果它们之间为空
    {
    return true;
    }

    if (i == 0)//如果这二点为最左边,所以可以连
    {
    return true;
    }
    }

    //向右开始判断
    //每次向右伸一个编移量,如果有连通的则可以连
    for (int i = (int)item1.Location.X + 1; i <= CurLevel.Backgrid.X - 1; i++)
    {
    Point p1 = new Point(i, item1.Location.Y);
    Point p2 = new Point(i, item2.Location.Y);
    //如果这二点有任意一点不为空
    //则向右的方向不可行
    if (!CheckPointIsEmpty(p1) || !CheckPointIsEmpty(p2)) break;

    if (CheckInPointsIsEmpty(p1, p2, ItemDer.LineY)) //如果它们之间为空
    {
    return true;
    }

    if (i == CurLevel.Backgrid.X - 1)//如果这二点为最右,所以可以连
    {
    return true;
    }
    }

    return false;
    }

    /// <summary>
    /// 判断左上右下的二点
    /// </summary>
    /// <param name="item1"></param>
    /// <param name="item2"></param>
    /// <returns></returns>

    /// <summary>
    /// 判断左下右上的二点
    /// </summary>
    /// <param name="item1"></param>
    /// <param name="item2"></param>
    /// <returns></returns>

    /// <summary>
    /// 判断二点之间是否都为空
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <returns></returns>
    private static bool CheckInPointsIsEmpty(Point p1, Point p2, ItemDer iDer)
    {
    //如果二点为X轴方向
    if (iDer == ItemDer.LineX)
    {
    //如果二点在一起
    if (Math.Abs(p1.X - p2.X) == 1 || (p1.X - p2.X) == 0)
    {
    return true;
    }

    //得到二点的X轴偏移量
    int offsetx = (int)(p1.X - p2.X);
    //p1在p2的左边
    if (offsetx < 0)
    {
    for (int i = 1; i < Math.Abs(offsetx); i++)
    {
    //如果二点之间有不为空的点
    if (!CheckPointIsEmpty(new Point(p1.X + i, p1.Y)))
    {
    return false;
    }
    }
    return true;
    }
    else//1在2的右边
    {
    for (int i = 1; i < Math.Abs(offsetx); i++)
    {
    //如果二点之间有不为空的点
    if (!CheckPointIsEmpty(new Point(p2.X + i, p1.Y)))
    {
    return false;
    }
    }
    return true;
    }
    }
    else if (iDer == ItemDer.LineY) //如果为Y轴方向
    {
    //如果二点在一起
    if (Math.Abs(p1.Y - p2.Y) == 1 || p1.Y - p2.Y == 0)
    {
    return true;
    }

    //得到二点的Y轴偏移量
    int offsety = (int)(p1.Y - p2.Y);
    //p1在p2的上边
    if (offsety < 0)
    {
    for (int i = 1; i < Math.Abs(offsety); i++)
    {
    //如果二点之间有不为空的点
    if (!CheckPointIsEmpty(new Point(p1.X, p1.Y + i)))
    {
    return false;
    }
    }
    return true;
    }
    else//1在2的下边
    {
    for (int i = 1; i < Math.Abs(offsety); i++)
    {
    //如果二点之间有不为空的点
    if (!CheckPointIsEmpty(new Point(p2.X, p2.Y + i)))
    {
    return false;
    }
    }
    return true;
    }
    }

    return false;
    }

    /// <summary>
    /// 检查查此位置是否为空
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    private static bool CheckPointIsEmpty(Point p)
    {
    //foreach (ImgItem item in Config.SLConfig.AllItems)
    //{
    // if (item.Location == p)
    // {
    // return false;
    // }
    //}
    return AllItems[(int)p.X][(int)p.Y] == null;
    }

    /// <summary>
    /// 判断二点的方位
    /// </summary>
    /// <param name="item1"></param>
    /// <param name="item2"></param>
    /// <returns></returns>
    private static ItemDer GetItemDer(ImgItem item1,ImgItem item2)
    {
    if (item1.Location.X == item2.Location.X)
    {
    return ItemDer.LineY;
    }
    if (item1.Location.Y==item2.Location.Y)

    {
    return ItemDer.LineX;
    }
    return ItemDer.Unkown;

    }

    #endregion

    真的 最后我要强调一点的是,这一个方块是一个imgItem 类 他本质是由一个个imgBrush的笔刷将图片画在上面的。那他怎么有点击事件。我这里是通过一个DelegateSelectItem 自定义事件触发了_Rect_MouseLeftButtonDown 完成的

    项目开源地址 http://51aspx.com/Code/WP7LianLianKan

  • 相关阅读:
    paper 66: MATLAB函数—disp的使用
    paper 65 :尺度不变特征变换匹配算法[转载]
    paper 64:尺度空间(Scale space)理论
    paper 63 :函数比较:imfilter与fspecial
    paper 62:高斯混合模型(GMM)参数优化及实现
    paper 61:计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
    paper 60 :转载关于视觉SCI期刊
    paper 59:招聘
    paper 58 :机器视觉学习笔记(1)——OpenCV配置
    paper 57 :颜色直方图的代码
  • 原文地址:https://www.cnblogs.com/manuosex/p/2687310.html
Copyright © 2011-2022 走看看