import GameModel from "../ts/core/GameModel"; cc.Class({ extends: cc.Component, properties: { _type: 0,//0 聊天框 1遊戲右下角ui type: { get() { return this._type; }, set(t) { this._type = t; } }, _string: '', string: { get() { return this._string; }, set(t) { this._string = t; this.showTextInfo(); } }, _maxWidth: 0, maxWidth: { get() { return this._maxWidth; }, set(t) { this._maxWidth = t; if (t <= 0) { this._maxWidth = 100; } this.node.width = t; } }, _fontSize: 20, fontSize: { get() { return this._fontSize; }, set(t) { this._fontSize = t; } }, _lineHeight: 22, lineHeight: { get() { return this._lineHeight; }, set(t) { this._lineHeight = t; this.node.height = t; } }, _strColor: cc.Color.BLACK, strColor: { get() { return this._strColor; }, set(c) { this._strColor = c; this.node.color = c; } }, startX: 0, startY: 0, emojiAtlas: cc.SpriteAtlas, joinTeamBg: cc.SpriteFrame, item_detail: cc.Prefab, fontRes: cc.Font }, onLoad() { this.node.setAnchorPoint(cc.v2(0, 1)); this.isLoad = true; }, /** * showLabInfo creator編輯是顯示用,程序裡用不到 */ showLabInfo() { this.node.destroyAllChildren(); let lnode = new cc.Node(); lnode.parent = this.node; lnode.width = this.maxWidth; lnode.color = cc.Color.BLACK; let lab = lnode.addComponent(cc.Label); lab.fontSize = this.fontSize; lab.lineHeight = this.lineHeight; lab.string = this.string; lab.horizontalAlign = cc.Label.HorizontalAlign.LEFT; lab.verticalAlign = cc.Label.VerticalAlign.TOP; lab.overflow = cc.Label.Overflow.RESIZE_HEIGHT; lnode.setPosition(cc.v2(this.startX, this.startY)); lnode.setAnchorPoint(cc.v2(0, 1)); }, showTextInfo() { if (this.isLoad == null) { this.showLabInfo(); return; } this.node.destroyAllChildren(); this.startX = 0; this.startY = 0; if (this.type == 1) { this.addScaleNode(); this.addNameNode(); } let textInfo = []; let msgstr = this.string; // let patt = /\[(?:[0-9]{1,3}|1000)\]/; // let pos = msgstr.search(patt); // while (pos != -1) { // if (pos > 0) { // textInfo.push({ type: 'txt', data: msgstr.substring(0, pos) }); // } // let numend = msgstr.indexOf(']', pos); // let numstr = msgstr.substring(pos + 1, numend); // textInfo.push({ type: 'img', data: numstr }); // msgstr = msgstr.substr(numend + 1); // pos = msgstr.search(patt); // } // if (msgstr.length > 0) { // textInfo.push({ type: 'txt', data: msgstr }); // } let patt = /\[[\s\S]*?\]/; // let patt = /\[(?:[0-9]{1,3}|1000)\]/; let pos = msgstr.search(patt); while (pos != -1) { if (pos > 0) { textInfo.push({ type: 'txt', data: msgstr.substring(0, pos) }); } let numend = msgstr.indexOf(']', pos); let numstr = msgstr.substring(pos + 1, numend); let ppatt1 = /\[(?:[0-9]{1,3}|1000)\]/; let pnumstr = '[' + numstr + ']'; let ppos1 = pnumstr.search(ppatt1); if (ppos1 >= 0) { textInfo.push({ type: 'img', data: numstr }); } else { textInfo.push({ type: 'link', data: numstr }); } // textInfo.push({ type: 'img', data: numstr }); msgstr = msgstr.substr(numend + 1); pos = msgstr.search(patt); } if (msgstr.length > 0) { if (!this.checkColor(textInfo, msgstr)) textInfo.push({ type: 'txt', data: msgstr }); } for (const info of textInfo) { if (info.type == 'txt') { let str = info.data; let cutPos = this.cutStringByWidth(str, this.maxWidth - this.startX); while (cutPos != str.length) { if (cutPos == 0) { this.startX = 0; this.startY -= this.lineHeight; } else { this.addLabelNode(str.substr(0, cutPos), info.color); str = str.substr(cutPos); } cutPos = this.cutStringByWidth(str, this.maxWidth - this.startX); } if (str.length > 0) { this.addLabelNode(str, info.color); } } if (info.type == 'img') { this.addImgNode(info.data); } if (info.type == 'link') { this.addLinkNode(info.data); } } if (this.startY < 0) { this.node.width = this.maxWidth; } else { this.node.width = this.startX; } this.node.height = -(this.startY - this.lineHeight) + 5; }, checkColor(list, str) { var hasColor = /\.*?\<\/c(olor)?[ ]\>/g; var arr = str.match(hasColor) if (arr == null) return false for (let i in arr) { var color = arr[i].match(/#(?:[0-9]|[a-f]){6}/)[0] var t = arr[i].replace(/\/, ""); t = t.replace(/\<\/c(olor)?[ ]\>/, ""); list.push({ type: "txt", data: t, color: color }) } return true }, addNameNode() { if (this.rolename == null || this.rolename == '') { return; } if (this.startX > this.maxWidth - this.fontSize) { this.startX = 0; this.startY -= this.lineHeight; } let lnode = new cc.Node(); lnode.color = new cc.Color(24, 218, 224); let title = `[${this.rolename}]`; if (this.vipLevel > 0) { title = `V${this.vipLevel}${title}`; } let textRT = lnode.addComponent(cc.Label); // if (this.fontRes) // textRT.font = this.fontRes; // else // textRT.font = GameModel.fontRes; textRT.cacheMode = cc.Label.CacheMode.BITMAP textRT.fontSize = this.fontSize; textRT.lineHeight = this.lineHeight; textRT.string = title; lnode.setPosition(cc.v2(this.startX, this.startY)); lnode.setAnchorPoint(cc.v2(0, 1)); lnode.parent = this.node; this.startX += lnode.width; }, addLabelNode(str, color) { let labelColor = this.node.color; if (color) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color) if (result) labelColor = cc.color(parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)); } else { if (this.type == 1) { if (this.scale == 0) { labelColor = cc.color(22, 196, 88); } else if (this.scale == 1) { labelColor = cc.color(0, 194, 141); } else if (this.scale == 2) { labelColor = cc.color(54, 171, 253); } else if (this.scale == 3) { labelColor = cc.color(255, 90, 90); } } } if (this.startX > this.maxWidth - this.fontSize) { this.startX = 0; this.startY -= this.lineHeight; } let lnode = new cc.Node(); lnode.color = labelColor; let lab = lnode.addComponent(cc.Label); // if (this.fontRes) // lab.font = this.fontRes; // else // lab.font = GameModel.fontRes; lab.cacheMode = cc.Label.CacheMode.BITMAP lab.fontSize = this.fontSize; lab.lineHeight = this.lineHeight; lab.string = str; lnode.setAnchorPoint(cc.v2(0, 1)); lnode.setPosition(cc.v2(this.startX, this.startY)); lnode.parent = this.node; this.startX += lnode.width; }, addScaleNode() { if (this.scale == null) { return; } let scaleFrame = null; if (this.scale == 0) { scaleFrame = this.emojiAtlas.getSpriteFrame('font_back_all'); } else if (this.scale == 1) { scaleFrame = this.emojiAtlas.getSpriteFrame('font_back_team'); } else if (this.scale == 2) { scaleFrame = this.emojiAtlas.getSpriteFrame('font_back_bang'); } else if (this.scale == 3) { scaleFrame = this.emojiAtlas.getSpriteFrame('font_back_system'); } // else if (this.scale == 7) { // scaleFrame = this.emojiAtlas.getSpriteFrame('font_back_system'); // } if (scaleFrame == null) { return; } if (this.startX > this.maxWidth - this.fontSize) { this.startX = 0; this.startY -= this.lineHeight; } let snode = new cc.Node(); let sp = snode.addComponent(cc.Sprite); sp.spriteFrame = scaleFrame; snode.setAnchorPoint(cc.v2(0, 0.5)); snode.setPosition(cc.v2(this.startX, this.startY - this.lineHeight / 2)); snode.setScale(this.lineHeight / snode.height); snode.parent = this.node; this.startX += snode.width * snode.scaleX; }, addImgNode(img) { let emojiFrame = this.emojiAtlas.getSpriteFrame(('000' + img).substr(-3) + '0000'); if (emojiFrame == null) { return; } let emojiFrames = []; for (let i = 0; ; i++) { let frame = this.emojiAtlas.getSpriteFrame(('000' + img).substr(-3) + ('0000' + i).substr(-4)); if (frame) emojiFrames.push(frame); else break; } let snode = new cc.Node(); let sp = snode.addComponent(cc.Sprite); sp.spriteFrame = emojiFrame; snode.setAnchorPoint(cc.v2(0, 0.5)); snode.setScale(this.lineHeight / snode.height); snode.parent = this.node; if (this.startX + snode.width * snode.scaleX > this.maxWidth - this.fontSize) { this.startX = 0; this.startY -= this.lineHeight; } snode.setPosition(cc.v2(this.startX, this.startY - this.lineHeight / 2)); this.startX += snode.width * snode.scaleX; if (emojiFrames.length > 0) { let emojiClip = cc.AnimationClip.createWithSpriteFrames(emojiFrames, 10); emojiClip.name = 'run'; emojiClip.wrapMode = cc.WrapMode.Loop; let nodeAni = snode.addComponent(cc.Animation); nodeAni.addClip(emojiClip); nodeAni.play('run'); } }, addLinkNode(link) { let strs = link.split("@"); if (strs.length < 2) { this.addLabelNode(link); return; } if (strs[2] == 10) { // 加入隊伍按鈕 this.addJoinTeamNode(link) return } let labelColor = this.node.color; labelColor = cc.color(0, 194, 141); if (this.startX > this.maxWidth - this.fontSize) { this.startX = 0; this.startY -= this.lineHeight; } let lnode = new cc.Node(); lnode.color = labelColor; let lab = lnode.addComponent(cc.Label); // if (this.fontRes) // lab.font = this.fontRes; // else // lab.font = GameModel.fontRes; lab.cacheMode = cc.Label.CacheMode.BITMAP lab.fontSize = this.fontSize; lab.lineHeight = this.lineHeight; lab.string = '[' + strs[0] + ']'; lnode.setAnchorPoint(cc.v2(0, 1)); lnode.setPosition(cc.v2(this.startX, this.startY)); lnode.parent = this.node; let btn = lnode.addComponent(cc.Button); btn.transition = cc.Button.Transition.NONE; var clickEventHandler = new cc.Component.EventHandler(); clickEventHandler.target = this.node; clickEventHandler.component = "CustomRichText"; clickEventHandler.handler = "onLinkPropClicked"; clickEventHandler.customEventData = link; btn.clickEvents.push(clickEventHandler); this.startX += lnode.width; }, /** * 加入隊伍 * @param {*} link */ addJoinTeamNode(link) { if (this.startX > this.maxWidth - this.fontSize) { this.startX = 0; this.startY -= this.lineHeight; } let snode = new cc.Node(); let sp = snode.addComponent(cc.Sprite); sp.spriteFrame = this.joinTeamBg; snode.setAnchorPoint(cc.v2(0, 0.5)); snode.setPosition(cc.v2(this.startX, this.startY - this.lineHeight / 2)); snode.setScale(this.lineHeight / 40); snode.parent = this.node; let lnode = new cc.Node(); lnode.color = new cc.Color(100, 60, 60); let title = "加入"; let textRT = lnode.addComponent(cc.Label); // if (this.fontRes) // textRT.font = this.fontRes; // else // textRT.font = GameModel.fontRes; textRT.fontSize = this.fontSize + 6; textRT.lineHeight = this.lineHeight; textRT.string = title; lnode.setPosition(cc.v2(43, 0)); lnode.setAnchorPoint(cc.v2(0.5, 0.5)); lnode.parent = snode; this.startX += 86 * snode.scaleX; let btn = snode.addComponent(cc.Button); btn.transition = cc.Button.Transition.NONE; var clickEventHandler = new cc.Component.EventHandler(); clickEventHandler.target = this.node; clickEventHandler.component = "CustomRichText"; if (this.type != 1) clickEventHandler.handler = "onLinkJoinTeam"; else clickEventHandler.handler = "onLinkPropClicked"; clickEventHandler.customEventData = link; btn.clickEvents.push(clickEventHandler); }, onLinkJoinTeam(event, link) { console.log(event, link) let strs = link.split("@"); GameModel.send('c2s_requst_team', { roleid: GameModel.player.roleid, teamid: strs[1] }); }, onLinkJoinTeam1(event, link) { let strs = link.split("@"); GameModel.send('c2s_requst_team', { roleid: GameModel.player.roleid, teamid: strs[1] }); }, onLinkPropClicked(event, link) { let datas = link.split("@"); if (datas[2] == 10) datas[2] = 9 GameModel.send("c2c_goods_info", { type: datas[2], id: datas[1] }); }, cutStringByWidth(str, w) { // TODO : 修改此方法 1 使用池管理 2 取消本方法 使用 RichText if (w < 0) { w = 0; } let lnode = new cc.Node(); let lab = lnode.addComponent(cc.Label); lab.fontSize = this.fontSize; lab.lineHeight = this.lineHeight; lab.string = str; lnode.parent = this.node; let tempLen = str.length; if (lab.node.width > w) { tempLen = Math.ceil((w / lab.node.width) * str.length) + 2; if (tempLen > str.length) { tempLen = str.length; } str = str.substr(0, tempLen); lab.string = str; lab._forceUpdateRenderData(true); while (lab.node.width > w) { str = str.substr(0, tempLen - 1); tempLen -= 1; lab.string = str; lab._forceUpdateRenderData(true); } } lnode.parent = null; lnode.destroy(); return tempLen; } });