import Common5 from "../../Platform/th/Common5"; const { ccclass, property } = cc._decorator; @ccclass export default class MoneyFlyEffect extends cc.Component { // @property(cc.Node) // startPoint: cc.Node = null; @property(cc.Node) endPoint: cc.Node = null; @property(cc.Node) endPoint2: cc.Node = null; @property(cc.Prefab) coinPrefab: cc.Prefab = null; @property(cc.Prefab) incomePopUp: cc.Prefab = null; coinPool: cc.NodePool = null; popUpPool: cc.NodePool = null; onLoad() { this.coinPool = new cc.NodePool(); this.popUpPool = new cc.NodePool(); this.initCoinPool(); } initCoinPool(count: number = 20) { for (let i = 0; i < count; i++) { let coin = cc.instantiate(this.coinPrefab); this.coinPool.put(coin); } } getNodeToTargetPos(curNode, targetNode) { //目标节点的本地坐标 let targetLocalPos = targetNode.getPosition() //目标节点的世界坐标 let targetWorldPos = targetNode.parent.convertToWorldSpaceAR(targetLocalPos) //目标节点相对于当前节点父节点的本地坐标 let localPos = curNode.parent.convertToNodeSpaceAR(targetWorldPos) return localPos } playAnim(startNode, money?) { let randomCount = Math.random() * 15 + 20; //console.log(randomCount, 'randomCount++++++++++==') let stPos = this.getNodeToTargetPos(this.node, startNode) let edPos = this.getNodeToTargetPos(this.node, this.endPoint); let canvas = cc.find('Canvas') let prefabLayer = canvas.getChildByName("prefabLayer") for (let i = prefabLayer.childrenCount - 1; i >= 0; i--) { const yuanBao = prefabLayer.children[i].getChildByName("yuanBao"); if (yuanBao) { let chaopiao = yuanBao.getChildByName("金币").getChildByName("钞票"); edPos = this.getNodeToTargetPos(this.node, chaopiao); break; } } let randomR = Math.random() * 60 + 60; this.playCoinFlyAnim(randomCount, stPos, edPos, randomR); if (money) { this.showIncomePopUp(money, stPos); } } showIncomePopUp(money, stPos) { let incomePopUp = this.popUpPool.get(); if (!incomePopUp) { incomePopUp = cc.instantiate(this.incomePopUp); } incomePopUp.getComponent(cc.Label).string = `+${Common5.getNumberChangeHanzi(money, '2')}元`; cc.tween(incomePopUp) .set({ active: true, parent: this.node, position: stPos, opacity: 255 }) .to(0.3, { scale: 1.5 }) .to(0.2, { scale: 1 }) .to(1, { position: cc.v3(stPos.x, stPos.y + 400, 0), opacity: 0 }) .call(() => { this.popUpPool.put(incomePopUp); }) .start(); } playCoinFlyAnim(count: number, stPos: cc.Vec2, edPos: cc.Vec2, r: number = 130) { // 确保当前节点池有足够的金币 const poolSize = this.coinPool.size(); const reCreateCoinCount = poolSize > count ? 0 : count - poolSize; this.initCoinPool(reCreateCoinCount); // 生成圆,并且对圆上的点进行排序 let points = this.getCirclePoints(r, stPos, count); let coinNodeList = points.map(pos => { let coin = this.coinPool.get(); coin.setPosition(stPos); this.node.addChild(coin); return { node: coin, stPos: stPos, mdPos: pos, edPos: edPos, dis: (pos as any).sub(edPos).mag() }; }); coinNodeList = coinNodeList.sort((a, b) => { if (a.dis - b.dis > 0) return 1; if (a.dis - b.dis < 0) return -1; return 0; }); // 执行金币落袋的动画 coinNodeList.forEach((item, idx) => { item.node.runAction( cc.sequence( cc.moveTo(0.3, item.mdPos), cc.delayTime(idx * 0.01), cc.moveTo(0.5, item.edPos), cc.callFunc(() => { this.coinPool.put(item.node); }) ) ); }); } /** * 以某点为圆心,生成圆周上等分点的坐标 * * @param {number} r 半径 * @param {cc.Vec2} pos 圆心坐标 * @param {number} count 等分点数量 * @param {number} [randomScope=80] 等分点的随机波动范围 * @returns {cc.Vec2[]} 返回等分点坐标 */ getCirclePoints(r: number, pos: cc.Vec2, count: number, randomScope: number = 60): cc.Vec2[] { let points = []; let radians = (Math.PI / 180) * Math.round(360 / count); for (let i = 0; i < count; i++) { let x = pos.x + r * Math.sin(radians * i); let y = pos.y + r * Math.cos(radians * i); points.unshift(cc.v3(x + Math.random() * randomScope, y + Math.random() * randomScope, 0)); } return points; } }