当前位置:首页手机软件 → 花鸟鱼虫连连看游戏

花鸟鱼虫连连看游戏

来源:小编 | 更新时间:2024-03-08 13:16:03

像《连连看》这样的经典游戏一定是90后的孩子玩的。无论是在电脑上还是在手机上,规则都很简单,只需连接相同的方块并消除即可。不需要超过三个连接线。小编最近撰文介绍了这款经典游戏,并首次展示了游戏界面:

696a98ffe48f4f78a897b24c1b4ea2a5~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1704777173&x-signature=MxUEMmlS44mPqgfKnQSHkopYMJ8%3D

分析:如何连接

连连看游戏的核心是如何判断两个方块是否相连。这其实就是一般游戏中的寻路算法之一。如何找到从一点到另一点的最短路径。不过寻路算法的实现过程比较复杂,因此本文不会深入探讨。这里会用另一种思维方式来寻找路径。

边肖编了一个java学习资料,私信回复[01]获取源代码。

20240102131333170417241389780.jpg

在连连看中,只能排除以下三种情况。

直线连接。

一个角落。

两个角。

前两种情况比较简单,但第三种情况可能在游戏中有多重联系。

看起来很复杂。其实你只需要计算出地图上X轴和Y轴上可以直接相连的两个方块的坐标,每个方块就可以得到两个数组(X轴和Y轴上可以直接相连的点),然后在两个方块的X轴和Y轴数组上做一个比较运算就可以得到角点位置。

以上简单分析了connection的基本实现思路,接下来开始编写代码。

程序

生成地图

点击事件

获取电缆

画一条连接线

生成地图

当然,首先要做的就是随机生成一张地图。

game.vue

从".' 导入单元格/细胞'

来自“导入实用程序./utils”

'从'./config'导入配置

来自“导入主题”./主题

导出默认值{

成分:{

细胞

},

数据() {

返回{

CellData[], //地图数据数组

CurrentSelectnull, //当前选中的框。

ConfigObject.assign(config) //配置信息

}

},

计算:{

当前主题(){

//当前主题

返回主题。过滤器(e=e.name===this.config.默认主题)[0]

}

},

已安装(){

this.init()

},

方法:{

//.

}

}

cell.vue

这里,div empty :before 和:after 伪类用于显示连接器。

导出默认值{

名称:'细胞',

道具:['isSelected','isBlank','className','lineClass','isLine'],

计算:{

班级名称(){

返回{

'已选择'this.isSelected, //已选择。

'空白'this.isblank,/空白色

[this.className]:是

}

}

}

}

为了更好的扩展链接盒的内容,我们使用数组来保存不同色块的类名,然后将对应的类名放在色块上,并通过CSS控制色块的背景图片。

在里面(){

console.time('initData')

this.cellData=this.initData()

console.timeEnd('initData')

},

初始化数据(){

//classNames=['a', 'b', 'c', 'd'] 每个元素代表一个盒子的类名。

//生成一个方阵,并将类名放入其中。莱特塞尔集团=

这。当前主题。类名.map (e={

返回{

IsBlank:false, //当为空白框时。

ClassName:e, //盒子的类名。

LineClass:' ', //连接线的类名。

IsLine:false, //是否应该显示连接线?

已选择:假

}

})

/空白框

让空白单元格{

是空白:是的,

班级名称: ””,

行类:“”,

是线:假,

已选择:假

}

//首先根据配置的块数随机取出几个块LetRandomCellGroup=utils. ArrayRandom(单元格组,

这。配置。 CellGroupCount) 取自方阵。

//然后随机填充一个地图数据let cell data=

实用程序。 ArrayfilbyRandomGroup(this . config . row * this . config . col, RandomCell Group) 根据配置中的行和列。

//将数据按照行的大小转换成二维数组,然后在外面包裹一层空的白色节点。

/*

* 实用程序.dyadicArrayWrap

* 通过填充包装二进制数组

* @params arr 源arr

* @params 填充要包装的源数组

*

* 0 0 0 0 0

* 1 1 1 0 1 1 1 0

* 1 1 1=0 1 1 1 0

* 1 1 1 0 1 1 1 0

* 0 0 0 0 0 */让结果=utils . dyadicarraywrap(utils . arraytodyadic(单元格数据, this.config.col), BlankCell)

//最后给节点设置行列坐标。

结果.forEach((列,行)={

cols.forEach((单元格,列)={

单元格.行=行

单元格.列=列

})

})

返回结果

}

最后,我们得到了地图数据的二维数组。

选择活动

下一步是选择框事件。

为了提高性能,点击事件没有直接绑定到盒子上,而是绑定到外表上,由事件代理实现。我还想在这里抱怨一下,Vue 目前没有事件代理。为了提高绑定的性能,我们需要自己实现一个事件代理。

//点击事件代理。

手柄点击(电动){

//如果盒子上没有触发点击事件,则退出if(ev.target.nodeName!=='TD ') 并返回

//获取点击框的坐标。如果该框为空,则退出letcol=ev.target.cellIndex

让行=ev 。目标。父节点。行索引

让当前单元格=this .单元格数据[行[列]

if(currentCell.isBlank===true) 返回

this.selectCell(当前Cell)

},

//选择框

选择单元格(currCell){

if(!this.currentSelect){

//如果没有选中框,直接设置选中的currCell.isSelected=true。

this.currentSelect=currCellre

转动

}

if(this .当前选择===当前单元格){

//如果点击的框与选中的框相同,则取消该框的选中状态。 currCell.isSelected=false。

this.currentSelect=null

返回

}

letprevCell=this.currentSelect

//利用className判断前后两个块的图片是否相同if(prevCell.className!==currCell.className){

//如果两个块的类名不同,则将点击的块设置为选中状态prevCell.isSelected=false。

currCell.isSelected=true

this.currentSelect=currCell

返回

}

//获取两个块的连接路径数组console.time('getLine ').

让结果=这个。 getline(上一个单元格, currCell)

console.timeEnd('getLine')

if(结果.length===0){

//如果没有获取到连接线,则说明两个块无法连接,则将点击的块设置为选中状态prevCell.isSelected=false。

currCell.isSelected=true

this.currentSelect=currCell

}否则{

//如果获取到连接线,则将两个方块设置为空白prevCell.isBlank=true。

currCell.isBlank=true

prevCell.className=' '

currCell.className=' '

prevCell.isSelected=false

currCell.isSelected=false

this.currentSelect=null

//最后画出连接线。

this.drawLine(结果)

}

}

选择的逻辑判断就到这里了,接下来就是本文的核心,如何获取连接路径。

获取电缆

这篇内容有点长,我分几部分来写。

首先介绍一下下面多次提到的可连线。

搜索可连接线时,红色方块是要搜索的方块,黑色是另一个方块,白色是空的白色方块。这样就可以从红色方块开始向前和向后遍历,得到一个可访问的方块集合对象,如图中全是白色方块。

getLine

找到连接线的入口

getLine(上一条, 当前){

//连接器数组

让结果=[]

//用直线连接。

//

分别获取最后选中框在X轴和Y轴上的可连接线。 Gethorizontaline 和getVerticalLine 都返回一个Set 对象。使用必须快速有效地确定某个框是否letpreview=this。 gethorizontaline (prev) 包含在可连接线路中。

letprevH=this .gethorizontalline(prev)

if(prev .has(curr)) 返回this.getBeeline(prev, curr)

让prevv=this .getverticalline(prev)

if(prev .has(curr)) 返回this.getBeeline(prev, curr)

//如果直线连接失败,则获取另一个方格的可连接线。

让currh=this .gethorizontalline(curr)

让currv=this .getverticalline(curr)

//快速判断。如果X轴和Y轴上的正方形的可连接长度为0,则返回空数组。

If ((!prevH.size!prev .size)" |(!currH.size!currV.size)) 返回结果

//可以连接一个角。

//分别判断X轴和Y轴上可连接线的交点。

etintersection=this . getintersection(prevH, currV) | 获取交集(prevH, currV) | |这。 getintersection(prevV, currV)

热点资讯
手游排行榜

CopyRight©2020-2030 www.xiquwang.com