使用uni app 写了个连连看,还没有路径展示,由于最近工作比较忙,没有时间取完善。大佬看到了可以改改加上路径然后写到评论或者开源一下。(绘制的有坐标。注掉坐标代码即可)不喜勿喷,欢迎大佬完善
<template>
<view class="container">
<view class="grid">
<view class="contentone">
<canvas class="canvas_cla" style="z-index: 1;" canvas-id="myCanvas" id="myCanvas"
@click="canvas_click"></canvas>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
datalist: [],
//行
rows: 18,
//列
clos: 10,
size: 35,
ctx: null,
firstclick: true,
clickdata: {},
twodata: {},
centerdata: {},
TowardEnum: {
NONE: null,
UP: {
row: -1,
clo: 0
},
RIGHT: {
row: 0,
clo: 1
},
DOWN: {
row: 1,
clo: 0
},
LEFT: {
row: 0,
clo: -1
}
},
};
},
onReady() {
this.ctx = uni.createCanvasContext('myCanvas');
this.init()
},
methods: {
canvas_click: function(e) {
let clickX = e.detail.x
let clickY = e.detail.y
for (var i = 0; i < this.datalist.length; i++) {
let data = this.datalist[i]
for (var j = 0; j < data.length; j++) {
let item = data[j]
if (item.name != "") {
if (clickX > item.x && clickX < item.x + item.size) {
if (clickY > item.y && clickY < item.y + item.size) {
if (this.firstclick) {
item.color = "#f00"
this.firstclick = false
this.clickdata = item
console.log(JSON.stringify(item))
this.drawpai()
} else {
if (this.clickdata.code != item.code) {
this.twodata = item
this.firstclick = true
item.color = "#f00"
console.log(JSON.stringify(item))
this.jisuan(item)
}
}
return; // 点击后退出循环,避免重复处理
}
}
}
}
}
},
deleflag() {
for (var i = 0; i < this.datalist.length; i++) {
let data = this.datalist[i]
for (var j = 0; j < data.length; j++) {
let item = data[j]
if (item.name != "") {
item.color = "#fff"
}
}
}
this.drawpai()
},
jisuan: function(item) {
// 示例调用
if (this.checkLink(this.clickdata.row, this.clickdata.clo, 0, this.TowardEnum.NONE, [], 1)) { //可以消除
//相邻
this.clickdata.name = ""
this.clickdata.color = "#efefef"
item.name = ""
item.color = "#efefef"
this.drawpai()
console.log("消除")
} else {
this.deleflag()
}
},
getLocaiton: function(row, clo) {
return "" + row + "," + clo;
},
checkLink: function(row, clo, changeTimes, nowToward, path, flag) { //当前小方块,转弯次数,路径方向(0123上右下左),所过路径
if (this.twodata.row == row && this.twodata.clo == clo && changeTimes <= 3) {
console.log("消除", JSON.stringify(path))
return true;
}
if (changeTimes > 3 || row < 0 || clo < 0 || row > this.rows - 1 || clo > this.clos - 1 || path
.indexOf(this
.getLocaiton(row, clo)) > -1 || (this.datalist[row][clo].name != '' && row != this.clickdata
.row && clo != this.clickdata.clo)) {
path.pop();
// // 如果回溯到起点且没有找到路径,则返回false
// if (path.length === 0) {
// return false;
// }
// console.log("33333333", JSON.stringify(path), row, clo, changeTimes, nowToward, )
// // 否则,尝试从上一个点向其他方向继续搜索
// let prevRow = parseInt(path[path.length - 1].split(',')[0]);
// let prevClo = parseInt(path[path.length - 1].split(',')[1]);
// console.log(prevRow, prevClo, row, clo)
// nowToward = this.getDirection(prevRow, prevClo, row, clo); // 计算当前应该尝试的方向
// console.log("44444444", nowToward)
// console.log("555555555", changeTimes + (nowToward === this.TowardEnum[
// this.prevDirectionToCurrent(nowToward)] ? 0 : 1))
// console.log("666666", nowToward === this.TowardEnum[this.prevDirectionToCurrent(nowToward)] ? 0 :
// 1)
// return this.checkLink(prevRow, prevClo, changeTimes + (nowToward === this.TowardEnum[
// this.prevDirectionToCurrent(nowToward)] ? 0 : 1), nowToward, path, 2);
return false;
}
if (flag == 2 && this.datalist[row][clo].name != '') {
path.pop();
return false;
}
// 递归调用checkLink函数,尝试四个方向
path.push(this.getLocaiton(row, clo));
return this.checkLink(row - 1, clo, nowToward === this.TowardEnum.UP ? changeTimes : changeTimes + 1,
this.TowardEnum.UP, path, 2) // UP
||
this.checkLink(row, clo + 1, nowToward === this.TowardEnum.RIGHT ? changeTimes : changeTimes + 1,
this.TowardEnum.RIGHT, path, 2) // RIGHT
||
this.checkLink(row + 1, clo, nowToward === this.TowardEnum.DOWN ? changeTimes : changeTimes + 1,
this.TowardEnum.DOWN, path, 2) // DOWN
||
this.checkLink(row, clo - 1, nowToward === this.TowardEnum.LEFT ? changeTimes : changeTimes + 1,
this.TowardEnum.LEFT, path, 2); // LEFT
// path.push(this.getLocaiton(row, clo));
// return this.checkLink(row - 1, clo, nowToward == this.TowardEnum.UP ? changeTimes : changeTimes + 1,
// this.TowardEnum.UP, path, 2) //UP
// ||
// this.checkLink(row, clo + 1, nowToward == this.TowardEnum.RIGHT ? changeTimes : changeTimes + 1,
// this.TowardEnum.RIGHT, path, 2) //RIGHT
// ||
// this.checkLink(row + 1, clo, nowToward == this.TowardEnum.DOWN ? changeTimes : changeTimes + 1,
// this.TowardEnum.DOWN, path, 2) //DOWN
// ||
// this.checkLink(row, clo - 1, nowToward == this.TowardEnum.LEFT ? changeTimes : changeTimes + 1,
// this.TowardEnum.LEFT, path, 2) //LEFT
},
// 辅助函数:根据前一个点和当前点的位置计算方向
getDirection: function(prevRow, prevClo, row, clo) {
console.log(prevRow, prevClo, row, clo)
if (row === prevRow && clo === prevClo + 1) return 'RIGHT';
if (row === prevRow && clo === prevClo - 1) return 'LEFT';
if (row === prevRow + 1 && clo === prevClo) return 'DOWN';
if (row === prevRow - 1 && clo === prevClo) return 'UP';
return null; // 不应该出现的情况
},
// 辅助函数:将字符串方向转换为枚举值
prevDirectionToCurrent: function(direction) {
switch (direction) {
case 'RIGHT':
return 'LEFT';
case 'LEFT':
return 'RIGHT';
case 'DOWN':
return 'UP';
case 'UP':
return 'DOWN';
default:
return null;
}
},
init: function() {
var values = ["A", "B", "C", "D", "E", "F", "G", "H"]
var datas = [];
for (var i = 0; i < this.rows - 2; i++) {
datas = datas.concat(values)
}
datas = this.shuffle(datas)
var datalist = []
for (var i = 0; i < this.rows; i++) {
var mydatas = []
for (var j = 0; j < this.clos; j++) {
var data = {}
if (i != 0 && j != 0 && i != this.rows - 1 && j != this.clos - 1) {
let item = datas.pop()
data.name = item
data.y = i * this.size + 2
data.x = j * this.size + 2
data.size = this.size
data.color = "#fff"
data.row = i
data.clo = j
data.code = "m-" + i + "-" + j
} else {
data.name = ''
data.y = i * this.size + 2
data.x = j * this.size + 2
data.size = this.size
data.color = "#efefef"
data.row = i
data.clo = j
data.code = "m-" + i + "-" + j
}
mydatas.push(data)
}
datalist.push(mydatas)
}
this.datalist = datalist
console.log(JSON.stringify(this.datalist))
this.drawpai()
},
drawpai: function() {
for (var i = 0; i < this.datalist.length; i++) {
let data = this.datalist[i]
for (var j = 0; j < data.length; j++) {
let item = data[j]
// 设置边框颜色、线宽和正方形大小
this.ctx.setStrokeStyle('#fff');
this.ctx.setLineWidth(4);
// 绘制正方形边框
// this.ctx.strokeRect(item.x, item.y, item.size, item.size);
// 设置填充颜色和填充正方形
this.ctx.setFillStyle(item.color); // 灰色填充
this.ctx.fillRect(item.x, item.y, item.size - 4, item.size - 4); // 减去边框宽度以避免重叠
// 设置文字样式和位置,并绘制文字
this.ctx.setFontSize(10);
this.ctx.setFillStyle('#000000'); // 文字颜色
const text = item.name;
const textWidth = this.ctx.measureText(text).width; // 测量文字宽度
this.ctx.fillText(text, item.x + (item.size - textWidth) / 2, item.y + item.size / 2 +
4); // 文字垂直居中,并稍微向下偏移以避免与边框重叠
this.ctx.setFontSize(10);
this.ctx.fillText(item.row + "-" + item.clo, item.x + 10, item.y +
10); // 文字垂直居中,并稍微向下偏移以避免与边框重叠
}
}
// 将绘制内容绘制到 Canvas 上
this.ctx.draw()
},
//将数组打乱
// 打乱数组的函数
shuffle: function(array) {
let currentIndex = array.length,
temporaryValue, randomIndex;
// 当还剩有元素未洗牌时
while (0 !== currentIndex) {
// 选取一个剩下的元素
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// 并与当前元素交换
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
},
convertToArray2D: function(array1D, rows, clos) {
console.log(array1D.length, rows, clos)
if (array1D.length !== rows * clos) {
throw new Error('一维数组的长度必须与指定的行列数相乘的结果相等');
}
let array2D = [];
for (let i = 0; i < array1D.length; i += clos) {
array2D.push(array1D.slice(i, i + clos));
}
return array2D;
},
}
};
</script>
<style>
.canvas_cla {
width: 100vw;
height: 100vh;
}
.contentone {
width: 100vw;
height: 100vh;
position: absolute;
display: flex;
justify-content: center;
}
</style>