前端实现连连看小游戏(1)

博主玩了这么久的连连看,居然是第一次发现,连连看最多只能有2个转弯。orz…

在网上搜索连连看的连线算法判断,并没有找到很全面的,经过自己摸索之后,做了一些小动画,希望大家可以看一遍都懂啦~)

 

一. 2个物体在同一直线上,可以直接连通 (这个不需要解释啦)

 

二. 2个对象不在同一直线上,一个转弯

【2个物体分别在所在位置进行x,y轴的延伸,如下图则交点为A,B。 只需判断2个交点到2个物体直接是否有障碍物,若没有,则可以连通】

看动画容易理解一点~

 

 

三. 2个物体不在同一直线上,连线有2个转弯 

【如下图,由于有2个转弯,不同于1个转弯的情况,我们需要有2个拐点。这2个拐点必须在同一个轴上(x轴 或者 y轴),那我们只要分别做这2个点的x轴的延伸,或者y轴的延伸,一个一个取点遍历扫描,若都可以连线,则可以连线~】

 

以上就是四种连线算法判断,动画只列举部分情况,每一种按照同样的原理扫描。可覆盖所有连线判断~

说完连线判断的逻辑之后,写一下整体的游戏框架,游戏基本使用原生javascript,使用createjs游戏引擎进行开发。

 

 代码思路:

1. 绘制游戏画图,确定为多少宫图,由于是在移动端的小游戏,根据最小屏幕尺寸(iphone4  320*480),确定为7*9的宫图。

1. 创建一个二维数组,如果某个坐标上有物体,则设为1,否则为0

2.判断该位置是否有物体,只需要判断对应的二维数组上值是否为1,若为1,则有物体,否则没有。

至于画线,消除相同物体,只要会连线逻辑,肯定就会自己绘制线条,消除物体了,所以本篇文章就只讲连线判断啦~

 

在判断能否连线的时候,肯定是从最简单的方法开始判断,如下:

同一直线能否直线连通--->如何一点被包围,则不通--->两点在一条直线上,不能直线连接但是可以连通---> 不在同一直线但是可以连通

getPath: function (p1, p2) {
            //开始搜索前对p1,p2排序,使p2尽可能的在p1的右下方。
            if (p1.x > p2.x) {
                var t = p1;
                p1 = p2;
                p2 = t;
            }
            else if (p1.x == p2.x) {
                if (p1.y > p2.y) {
                    var t = p1;
                    p1 = p2;
                    p2 = t;
                }
            }
            //2点在同一直线上,可以直线连通
            if (this.hasLine(p1, p2).status) {
                return true;
            }
            //如果两点中任何一个点被全包围,则不通。
            else if (this.isWrap(p1, p2)) {
                return false;
            }
            //两点在一条直线上,不能直线连接但是可以连通
            else if (this.LineLink(p1, p2)) {
                return true;
            }
            //不在同一直线但是可以连通
            else if (this.curveLink(p1, p2)) {
                return true;
            }    
}

 

