使用cocoscreator完成一个消除类型的游戏,在原本消除游戏的基础上做了一些更改。
试玩地址–mobile
- 在gif中可以看见,只有第一排的物体是能被点击的,点击物体后,物体会移动到消除区域,下方物体上移补位。当消除区域有三个同样的物体并且首尾相连即可完成一次消除。
生成6x6饭团
- 在这里需要生成一个6x6的饭团网格,而且是需要随机在位置上生成不同样式的饭团的。直接在onLoad方法中调用drawBlock方法,生成6x6的饭团网格区域。
drawBlocks() {
this.blockSize = (this.targetBg.width - this.gap * (rows - 1)) / rows;
let x = this.blockSize / 2;
let y = this.blockSize / 2;
this.position = [];
this.blockArr = [];
for (let i = 0; i < rows; ++i) {
this.blockArr.push([0, 0, 0, 0, 0, 0]);
this.position.push([0, 0, 0, 0, 0, 0])
for (let j = 0; j < rows; ++j) {
let a = Math.floor(Math.random() * 6) + 1;
if (a == 1) { this.blockPre = this.blockPre1 }
if (a == 2) { this.blockPre = this.blockPre2 }
if (a == 3) { this.blockPre = this.blockPre3 }
if (a == 4) { this.blockPre = this.blockPre4 }
if (a == 5) { this.blockPre = this.blockPre5 }
if (a == 6) { this.blockPre = this.blockPre6 }
let block = cc.instantiate(this.blockPre);
block.width = this.blockSize;
block.height = this.blockSize;
block.getChildByName('mask').width = block.width;
block.getChildByName('mask').height = block.height;
block.getChildByName('mask').active = false;
this.targetBg.addChild(block);
if(i==rows-1){
block.getChildByName('outLine').active = true;
}
block.setPosition(cc.v2(x, y));
this.blockArr[i][j] = block
this.position[i][j] = cc.v2(x, y);
x += this.gap + this.blockSize;
}
y += this.gap + this.blockSize;
x = this.blockSize / 2;
}
},
第一排的饭团可以点击,且点击结束后移动道消除区
- 这里主要用事件的机制,点击开始时,判断是否点击上,点击上了,则点击的饭团放大。点击结束后往消除区移动,下面的饭团补充位置。
touchStart(event) {
if(this.gameTouchEnabled)return;
let touchPos = event.getLocation();
for(let i = this.displayArr.length-1;i>=0;i--){
this.displayArr[i].removeFromParent(false);
this.displayArr = this.removeItemFromArray(this.displayArr[i],this.displayArr);
}
return;
}
for (let i = 0; i < this.blockArr.length; ++i) {
for (let j = 0; j < this.blockArr[i].length; ++j) {
let block = this.blockArr[i][j];
if (block == null) continue;
let posInNode = this.worldConvertLocalPoint(block, touchPos);
let rect = cc.rect(0, 0, block.width, block.height);
if (rect.contains(posInNode) && this.blockArr[5].indexOf(block) !== -1) {
cc.audioEngine.playEffect(this.touch, false);
this.touchTile = block;
cc.tween(this.touchTile)
.to(0.1, { scale: 1.2 })
.start();
}
}
}
let posNode = this.worldConvertLocalPoint(this.boom, touchPos);
},
touchMove(event) {
if (this.touchTile) {
return true;
}
},
touchEnd(event) {
if (this.touchTile) {
if (this.displayArr.length < 6) {
this.blockToDispaly();
for (let i = 0; i < this.blockArr.length; ++i) {
let index = this.blockArr[i].indexOf(this.touchTile);
if (index !== -1) {
this.blockArr[i][index] = null;
break;
}
}
this.moveToUp();
} else {
cc.log("gameOver");
}
cc.tween(this.touchTile)
.to(0.1, { scale: 1 })
.start();
this.gameTouchEnabled = true;
} else {
cc.log("no TouchTile")
}
this.touchTile = null;
},
moveToUp() {
let move = (x, y, callback) => {
if (!this.blockArr[x][y] && x !== 0) {
let block = this.blockArr[x - 1][y]
if(x==rows-1){
block.getChildByName('outLine').active = true;
}
let position = this.position[x][y];
this.blockArr[x][y] = block;
this.blockArr[x - 1][y] = null;
this.doMove(block, position, () => {
move(x - 1, y, callback);
})
} else if (x == 0) {
let a = Math.floor(Math.random() * 6) + 1;
if (a == 1) { this.blockPre = this.blockPre1 }
if (a == 2) { this.blockPre = this.blockPre2 }
if (a == 3) { this.blockPre = this.blockPre3 }
if (a == 4) { this.blockPre = this.blockPre4 }
if (a == 5) { this.blockPre = this.blockPre5 }
if (a == 6) { this.blockPre = this.blockPre6 }
let block = cc.instantiate(this.blockPre);
block.width = this.blockSize;
block.height = this.blockSize;
this.targetBg.addChild(block);
this.blockArr[x][y] = block;
block.setPosition(this.position[x][y]);
this.gameTouchEnabled = false;
return;
} else {
callback && callback();
return;
}
}
let toMove = [];
for (let i = 0; i < this.blockArr.length; ++i) {
for (let j = 0; j < this.blockArr[i].length; ++j) {
if (this.blockArr[i][j] == null) {
toMove.push({ x: i, y: j })
}
}
}
let counter = 0;
for (let i = 0; i < toMove.length; ++i) {
move(toMove[i].x, toMove[i].y, () => {
counter++;
if (counter == toMove.length) {
return;
}
});
}
},
消除区域的消除逻辑
- 目前消除区域的消除逻辑是使用引擎中的分组来判断的,但其实并不好,当饭团种类越多,意味着要分的组也越多。最好的是在生成不同饭团的时候,给饭团对象一个不同的属性。在消除事根据该属性判断是否是相同的饭团。
checkMatch() {
if (this.displayArr.length >= 3) {
for (let i = 0; i < this.displayArr.length; i++) {
if (!this.displayArr[i + 1] || !this.displayArr[i + 2]) {
return;
}
if (this.displayArr[i].group == this.displayArr[i + 1].group && this.displayArr[i].group == this.displayArr[i + 2].group) {
this.scoreNum.string =Number(this.scoreNum.string)+Number(3);
cc.audioEngine.playEffect(this.match, false);
this.displayArr[i + 2].removeFromParent(false);
this.displayArr[i + 1].removeFromParent(false);
this.displayArr[i].removeFromParent(false);
this.displayArr = this.removeItemFromArray(this.displayArr[i + 2], this.displayArr);
this.displayArr = this.removeItemFromArray(this.displayArr[i + 1], this.displayArr);
this.displayArr = this.removeItemFromArray(this.displayArr[i], this.displayArr);
return;
}
}
}
},
那么到此就基本完成了这个消除游戏的一个大体逻辑,后续在游戏中可以增添道具等物体来增添游戏的趣味性。