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
原创文章,作者:李掌柜的博客,如若转载,请注明出处:https://www.zengqueling.com/%e6%8b%bc%e5%9b%be/