//判断同一条线能否连通,x轴相同或者y轴相同
        hasLine: function (p1, p2) {
            this.path = [];
            //同一点
            if (p1.x == p2.x && p1.y == p2.y) {
                return {
                    status: false
                };
            }
            if (this.onlineY(p1, p2)) {
                var min = p1.y > p2.y ? p2.y : p1.y;
                min = min + 1;
                var max = p1.y > p2.y ? p1.y : p2.y;
                for (min; min < max; min++) {
                    var p = {x: p1.x, y: min};
                    if (!this.isEmpty(p)) {
                        console.log('有障碍物p点………………');
                        console.log(p);
                        this.path = [];
                        break;
                    }
                    this.path.push(p);
                }
                if (min == max) {
                    return {
                        status: true,
                        data: this.path,
                        dir: 'y' //y轴
                    };
                }
                this.path = [];
                return {
                    status: false
                };
            }
            else if (this.onlineX(p1, p2)) {
                var j = p1.x > p2.x ? p2.x : p1.x;
                j = j + 1;
                var max = p1.x > p2.x ? p1.x : p2.x;
                for (j; j < max; j++) {
                    var p = {x: j, y: p1.y};
                    if (!this.isEmpty(p)) {
                        console.log('有障碍物p点………………');
                        console.log(p);
                        this.path = [];
                        break;
                    }
                    this.path.push(p);
                }

                if (j == max) {
                    return {
                        status: true,
                        data: this.path,
                        dir: 'x' //x轴
                    };
                }
                this.path = [];
                return {
                    status: false
                };
            }
            return {
                status: false
            };
//2点是否有其中一点被全包围,若有,则返回true
        isWrap: function (p1, p2) {
            //有一点为空,则条件不成立
            if (!this.isEmpty({x: p1.x, y: p1.y + 1}) && !this.isEmpty({
                    x: p1.x,
                    y: p1.y - 1
                }) && !this.isEmpty({
                    x: p1.x - 1,
                    y: p1.y
                }) && !this.isEmpty({x: p1.x + 1, y: p1.y})) {
                return true;
            }
            if (!this.isEmpty({x: p2.x, y: p2.y + 1}) && !this.isEmpty({
                    x: p2.x,
                    y: p2.y - 1
                }) && !this.isEmpty({
                    x: p2.x - 1,
                    y: p2.y
                }) && !this.isEmpty({x: p2.x + 1, y: p2.y})) {
                return true;
            }
            return false;
        }
  //两点在一条直线上,不能直线连接但是可以连通
        LineLink: function (p1, p2) {
            var pt0, pt1, pt2, pt3;
            //如果都在x轴,则自左至右扫描可能的路径,
            //每次构造4个顶点pt0, pt1, pt2, pt3,然后看他们两两之间是否连通
            if (this.onlineX(p1, p2)) {
                for (var i = 0; i < this.H; i++) {
                    if (i == p1.y) {
                        continue;
                    }
                    pt0 = p1;
                    pt1 = {x: p1.x, y: i};
                    pt2 = {x: p2.x, y: i};
                    pt3 = p2;
                    //如果顶点不为空,则该路不通。
                    if (!this.isEmpty(pt1) || !this.isEmpty(pt2)) {
                        continue;
                    }
                    if (this.hasLine(pt0, pt1).status && this.hasLine(pt1, pt2).status && this.hasLine(pt2, pt3).status) {
                        this.drawLine(2, [pt0, pt3, pt1, pt2]);
                        return [pt0, pt1, pt2, pt3];
                    }
                }
            }
            //如果都在y轴,则自上至下扫描可能的路径,
            //每次构造4个顶点pt0, pt1, pt2, pt3,然后看他们两两之间是否连通
            if (this.onlineY(p1, p2)) {
                for (var j = 0; j < this.W; j++) {
                    if (j == p1.x) {
                        continue;
                    }
                    pt0 = p1;
                    pt1 = {x: j, y: p1.y};
                    pt2 = {x: j, y: p2.y};
                    pt3 = p2;
                    //如果顶点不为空,则该路不通。
                    if (!this.isEmpty(pt1) || !this.isEmpty(pt2)) {
                        continue;
                    }
                    if (this.hasLine(pt0, pt1).status && this.hasLine(pt1, pt2).status && this.hasLine(pt2, pt3).status) {
                        this.drawLine(2, [pt0, pt3, pt1, pt2]);
                        return [pt0, pt1, pt2, pt3];
                    }
                }
            }
        },
 //两点不在一条直线上,看是否可通
        curveLink: function (p1, p2) {
            var pt0, pt1, pt2, pt3;
            //特殊情况,先判断是否是一个转弯
            var spec1 = {x: p1.x, y: p2.y},
                spec2 = {x: p2.x, y: p1.y};
            if (this.isEmpty(spec1)) {
                if (this.hasLine(p1, spec1).status && this.hasLine(p2, spec1).status) {
                    console.log('1个转弯');
                    this.drawLine(1, [p1, p2, spec1]);
                    return [p1, p2, spec1];
                }
            }
            if (this.isEmpty(spec2)) {
                if (this.hasLine(p1, spec2).status && this.hasLine(p2, spec2).status) {
                    console.log('1个转弯');
                    // console.table([pt0, spec2, pt3]);
                    this.drawLine(1, [p1, p2, spec2]);
                    return [p1, spec2, p2];
                }
            }
            //先纵向扫描可能的路径
            //同样,每次构造4个顶点,看是否可通
            for (var k = 0; k <= this.H; k++) {
                pt0 = p1;
                pt1 = {x: p1.x, y: k};
                pt2 = {x: p2.x, y: k};
                pt3 = p2;

                //2个交点都为空
                if (this.isEmpty(pt1) && this.isEmpty(pt2)) {
                    //2个转弯
                    if (this.hasLine(pt0, pt1).status && this.hasLine(pt1, pt2).status && this.hasLine(pt2, pt3).status) {
                        console.log('2个转弯');

                        this.drawLine(2, [pt0, pt3, pt1, pt2]);
                        return [pt0, pt3, pt1, pt2];
                    }
                }
            }

            //横向扫描所有可能的路径
            for (var k = 0; k <= this.W; k++) {
                pt0 = p1;
                pt1 = {x: k, y: p1.y};
                pt2 = {x: k, y: p2.y};
                pt3 = p2;

                //2个交点都为空
                if (this.isEmpty(pt1) && this.isEmpty(pt2)) {
                    //2个转弯
                    if (this.hasLine(pt0, pt1).status && this.hasLine(pt1, pt2).status && this.hasLine(pt2, pt3).status) {
                        console.log('2个转弯');

                        this.drawLine(2, [pt0, pt3, pt1, pt2]);
                        return [pt0, pt3, pt1, pt2];
                    }
                }
            }
            return false;
        }
连线判断

 

转载于:https://www.cnblogs.com/beidan/p/7049007.html

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现连连看小游戏需要掌握以下技能: - C# 编程语言 - WinForms 或 WPF 桌面应用程序开发 - 游戏开发基础知识,如游戏循环、精灵对象、碰撞检测等 - 算法和数据结构,如广度优先搜索、深度优先搜索、并查集等 以下是实现连连看小游戏的一些思路和步骤: 1. 设计游戏界面:需要设计游戏主界面和游戏结束界面,包括游戏标题、计时器、得分等元素。 2. 实现游戏数据:需要设计游戏关卡,包括地图、关卡难度、连连看元素等。可以使用 XML 或 JSON 文件来存储游戏数据。 3. 实现游戏流程:需要实现游戏循环、游戏计时器、得分系统等,同时需要实现游戏操作,如点击元素、连线、判断是否可以消除等。 4. 实现连线算法:需要实现连线算法,包括广度优先搜索和深度优先搜索,来判断两个元素是否可以连通,以及寻找最短路径。 5. 实现消除算法:需要实现消除算法,包括从地图中删除元素、更新得分、更新游戏状态等。 6. 实现提示功能:需要实现提示功能,可以根据当前游戏状态来提示玩家可以进行的操作。 7. 实现游戏结束判断:需要实现游戏结束判断,当所有元素都被消除,或者时间用尽,游戏结束。 以上是实现连连看小游戏的一些思路和步骤,需要具备一定的编程和算法基础,如果您是初学者,可以先学习 C# 编程语言和桌面应用程序开发,再逐步学习游戏开发和算法知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值