方块消除教程
- <背景>--------------------------------------------------------------------.1
- <方块>--------------------------------------------------------------------.1
- <生成方块>--------------------------------------------------------------.1
- <方块拖动>------------------------------------------------------------.1
- <可填充检测>-----------------------------------------------------------.1
- <显示虚线框>-----------------------------------------------------------.1
- <填充方块>--------------------------------------------------------------.1
- <可消除检测>-----------------------------------------------------------.1
- <方块消除>-------------------------------------------------------------.1
<背景>--------------------------------------------------------------------.1
背景主要是一个二维数组,行和列自己配置,但是需要提前制作好背景的预制体,背景上如果有不同的操作,需要挂上backItem的代码,之后再生成对象之后直接调用,以此有以下代码:
InitBack() {
for (let row = 0; row < this.row; row++) {
this.backList[row] = this.backList[row] || []
for (let col = 0; col < this.col; col++) {
let go = cc.instantiate(this.BackItem);
go.parent = this.node;
go.setPosition(row * this.width, col * this.width)
let back = go.getComponent(Back);
back.SetPosition(go.position);
this.backList[row][col] = back;
}
}
},
如下:
<方块>--------------------------------------------------------------------.1
二维数组,主要是为了后面选择方块方便使用!因为旋转二维矩阵很简单!这里主要是积累了图形学的支持!如此有以下代码:
var WithDrawConfig = {
OBlock : [[1,1,1],[1,1,1],[1,1,1]],
LBlock : [[1,1,1],[1,0,0],[1,0,0,]],
IBlock : [[0,0,0],[1,1,1],[0,0,0]]
}
export default WithDrawConfig
还可以扩展很多的不同类型的方块
<生成方块>--------------------------------------------------------------.1
根据方块的配置文件,生成对应的方块!方块也是二维数组,如此有以下代码,但是我们需要提前制作好预制体!
如此:
//初始化最右边方块
InitLeftBlock() {
for (let i = 0; i < GameConfig.IBlock.length; i++) {
let array = GameConfig.IBlock[i];
for (let j = 0; j < array.length; j++) {
if (array[j] == 1) {
let go = cc.instantiate(this.BlockItem);
go.parent = this.Right;
go.setPosition((i - 1) * this.width, (j - 1) * this.width)
this.rightBlockList.push(go);
let block = go.getComponent(Block);
block.SetType("pup");
}
}
}
},
可以根据这个生成不同的三个位置的方块!
<方块拖动>------------------------------------------------------------.1
OnTouchMoveLeftCallback(event) {
//这里主要是坐标空间转换,鼠标的坐标和方块的坐标转换到一个空间,然后才能给方块的坐标赋值,这里很重要
let out = cc.v2();
let pos = cc.Camera.main.getScreenToWorldPoint(event.getLocation(), out);
pos = this.Left.parent.convertToNodeSpaceAR(out)
this.Left.setPosition(pos);
this.DetectionPostion(this.leftBlockList, this.Left)
this.Whether(this.leftBlockList);
this.EliminateWillBlock();
this.BlockJitter();
},
<可填充检测>-----------------------------------------------------------.1
//寻找可以填充的方块位置
DetectionPostion(target, targetParent) {
this.searchBlockList = []
for (let row = 0; row < this.row; row++) {
for (let col = 0; col < this.col; col++) {
for (let index = 0; index < target.length; index++) {
let xdis = Math.abs((target[index].x + targetParent.x) - ((this.backList[row][col].GetPosition().x + this.node.x - this.offsetX)));
let ydis = Math.abs((target[index].y + targetParent.y) - ((this.backList[row][col].GetPosition().y + this.node.y - this.offsetY)));
if (xdis <= 35 && ydis <= 35) {
this.searchBlockList.push(this.backList[row][col]);
if(!this.backList[row][col].GetFill()){
this.backList[row][col].SetWillPut(true);
this.backList[row][col].SetTarget(target[index]);
}
break;
} else {
this.backList[row][col].HideWhiteImage();
if(!this.backList[row][col].GetFill()){
this.backList[row][col].SetWillPut(false);
this.backList[row][col].SetTarget(null);
}
}
}
}
}
//判断整个方块是否都填入,避免越界判断以及fill判断
let list = []
let isSucess = true;
for (let index = 0; index < this.searchBlockList.length; index++) {
if (this.searchBlockList[index].GetFill()) {
isSucess = false;
break;
} else {
list.push(this.searchBlockList[index]);
}
}
if (isSucess && target.length != list.length) {
this.searchBlockList = [];
}
},
<显示虚线框>-----------------------------------------------------------.1
这里主要是为了根据拖动方块的位置显示虚线框:
//显示虚线框
Whether(target) {
let list = []
if(this.searchBlockList.length>0)
this.isSucess = true;
for (let index = 0; index < this.searchBlockList.length; index++) {
if (this.searchBlockList[index].GetFill()) {
this.isSucess = false;
break;
} else {
list.push(this.searchBlockList[index]);
}
}
if (this.isSucess && target.length == list.length) {
for (let index = 0; index < list.length; index++) {
list[index].ShowWhiteImage();
}
}
},
<填充方块>--------------------------------------------------------------.1
这里主要是把可以填到空缺位置的方块,放入空位,否则,复位:
PutBlock(target, targetParent) {
if(target.length!=this.searchBlockList.length)
this.searchBlockList = []
for (let index = 0; index < this.searchBlockList.length; index++) {
target[index].parent = this.node;
this.searchBlockList[index].SetFill(true);
this.searchBlockList[index].SetTarget(target[index]);
target[index].setPosition(this.searchBlockList[index].GetPosition());
this.searchBlockList[index].HideWhiteImage();
}
this.EliminateBlock();
this.RemoveBlock();
},
<可消除检测>-----------------------------------------------------------.1
这里主要是找到当前可以消除的方块,也就是达到一整行的方块!
//找到可消除的行和列
EliminateBlock() {
this.clearRowBlockList = []
for (let row = 0; row < this.row; row++) {
for (let col = 0; col < this.col; col++) {
if (!this.backList[row][col].GetFill()) {
break;
}
if (col == this.col - 1) {
console.log("当前可消除的行为:" + row)
this.clearRowBlockList.push(row);
}
}
}
this.clearColBlockList = []
for (let col = 0; col < this.col; col++) {
for (let row = 0; row < this.row; row++) {
if (!this.backList[row][col].GetFill()) {
break;
}
if (row == this.row - 1) {
console.log("当前可消除的列为:" + col)
this.clearColBlockList.push(col);
}
}
}
},
<方块消除>-------------------------------------------------------------.1
把可以消除的行和列的方块消除!
//消除方块
RemoveBlock() {
for (let index = 0; index < this.clearColBlockList.length; index++) {
for (let j = 0; j < this.col; j++) {
if (!this.backList[j][this.clearColBlockList[index]].GetisDestory()) {
let time = j * this.waitTime;
setTimeout(()=>{
let go = cc.instantiate(this.Effect);
go.parent = this.node;
let eff = go.getComponent(Effect);
eff.SetType(this.backList[j][this.clearColBlockList[index]].GetType());
go.setPosition(this.backList[j][this.clearColBlockList[index]].GetPosition());
},time);
this.backList[j][this.clearColBlockList[index]].DestroySelf(time);
}
}
}
for (let index = 0; index < this.clearRowBlockList.length; index++) {
for (let j = 0; j < this.row; j++) {
if (!this.backList[this.clearRowBlockList[index]][j].GetisDestory()) {
let time = j * this.waitTime;
setTimeout(()=>{
let go = cc.instantiate(this.Effect);
go.parent = this.node;
let eff = go.getComponent(Effect);
eff.SetType(this.backList[this.clearRowBlockList[index]][j].GetType());
go.setPosition(this.backList[this.clearRowBlockList[index]][j].GetPosition());
},time);
this.backList[this.clearRowBlockList[index]][j].DestroySelf(time);
}
}
}
},
效果: