Files
18xchat/.svn/pristine/70/708777da0be1f1d001adb8dad18a50467ee71871.svn-base
2025-07-17 17:18:21 +08:00

957 lines
36 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { _decorator, AudioSource, EditBox, EventTouch, isValid, Label, Node, ScrollView, Sprite, Tween, tween, UIOpacity, utils, v3, Vec3 } from 'cc';
import { GButton } from '../../Main/Common/GButton';
import Utils from '../../Main/Common/Utils';
import { ViewManager } from '../../Main/Manager/ViewManager';
import { InnerMsgCode } from '../../Main/Config/InnerMsgCode';
import li_BaseView from '../../Main/Common/li_BaseView';
import SubManager from '../SubManager';
import GameManager, { E_TalkStage, E_TalkStatusType } from '../../Main/Manager/GameManager';
import { I_LevelConfig, I_NpcTalkBack } from '../../Main/Config/CommonConfig';
import HttpUnit from '../../Main/Common/HttpUnit';
import { SDKManager } from '../../Main/Channel/SDKManager';
import ResManager from '../../Main/Manager/ResManager';
import PlayerDataManager from '../../Main/Manager/PlayerDataManager';
import GameRootUI from '../../Main/Common/GameRootUI';
import { E_AD_TARGET } from './TalkAdDialog';
import GlobalValue from '../../Main/Common/GlobalValue';
import AudioManager from '../../Main/Manager/AudioManager';
const { ccclass, property } = _decorator;
//聊天界面
@ccclass('Talk_UI')
export class Talk_UI extends li_BaseView {
private _nodeTab: any = {};
private _data;
private dazijiInfo = {stage: 0, idx: 0, str: "", tm:0, ts:0.05, lab:null}; //打字机信息 stage:0-未开始,1-正在打字,2-打字结束
private npcTalkInfo = {stage: 0, str:"", dotStr:"...", dotIdx:0, dotTm:0, dotTs:0.3, tm:0, ts:1.5}; //等待npc回复 stage:0-未开始,1-获取中,2-获取完成
private aiHuifuInfo = {stage: 0, labAry:[], dotStr:"...", dotIdx:0, dotTm:0, dotTs:0.3}; //等待ai回复 stage:0-未开始,1-获取中,2-获取完成
private ebTalk: EditBox;
private labNpcTalk: Label;
private xindongSpt: Sprite;
private lvCfg: I_LevelConfig = null; //当前关卡配置
private lastRandTalkIdx: number = -1; //上一次随机对话的索引
//----重写父类接口---------------------------------------
onLoadCT() {
Utils.parseNode(this.node, this._nodeTab)
this.registerListenner();
this.ebTalk = this._nodeTab.ebTalk.getComponent(EditBox);
this.labNpcTalk = this._nodeTab.npcTalk.getComponent(Label);
this.xindongSpt = this._nodeTab.xindongSpt.getComponent(Sprite);
this.ebTalk.node.on('editing-did-began', this.onEditingBegan, this);
this.ebTalk.node.on('editing-did-ended', this.onEditingEnded, this);
this.ebTalk.node.on('editing-return', this.onEditingReturn, this);
// this._nodeTab.npcTalkSV.on(Node.EventType.TOUCH_START, (event: EventTouch)=>{
// event.preventSwallow = true; //允许点击事件穿透
// }, this);
this._nodeTab.npcTalkSV.getChildByName("view").on(Node.EventType.TOUCH_END, (event:EventTouch) => {
// event.preventSwallow = true; //允许点击事件穿透
this.onNpcFramClick();
}, this);
this._nodeTab.arrowNode.active = false;
let npcNextArrow:Node = this._nodeTab.npcNextArrow
tween(npcNextArrow)
.to(0.5, {position: new Vec3(15, 0, 0)})
.to(0.5, {position: new Vec3(-15, 0, 0)})
.union()
.repeatForever()
.start()
}
openUIDataCT(data: any): void {
this._data = data
}
registerListenner() {
Utils.addInnerEL(InnerMsgCode.Data_NpcTalkBack, this, this.resiveNpcTalkBack)
Utils.addInnerEL(InnerMsgCode.UI_Socket_Timeout, this, this.resiveSocketTimeout)
Utils.addInnerEL(InnerMsgCode.UI_TalkStageUp, this, this.resiveTalkStageUp)
Utils.addInnerEL(InnerMsgCode.Data_LevelStarUp, this, this.resiveLevelStarUp)
Utils.addInnerEL(InnerMsgCode.Data_ChehuiUp, this, this.resiveChehuiUp)
Utils.addInnerEL(InnerMsgCode.UI_ResartGame, this, this.resiveResartGame)
}
start() {
GButton.BandClick(this._nodeTab.btnBack, this.onBackClick, this);
GButton.BandClick(this._nodeTab.btnSend, this.onSendClick, this);
GButton.BandClick(this._nodeTab.btnSuiji, this.onSuijiClick, this);
//弹窗适配
let scaleRatio = Utils.getScaleRatio(2)
if (scaleRatio > 1) {
scaleRatio = 1;
}
this._nodeTab.gs1frame.scale = new Vec3(scaleRatio, scaleRatio, 1)
//规则内容
Utils.setString(this._nodeTab.labGs1Tips, GlobalValue.RuleStr)
// GButton.BandClick(this._nodeTab.npcTalkFrame, ()=>{
// this.onNpcFramClick();
// }, this, 0, null, null, false);
GButton.BandClick(this._nodeTab.btnRecord, ()=>{
// // 测试代码
// if (true) {
// this.showXinAddAnimation()
// return
// }
ViewManager.I.openBundlesView("UI/StartUI/Record_UI")
}, this);
GButton.BandClick(this._nodeTab.btnTishi, ()=>{
ViewManager.I.openBundlesView("UI/StartUI/Tips_UI")
//上报服务器记录
HttpUnit.ins.sendTipRecord({level_id: this.lvCfg.id}, null)
}, this);
GButton.BandClick(this._nodeTab.btnAD, ()=>{
let contStr = ""
let levelData = GameManager.CurLevelData
if (!levelData || levelData.ad_num <= 0) {
contStr = "关卡内续航次数已用完"
} else {
contStr = `看广告或分享可额外获取对话次数,剩余${levelData.ad_num}次`
}
ViewManager.I.openBundlesView("UI/StartUI/TalkAdDialog", {
type: E_AD_TARGET.liaotian, //加聊天次数
content: contStr,
adCallback: ()=>{
SDKManager.show_reward_video_ad(this.node.uuid, 1)
},
shareCallback: ()=>{
SDKManager.show_reward_share(this.node.uuid, 1)
}
})
}, this);
GButton.BandClick(this._nodeTab.btnJia10, ()=>{
let contStr = ""
let levelData = GameManager.CurLevelData
if (!levelData || levelData.can_use_strength_cnt <= 0) {
contStr = "关卡内加分次数已用完"
} else {
contStr = `观看广告,下一次聊天的最终得分增加 10 分(不会超过 100 分,也不会影响对话效果),剩余${levelData.can_use_strength_cnt}次`
}
ViewManager.I.openBundlesView("UI/StartUI/TalkAdDialog", {
type: E_AD_TARGET.baoji, //加聊天次数
content: contStr,
adCallback: ()=>{
SDKManager.show_reward_video_ad(this.node.uuid, 2)
},
shareCallback: ()=>{
SDKManager.show_reward_share(this.node.uuid, 2)
}
})
}, this);
GButton.BandClick(this._nodeTab.btnRole, ()=>{
this._nodeTab.ruleNode.active = true
}, this);
GButton.BandClick(this._nodeTab.btnRoleOk, ()=>{
this.onRoleCloseClick()
}, this);
GButton.BandClick(this._nodeTab.btnRoleClose, ()=>{
this.onRoleCloseClick()
}, this);
//ai语音开关
GButton.BandClick(this._nodeTab.btnYuyin, ()=>{
GameManager.AIVoiceSwt = !GameManager.AIVoiceSwt;
this.refreshAIVoiceState()
}, this);
this.refreshAIVoiceState()
if (!SDKManager.checkSupportBase64Audio()) {
this._nodeTab.btnYuyin.active = false
}
SDKManager.register_video_reward(this.node.uuid, (tag:number)=>{
console.log("视频广告回调", tag)
if (tag == 1) {
// 加次数
SubManager.ShowPrompt("观看视频成功,获得聊天次数")
this.doAddLevelCnt(1)
} else if (tag == 2) {
// 甜蜜暴击
SubManager.ShowPrompt("观看视频成功")
this.doStrengthTalk()
}
})
SDKManager.register_share_reward(this.node.uuid, (tag:number)=>{
console.log("分享回调", tag)
if (tag == 1) {
// 加次数
SubManager.ShowPrompt("分享成功,获得聊天次数")
this.doAddLevelCnt(2)
}
})
this.initedGame()
this.initXinAni()
}
onDestroy () {
super.onDestroy()
if (isValid(this.ebTalk)) {
this.ebTalk.node.off('editing-did-began', this.onEditingBegan, this);
this.ebTalk.node.off('editing-did-ended', this.onEditingEnded, this);
this.ebTalk.node.off('editing-return', this.onEditingReturn, this);
}
}
update(deltaTime: number) {
//region 打字机效果逻辑
if (this.dazijiInfo.stage == 1) {
this.dazijiInfo.tm += deltaTime
if (this.dazijiInfo.tm >= this.dazijiInfo.ts) {
this.dazijiInfo.tm = 0
this.dazijiInfo.lab.string = this.dazijiInfo.str.substring(0, this.dazijiInfo.idx)
this.dazijiInfo.idx += 1
if (this.dazijiInfo.idx > this.dazijiInfo.str.length) {
this.dazijiInfo.stage = 2
}
let talksv = this._nodeTab.npcTalkSV.getComponent(ScrollView)
talksv.scrollToBottom(0.1)
}
} else if (this.dazijiInfo.stage == 2) {
console.log("文本打字机效果结束")
this.dazijiInfo.stage = 0
this.dazijiInfo.lab.string = this.dazijiInfo.str
this._nodeTab.arrowNode.active = true;
let talksv = this._nodeTab.npcTalkSV.getComponent(ScrollView)
this.scheduleOnce(() => {
talksv.scrollToBottom(0.1)
}, 0.1)
}
//接收npc回复逻辑
if (this.npcTalkInfo.stage == 1) {
//...的频率
this.npcTalkInfo.dotTm += deltaTime
if (this.npcTalkInfo.dotTm >= this.npcTalkInfo.dotTs) {
this.npcTalkInfo.dotTm = 0
this.labNpcTalk.string = this.npcTalkInfo.dotStr.substring(0, this.npcTalkInfo.dotIdx)
this.npcTalkInfo.dotIdx += 1
if (this.npcTalkInfo.dotIdx > this.npcTalkInfo.dotStr.length) {
this.npcTalkInfo.dotIdx = 0
}
}
//sorket获取频率
this.npcTalkInfo.tm += deltaTime
if (this.npcTalkInfo.tm >= this.npcTalkInfo.ts) {
this.npcTalkInfo.tm = 0
GameManager.I.getNpcTalkBack({})
}
}
//接收ai回复逻辑
if (this.aiHuifuInfo.stage == 1) {
//...的频率
this.aiHuifuInfo.dotTm += deltaTime
if (this.aiHuifuInfo.dotTm >= this.aiHuifuInfo.dotTs) {
this.aiHuifuInfo.dotTm = 0
this.aiHuifuInfo.labAry.forEach((_lab: Label) => {
_lab.string = "提示加载中" + this.aiHuifuInfo.dotStr.substring(0, this.aiHuifuInfo.dotIdx)
})
this.aiHuifuInfo.dotIdx += 1
if (this.aiHuifuInfo.dotIdx > this.aiHuifuInfo.dotStr.length) {
this.aiHuifuInfo.dotIdx = 0
}
}
}
}
//region NPC回复消息
/**接收到npc回复数据流 */
resiveNpcTalkBack(data:I_NpcTalkBack) {
this.npcTalkInfo.stage = 0
GameManager.TurnToStage(E_TalkStage.npcTalk)
let npcTalk = GameManager.CurNpcTalkData
//npc回复后清空玩家之前的输入
if (npcTalk.judgement > -1) {
this.ebTalk.string = ""
this.refreshInputNum()
}
//友盟事件上报 对话轮数
let id = HttpUnit.GetID()
SDKManager.umaEvent(SDKManager.Uma_Event_TalkRound, {
userId: id+"", //玩家id
ISay: npcTalk.userInput, //玩家发言
NpcSay: npcTalk.aiResponse, //npc发言
})
}
/**socket连接超时 */
resiveSocketTimeout(data:any) {
SubManager.ShowConfirm({
content: "连接已断开,请重新开始游戏",
hideNo: true, //隐藏取消按钮
yesCallback: () => {
ViewManager.I.closeAllView();
Utils.sendInnerMsg(InnerMsgCode.UI_Talk_Back, {})
},
closeCallback: () => {
ViewManager.I.closeAllView();
Utils.sendInnerMsg(InnerMsgCode.UI_Talk_Back, {})
}
})
this.npcTalkInfo.stage = 0
}
/**接收到聊天状态变化消息 */
resiveTalkStageUp(data:any) {
this.refreshTalkStage()
}
/**接收到星级变化消息 */
resiveLevelStarUp(data:any) {
if (data && data.level == GameManager.CurLevelId) {
for (let i=1; i<=3; i++) {
let lsStar = this._nodeTab["lsStar"+i].getComponent(Sprite)
let starPath = data.star >= i ? "lv_3" : "lv_2"
ResManager.I.changeBundleSpriteFrame(lsStar, starPath, "Zhujiemian")
}
}
}
//region 撤回逻辑
/**收到撤回消息 */
resiveChehuiUp(data:any) {
//刷新次数
this.refreshTalkStepData()
//刷新对话得分
this.refreshDuihuaDefen()
//刷新心动次数
this.refreshXindongCishu(false)
//刷新npc表情
let talkdata = GameManager.CurNpcTalkData
let aiEmoji = talkdata ? talkdata.aiEmoji : ""
let rolePath = GameManager.GetNpcEmoPic(aiEmoji)
Utils.sendInnerMsg(InnerMsgCode.SceneLayerBgUp, {rolePath:rolePath})
}
/**重新开始游戏 */
resiveResartGame(data:any) {
console.log("重新开始游戏")
this.initedGame()
}
//region UI初始化
/**初始化 */
initedGame() {
this.lvCfg = GameManager.getLevelCfg(GameManager.CurLevelId)
//背景乐
let bgmUrl = `https://hxzgame.vip.hnhxzkj.com/lzx/XiangQin/BGM/${this.lvCfg.bgm}.mp3`
AudioManager.I.PlayRemoteMusic(bgmUrl, true)
//名称
Utils.setString(this._nodeTab.npcName, this.lvCfg.name)
//刷新历史星级
for (let i=1; i<=3; i++) {
let lsStar = this._nodeTab["lsStar"+i].getComponent(Sprite)
let starPath = this.lvCfg.star >= i ? "lv_3" : "lv_2"
ResManager.I.changeBundleSpriteFrame(lsStar, starPath, "Zhujiemian")
}
this._nodeTab.ruleNode.active = false
this.hideAiAnswer()
this.refreshTalkStage()
//刷新状态显示
this.refreshTalkStepData()
this.refreshBaojiState()
this.refreshXindongCishu(false)
this.refreshDuihuaDefen()
//检测引导
this.checkGuide()
//开始时先自动显示一下npc的攻略
if (PlayerDataManager.I.GuideTalkFinished) {
this.autoShowNpcTip()
}
}
//输入框开始编辑事件
onEditingBegan(param1:any, param2:any) {
console.log("聊天界面1 onEditingBegan", param1, param2)
}
//输入框回车事件
onEditingReturn(param1:any, param2:any) {
console.log("聊天界面2 onEditingReturn", param1, param2)
}
//输入框结束编辑事件
onEditingEnded(param1:any, param2:any) {
console.log("聊天界面3 onEditingEnded", param1, param2)
}
//输入框文本改变事件
onTextChanged(param1:any, param2:any) {
// console.log("聊天界面4 onTextChanged", param1, param2)
this.refreshInputNum()
}
//刷新AI语音状态
private refreshAIVoiceState() {
let voicePath = GameManager.AIVoiceSwt ? "lv_4" : "lv_5"
let sptYuyin = this._nodeTab.sptYuyin.getComponent(Sprite)
ResManager.I.changeBundleSpriteFrame(sptYuyin, voicePath, "Zhujiemian")
}
//播放AI语音
private playAIVoice(str:string) {
if (!GameManager.AIVoiceSwt) {
return //开关没开
}
if (!SDKManager.checkSupportBase64Audio()) {
return //不支持base64音频
}
HttpUnit.ins.getAIVoice({record_id: GameManager.RecordId, text:str}, (data) => {
if (data) {
console.log("播放AI语音11", data)
SDKManager.playBase64Audio(data.url, false)
}
})
}
//region 刷新聊天状态
private refreshTalkStage() {
let gStage = GameManager.curStage
if (gStage == E_TalkStage.prologue) {
this.showNpcPrologue()
} else if (gStage == E_TalkStage.myTalk) {
this.turnToMyTalk()
this.showAiAnswer()
} else if (gStage == E_TalkStage.waitNpcTalk) {
this.turnToWaitNpcTalk()
} else if (gStage == E_TalkStage.npcTalk) {
this.turnToNpcTalk(GameManager.CurNpcTalkData)
} else if (gStage == E_TalkStage.npcFixedTalk) {
this.turnToNpcFixedTalk(GameManager.CurNpcFixedTalkText)
} else if (gStage == E_TalkStage.upTalkStatus) {
this.turnToUpdateStage()
}
}
//显示NPC开场白
private showNpcPrologue() {
this._nodeTab.NpcTalkNode.active = true
this._nodeTab.MyTalkNode.active = false
this._nodeTab.arrowNode.active = false;
//开场白
this.dazijiInfo.stage = 1
this.dazijiInfo.idx = 0
this.dazijiInfo.lab = this.labNpcTalk
this.dazijiInfo.str = this.lvCfg.prologueMessage
this.dazijiInfo.tm = this.dazijiInfo.ts
GameManager.AddTalkRecord({talk:this.lvCfg.prologueMessage, isMe:false, score:-1, scoreBase:-1, scoreAdditional:0})
// this.playAIVoice(this.lvCfg.prologueMessage)
}
/**切换到玩家说话状态 */
private turnToMyTalk() {
this._nodeTab.NpcTalkNode.active = false
this._nodeTab.MyTalkNode.active = true
// //刷新npc表情
// let rolePath = GameManager.GetNpcEmoPic("")
// Utils.sendInnerMsg(InnerMsgCode.SceneLayerBgUp, {rolePath:rolePath})
}
/**切换到等待NPC说话状态 */
private turnToWaitNpcTalk() {
this._nodeTab.NpcTalkNode.active = true
this._nodeTab.MyTalkNode.active = false
this._nodeTab.arrowNode.active = false;
this.labNpcTalk.string = ""
}
/**切换到NPC说话状态 */
private turnToNpcTalk(data:I_NpcTalkBack) {
this._nodeTab.NpcTalkNode.active = true
this._nodeTab.MyTalkNode.active = false
this._nodeTab.arrowNode.active = false;
GameManager.AddStepScore(data.aiScore) //记录本次分数
this.refreshDuihuaDefen()
//npc回复
// this.labNpcTalk.string = data.aiResponse
this.dazijiInfo.stage = 1
this.dazijiInfo.idx = 0
this.dazijiInfo.lab = this.labNpcTalk
this.dazijiInfo.str = data.aiResponse
this.dazijiInfo.tm = this.dazijiInfo.ts
GameManager.AddTalkRecord({talk:data.aiResponse, isMe:false, score:data.aiScore, scoreBase:data.aiBaseScore, scoreAdditional:data.aiAdditionalScore})
this.playAIVoice(data.aiResponse)
//刷新npc表情
let rolePath = GameManager.GetNpcEmoPic(data.aiEmoji)
Utils.sendInnerMsg(InnerMsgCode.SceneLayerBgUp, {rolePath:rolePath})
//额外分数
if (data.aiAdditionalScore > 0) {
SubManager.ShowPrompt(`恭喜!聊天加分成功!${data.aiBaseScore} + ${data.aiAdditionalScore}`)
}
//对话轮次
GameManager.srouceCnt = data.sourceCnt
this.refreshTalkStepData()
}
/**切换到npc固定话术展示状态 */
private turnToNpcFixedTalk(str:string) {
this._nodeTab.NpcTalkNode.active = true
this._nodeTab.MyTalkNode.active = false
this._nodeTab.arrowNode.active = false;
//npc固定话术
this.dazijiInfo.stage = 1
this.dazijiInfo.idx = 0
this.dazijiInfo.lab = this.labNpcTalk
this.dazijiInfo.str = str
this.dazijiInfo.tm = this.dazijiInfo.ts
}
/**切换到更新聊天状态状态 */
private turnToUpdateStage() {
HttpUnit.ins.getTalkStage({record_id: GameManager.RecordId}, (data) => {
if (data) {
GameManager.CurLevelData = data.level
this.refreshTalkStepData()
this.refreshBaojiState()
this.checkIsFinish()
}
})
}
/**刷新心动次数 */
private refreshXindongCishu(doAct:boolean = true) {
let maxCount = HttpUnit.GetXindongMaxCount()
let curCount = GameManager.xindongCishu
Utils.setString(this._nodeTab.xindongNum, `${curCount}/${maxCount}`)
Tween.stopAllByTarget(this.xindongSpt)
if (doAct) {
tween(this.xindongSpt).to(0.3, { fillRange: curCount / maxCount }).start()
} else {
this.xindongSpt.fillRange = curCount / maxCount
}
}
/**刷新对话得分 */
private refreshDuihuaDefen() {
let curScore = GameManager.getCurStepScore()
let [totalScore, pjScore] = GameManager.getGameScore()
Utils.setString(this._nodeTab.scoreNew, curScore+"")
Utils.setString(this._nodeTab.scoreTotal, totalScore+"")
}
/**刷新当前状态显示 */
private refreshTalkStepData() {
let curCnt = GameManager.srouceCnt
let stepData = GameManager.CurLevelData
Utils.setString(this._nodeTab.lunciNum, `${curCnt}/${stepData.total_cnt}`)
}
/**刷新暴击状态是否显示 */
private refreshBaojiState() {
let stepData = GameManager.CurLevelData
this._nodeTab.baojiNode.active = stepData && stepData.is_strength_take_effect == true
}
/**刷新玩家输入字数 */
private refreshInputNum() {
let numMax = this.ebTalk.maxLength
let numCur = this.ebTalk.string.length
Utils.setString(this._nodeTab.labStrLen, `(${numCur}/${numMax})`)
}
//region 检测是否结束
/**检查对话轮次是否用完
* @returns [是否结束对话,是否显示广告加次数]
*/
private checkIsFinish() {
let isFinish = false //是否结束对话
let isShowAD = false //是否显示广告
let isSendEnd = false //是否发送结束请求
let stepData = GameManager.CurLevelData
if (stepData.status == E_TalkStatusType.succ) {
//已成功
isFinish = true
} else if (stepData.status == E_TalkStatusType.fail) {
//已失败
isFinish = true
} else if (stepData.status == E_TalkStatusType.noCount) {
//次数已用完
isFinish = true
isShowAD = stepData.ad_num > 0 //true
isSendEnd = true
}
if (isFinish) {
if (isShowAD) {
ViewManager.I.openBundlesView("UI/StartUI/TalkAdDialog", {
type: E_AD_TARGET.liaotian, //加聊天次数
content: "看广告或分享可额外获取对话次数",
adCallback: ()=>{
SDKManager.show_reward_video_ad(this.node.uuid, 1)
},
shareCallback: ()=>{
SDKManager.show_reward_share(this.node.uuid, 1)
},
closeCallback: ()=>{
if (isSendEnd) {
this.doJiesuan()
} else {
ViewManager.I.openBundlesView("UI/StartUI/Finish_UI", stepData)
}
}
})
} else {
if (isSendEnd) {
this.doJiesuan()
} else {
ViewManager.I.openBundlesView("UI/StartUI/Finish_UI", stepData)
}
}
} else {
GameManager.TurnToStage(E_TalkStage.myTalk)
}
}
//增加聊天次数 atype: 1=看广告 2=分享
private doAddLevelCnt(atype:number) {
HttpUnit.ins.addTalkCnt({record_id: GameManager.RecordId, type:atype}, (data) => {
if (data) {
GameManager.CurLevelData = data.level
this.refreshTalkStepData()
this.refreshBaojiState()
//判断是否继续对话
if (GameManager.srouceCnt < data.level.total_cnt) {
if (GameManager.curStage != E_TalkStage.waitNpcTalk) {
GameManager.TurnToStage(E_TalkStage.myTalk)
}
} else {
this.doJiesuan()
}
}
})
}
/**增强下一轮对话 */
private doStrengthTalk() {
HttpUnit.ins.sendTalkStrength({record_id: GameManager.RecordId}, (data) => {
if (data) {
GameManager.CurLevelData = data.level
this.refreshBaojiState()
}
})
}
//结算
private doJiesuan() {
let [score_all, score] = GameManager.getGameScore()
HttpUnit.ins.sendLevelFinish({record_id: GameManager.RecordId, score:score, score_all:score_all}, (data) => {
if (data && data.level) {
//成功
ViewManager.I.openBundlesView("UI/StartUI/Finish_UI", data.level)
} else {
//失败
console.warn("结算失败,服务器返回异常!")
ViewManager.I.closeAllView();
Utils.sendInnerMsg(InnerMsgCode.UI_Talk_Back, {})
}
})
}
//退出聊天
onBackClick() {
SubManager.ShowConfirm({
content: "确定退出吗?\n(退出会保留当前聊天进度)",
yesCallback: () => {
//退出并结算
// this.doJiesuan();
//只退出聊天,不结算
this.onClose();
Utils.sendInnerMsg(InnerMsgCode.UI_Talk_Back, {})
}
})
}
//发送消息
onSendClick() {
let str = this.ebTalk.string;
if (str.length == 0) {
SubManager.ShowPrompt("请先输入内容")
return
}
GameRootUI.DisableOper(2)
HttpUnit.ins.sendUserTalk({record_id: GameManager.RecordId, user_input: str}, (data) => {
GameRootUI.EnableOper()
if (data) {
if (GameManager.curStage != E_TalkStage.myTalk) {
return
}
GameManager.TurnToStage(E_TalkStage.waitNpcTalk)
this.hideAiAnswer()
//使用服务器处理过的字符串
if (data.user_input) {
str = data.user_input
}
GameManager.AddTalkRecord({talk:str, isMe:true, score:-1, scoreBase:-1, scoreAdditional:0})
//开始接收npc回复
this.npcTalkInfo.stage = 1
this.npcTalkInfo.str = ""
this.npcTalkInfo.dotTm = this.npcTalkInfo.dotTs
this.npcTalkInfo.tm = this.npcTalkInfo.ts
this.npcTalkInfo.dotIdx = 1
}
})
}
//随机回复对话
onSuijiClick() {
let sjLen = this.lvCfg.randomInputPool.length
let randIdx = Utils.getRandomInt(0, sjLen-1)
console.log("随机回复对话:", randIdx, sjLen)
if (randIdx == this.lastRandTalkIdx) {
randIdx++
if (randIdx >= sjLen) randIdx = 0
}
this.lastRandTalkIdx = randIdx
this.ebTalk.string = this.lvCfg.randomInputPool[randIdx]
this.refreshInputNum()
}
//点击npc对话背景
onNpcFramClick() {
if (this.dazijiInfo.stage == 1) {
this.dazijiInfo.stage = 2
} else {
if (GameManager.curStage == E_TalkStage.prologue) {
GameManager.TurnToStage(E_TalkStage.upTalkStatus)
} else if (GameManager.curStage == E_TalkStage.npcTalk) {
let npcTalk = GameManager.CurNpcTalkData
if (npcTalk.judgement == 0) {
console.log("固定鼓励话术展示!", GameManager.npcFixTalkCountXihuan)
if (GameManager.npcFixTalkCountXihuan > 0) {
GameManager.TurnToStage(E_TalkStage.upTalkStatus)
} else {
GameManager.CurNpcFixedTalkText = this.lvCfg.encourageMessage
GameManager.TurnToStage(E_TalkStage.npcFixedTalk)
}
GameManager.npcFixTalkCountXihuan = GameManager.npcFixTalkCountXihuan + 1
GameManager.xindongCishu = GameManager.xindongCishu + 1
this.showXinAddAnimation()
// this.refreshXindongCishu(true)
} else if (npcTalk.judgement == 2) {
console.log("固定厌恶话术展示!", GameManager.npcFixTalkCountTaoyan)
if (GameManager.npcFixTalkCountTaoyan > 0) {
GameManager.TurnToStage(E_TalkStage.upTalkStatus)
} else {
GameManager.CurNpcFixedTalkText = this.lvCfg.hateMessage
GameManager.TurnToStage(E_TalkStage.npcFixedTalk)
}
GameManager.npcFixTalkCountTaoyan = GameManager.npcFixTalkCountTaoyan + 1
} else {
GameManager.TurnToStage(E_TalkStage.upTalkStatus)
}
} else if (GameManager.curStage == E_TalkStage.npcFixedTalk) {
GameManager.TurnToStage(E_TalkStage.upTalkStatus)
}
}
}
//region ai生成的回复
/**从服务器获取回复 */
private showAiAnswer() {
this._nodeTab.aiAnsNode.active = true
//获取到之前
this.aiHuifuInfo.labAry = []
for (let i=1; i<=3; i++) {
let AiAnsItem: Node = this._nodeTab["AiAnsItem"+i]
let labAns = AiAnsItem.getComponentInChildren(Label)
labAns.string = "" // "提示加载中..."
GButton.RemoveAndBandClick(AiAnsItem, ()=>{
SubManager.ShowPrompt("提示获取中,请稍后")
}, this);
this.aiHuifuInfo.labAry.push(labAns)
}
//播放ai回复效果
this.aiHuifuInfo.stage = 1
this.aiHuifuInfo.dotTm = this.aiHuifuInfo.dotTs
this.aiHuifuInfo.dotIdx = 1
HttpUnit.ins.getAIAutoAns({record_id: GameManager.RecordId}, (data) => {
//获取到之后
this.aiHuifuInfo.stage = 0
if (data) {
console.log("从服务器获取回复", data)
let gStage = GameManager.curStage
if (gStage == E_TalkStage.myTalk) {
for (let i=1; i<=3; i++) {
let AiAnsItem: Node = this._nodeTab["AiAnsItem"+i]
let labAns = AiAnsItem.getComponentInChildren(Label)
let ans = data["tips"+i]
if (ans) {
labAns.string = this.clampAiAnswer(ans)
GButton.RemoveAndBandClick(AiAnsItem, ()=>{
this.ebTalk.string = ans
this.refreshInputNum()
}, this);
} else {
labAns.string = ""
GButton.RemoveClick(AiAnsItem);
}
}
}
}
})
}
private hideAiAnswer() {
this._nodeTab.aiAnsNode.active = false
}
//截取字符串,超过长度的用...代替
private clampAiAnswer(ansStr: string) {
let labelLimit = 20 //字符串长度限制
let tempStr: string = "";
let tempLen: number = 0;
for (let i = 0; i < ansStr.length; i++) {
tempLen += ansStr.charCodeAt(i) > 255 ? 2 : 1;
if (tempLen > labelLimit) {
return tempStr + "...";
}
tempStr += ansStr.charAt(i);
}
return ansStr;
}
//region 爱心增加动画
private _xin1PosOrig: Vec3
private _xin2PosOrig: Vec3
private _xin2Opa: UIOpacity = null
//初始化爱心动画
private initXinAni() {
this._xin1PosOrig = (this._nodeTab.xinSpt1 as Node).position.clone()
this._xin2PosOrig = (this._nodeTab.xinSpt2 as Node).position.clone()
this._xin2Opa = this._nodeTab.xinSpt2.getComponent(UIOpacity)
this._xin2Opa.opacity = 0
}
//显示爱心增加动画
private showXinAddAnimation() {
Tween.stopAllByTarget(this._nodeTab.xinSpt2)
Tween.stopAllByTarget(this._xin2Opa)
let xinSpt2: Node = this._nodeTab.xinSpt2
//缩放
xinSpt2.scale = new Vec3(0.1, 0.1, 0.1)
tween(xinSpt2)
.to(0.2, { scale: new Vec3(2.2, 2.2, 1) }, {easing: 'sineIn'})
.to(0.2, { scale: new Vec3(1, 1, 1) }, {easing: 'sineOut'})
.start()
//移动
xinSpt2.position = this._xin2PosOrig
tween(xinSpt2)
.delay(0.4)
.to(0.45, { position: this._xin1PosOrig }, {easing: 'sineIn'})
.call(() => {
this.showXin2Animation()
this.refreshXindongCishu(true) //刷新次数显示
})
.start()
// #region 贝塞尔曲线动作
// // 三维空间的缓动
// const quadraticCurve = (t: number, p1: Vec3, cp: Vec3, p2: Vec3, out: Vec3) => {
// out.x = (1 - t) * (1 - t) * p1.x + 2 * t * (1 - t) * cp.x + t * t * p2.x
// out.y = (1 - t) * (1 - t) * p1.y + 2 * t * (1 - t) * cp.y + t * t * p2.y
// out.z = (1 - t) * (1 - t) * p1.z + 2 * t * (1 - t) * cp.z + t * t * p2.z
// }
// const startPos = this._xin2PosOrig
// const controlPos = v3(2, 3, 0)
// const endPos = this._xin1PosOrig
// const tempVec3 = v3()
// tween(xinSpt2)
// .to(
// 0.45,
// { position: endPos },
// {
// onUpdate: (target, ratio) => {
// quadraticCurve(ratio, startPos, controlPos, endPos, tempVec3)
// xinSpt2.setPosition(tempVec3)
// },
// }
// )
// .call(() => {
// this.showXin2Animation()
// this.refreshXindongCishu(true) //刷新次数显示
// })
// .start()
// #endregion
//透明度
this._xin2Opa.opacity = 0
tween(this._xin2Opa)
.to(0.05, { opacity: 255 })
.delay(0.75)
.to(0.05, { opacity: 0 })
.start()
}
private showXin2Animation() {
Tween.stopAllByTarget(this._nodeTab.xinSpt1)
let xinSpt1: Node = this._nodeTab.xinSpt1
xinSpt1.scale = new Vec3(1, 1, 1)
tween(xinSpt1)
.to(0.3, {scale: new Vec3(1.4, 1.4, 1.4) }, {easing: 'sineInOut'})
.to(0.3, {scale: new Vec3(1, 1, 1) }, {easing: 'sineInOut'})
.start()
}
//region 引导相关
//检查引导
private checkGuide() {
if (PlayerDataManager.I.GuideTalkFinished) {
return
}
let delayInterval = 0.5
GameRootUI.DisableOper(delayInterval)
this.scheduleOnce(() => {
this._nodeTab.ruleNode.active = true
},delayInterval)
}
//引导完成
private finishGuide() {
if (PlayerDataManager.I.GuideTalkFinished) {
return
}
PlayerDataManager.I.SetGuideTalkFinish(true)
this.autoShowNpcTip()
}
//关闭规则弹窗
private onRoleCloseClick() {
this._nodeTab.ruleNode.active = false
this.finishGuide()
}
//自动显示NPC提示弹窗
private autoShowNpcTip() {
if (GameManager.srouceCnt > 0) {
return
}
let delayInterval = 0.5
GameRootUI.DisableOper(delayInterval)
this.scheduleOnce(() => {
ViewManager.I.openBundlesView("UI/StartUI/Tips_UI")
},delayInterval)
}
}