作者在 2020-02-09 23:56:02 发布以下内容
item.js
cc.Class({
extends: cc.Component,
properties: {
picSprite: cc.Sprite,
frame: cc.Node,
cfg: null,
moveStartCb: null,
moveEndCb: null
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start() {
},
// update (dt) {},
initPic(cfg, moveStartCb, moveEndCb) {
this.cfg = cfg;
this.moveStartCb = moveStartCb;
this.moveEndCb = moveEndCb;
this.__initNode();
this.__initSprite();
this.__initFrame();
this.__initTouch();
},
setItemPosition(x, y) {
this.cfg.posX = x;
this.cfg.posY = y;
this.__resetItemPosition();
},
__initNode() {
let cfg = this.cfg;
this.node.setPosition(cfg.posX, cfg.posY);
// 这里要给父 Node 指定大小,因为之后要实现拖动父 Node
this.node.setContentSize(cfg.w, cfg.h);
},
__initSprite() {
let cfg = this.cfg;
let rect = cc.rect(cfg.x, cfg.y, cfg.w, cfg.h);
this.picSprite.spriteFrame = new cc.SpriteFrame(cfg.texture, rect);
this.picSprite.node.setContentSize(cfg.w, cfg.h);
},
__initFrame() {
let cfg = this.cfg;
this.frame.setContentSize(cfg.w, cfg.h);
},
__initTouch() {
let self = this;
this.node.on(cc.Node.EventType.TOUCH_START, function (event) {
self.moveStartCb = self.moveStartCb || function () {
};
self.moveStartCb(self.node);
}, this.node);
this.node.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
this.opacity = 100;
let delta = event.touch.getDelta();
this.x += delta.x;
this.y += delta.y;
}, this.node);
this.node.on(cc.Node.EventType.TOUCH_END, function () {
this.opacity = 255;
self.moveEndCb = self.moveEndCb || function () {
};
self.moveEndCb(self.node);
}, this.node);
},
__resetItemPosition() {
this.node.setPosition(this.cfg.posX, this.cfg.posY);
}
});
item-manager.js
cc.Class({
extends: cc.Component,
properties: {
itemPrefeb: cc.Prefab,
endManager: cc.Node,
timer: cc.Node
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start() {
let self = this;
// 初始化变量
self.__initParams();
for (let i = 0; i < 9; i++) {
let node = cc.instantiate(self.itemPrefeb);
node.parent = self.node;
self.items.push(node.getComponent('item'));
}
// 加载 Texture
cc.loader.loadRes("pic", cc.Texture2D, function (err, texture) {
self.curTexture = texture;
self.__initItems();
self.__shuffleItemPos();
});
},
// update (dt) {},
__initParams() {
this.items = [];
this.curTexture = null;
this.picHeight = 540;
this.picWidth = 810;
this.maxIndex = 0;
},
__initItems() {
let self = this;
let itemWidth = self.picWidth / 3;
let itemHeight = self.picHeight / 3;
let itemIndex = 0;
let posY = 0;
let posX = 0;
for (let l = 0; l < 3; l++) {
posY = (1 - l) * itemHeight;
for (let r = 0; r < 3; r++) {
posX = (r - 1) * itemWidth;
let item = self.items[itemIndex];
item.initPic({
texture: self.curTexture,
x: itemWidth * r,
y: itemHeight * l,
w: itemWidth,
h: itemHeight,
posX: posX,
posY: posY,
index: itemIndex
}, self.__moveStart, self.__moveEnd);
itemIndex++;
}
}
},
__shuffleItemPos() {
let self = this;
for (let i = 0; i < self.items.length; i++) {
let randomSeed = Math.floor(Math.random() * (self.items.length));
let item = self.items[i];
let rItem = self.items[randomSeed];
let x = item.cfg.posX;
let y = item.cfg.posY;
item.setItemPosition(rItem.cfg.posX, rItem.cfg.posY);
rItem.setItemPosition(x, y);
}
},
__moveStart(node) {
console.info('start');
let itemManager = node.parent.getComponent('item-manager');
itemManager.itemStartPos = cc.v2({x: node.position.x, y: node.position.y});
itemManager.maxIndex++;
node.zIndex = itemManager.maxIndex;
cc.loader.loadRes('sound/pick', cc.AudioClip, function (err, clip) {
cc.audioEngine.playEffect(clip, false);
});
},
__moveEnd(node) {
console.info('end');
cc.loader.loadRes('sound/drop', cc.AudioClip, function (err, clip) {
cc.audioEngine.playEffect(clip, false);
});
let self = node.parent.getComponent('item-manager');
self.__adsorption(node);
},
__adsorption(node) {
let picHeight = node.height;
let picWidth = node.width;
let nodeVec = cc.v2({x: node.position.x, y: node.position.y});
let conditions = [
{x: picWidth, y: 0},
{x: (-1) * picWidth, y: 0},
{x: 0, y: picHeight},
{x: 0, y: (-1) * picHeight},
];
for (let i = 0; i < this.items.length; i++) {
let itemNode = this.items[i].node;
let itemPos = itemNode.position;
let isMoved = false;
for (let j = 0; j < conditions.length; j++) {
let con = conditions[j];
let targetVec = cc.v2({
x: itemPos.x + con.x,
y: itemPos.y + con.y
});
let distance = targetVec.sub(nodeVec).mag();
if (distance > 100) continue;
isMoved = true;
// 目标位置上已经有其他节点
if (this.__isPosHasItem(node, targetVec)) {
let action = cc.moveTo(0.1, this.itemStartPos);
node.runAction(action);
}
// 目标位置上没有其他节点
else {
let finished = cc.callFunc(this.__checkWin, this);
let action = cc.moveTo(0.1, targetVec);
let seq = cc.sequence(action, finished);
node.runAction(seq);
}
break;
}
if (!isMoved) continue;
console.info('自动吸附条件成立!!!!');
break;
}
},
__checkWin() {
let conditions = [
{x: 270, y: 0}, // 2-1
{x: 270, y: 0}, // 3-2
{x: 270 * (-2), y: -180}, // 4-3
{x: 270, y: 0}, // 5-4
{x: 270, y: 0}, // 6-5
{x: 270 * (-2), y: -180}, // 7-6
{x: 270, y: 0}, // 8-7
{x: 270, y: 0}, // 9-8
];
let j = 0;
for (let i = 0; i < this.items.length - 1; i++) {
let thisPos = this.items[i].node.position;
let nextPos = this.items[i + 1].node.position;
if (Math.abs(nextPos.x - thisPos.x - conditions[j].x) > 5) return;
if (Math.abs(nextPos.y - thisPos.y - conditions[j].y) > 5) return;
j++;
}
this.endManager.getComponent('end-manager').showWin();
this.timer.getComponent('timer').stopTimer();
},
__isPosHasItem(node, targetVec) {
for (let i = 0; i < this.items.length; i++) {
let item = this.items[i];
if (item.node._id == node._id) continue;
if (Math.abs(item.node.position.x - targetVec.x) > 1) continue;
if (Math.abs(item.node.position.y - targetVec.y) > 1) continue;
return true;
}
return false;
}
});
end-manager.js
cc.Class({
extends: cc.Component,
properties: {
bgNode: cc.Node,
maskNode: cc.Node,
winNode: cc.Node,
loseNode: cc.Node
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start() {
this.maskNode.on('touchstart', function (event) {
event.stopPropagation();
});
this.maskNode.on('touchend', function (event) {
event.stopPropagation();
});
},
// update (dt) {},
showWin() {
this.node.active = true;
this.bgNode.active = true;
this.winNode.active = true;
this.loseNode.active = false;
},
showLose() {
this.node.active = true;
this.bgNode.active = true;
this.winNode.active = false;
this.loseNode.active = true;
},
});
timer.js
cc.Class({
extends: cc.Component,
properties: {
timerLabel: cc.Label,
endManager: cc.Node
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start() {
this.__startTimer();
this.isPause = false;
},
// update (dt) {},
pauseTimer() {
this.isPause = true;
},
resumeTimer() {
this.isPause = false;
},
stopTimer() {
this.unschedule(this.__timerCallback);
},
__startTimer() {
this.count = 60;
this.schedule(this.__timerCallback, 1);
},
__timerCallback() {
if (this.isPause) {
return;
}
if (this.count <= 0) {
this.unschedule(this.callback);
this.endManager.getComponent('end-manager').showLose();
return;
}
this.count--;
this.timerLabel.string = "00:" + this.__prefixZero(this.count, 2);
},
__prefixZero(num, length) {
return (Array(length).join('0') + num).slice(-length);
}
});
pause-manager.js
cc.Class({
extends: cc.Component,
properties: {
pauseWindow: cc.Node,
maskNode: cc.Node
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start() {
this.maskNode.on('touchstart', function (event) {
event.stopPropagation();
});
this.maskNode.on('touchend', function (event) {
event.stopPropagation();
});
},
// update (dt) {},
pause() {
this.pauseWindow.active = true;
this.__plaClickSound();
},
resume() {
this.pauseWindow.active = false;
this.__plaClickSound();
},
__plaClickSound() {
cc.loader.loadRes('sound/ButtonClick', cc.AudioClip, function (err, clip) {
cc.audioEngine.playEffect(clip, false);
});
}
});
注:代码来源github