This commit is contained in:
2025-07-17 17:18:21 +08:00
commit 1ffc1b5cf0
5309 changed files with 1150310 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 870 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "1f202d42-9020-49b2-9788-3d525ca13c1f",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "1f202d42-9020-49b2-9788-3d525ca13c1f@6c48a",
"displayName": "echoco_default",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "1f202d42-9020-49b2-9788-3d525ca13c1f",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "1f202d42-9020-49b2-9788-3d525ca13c1f@f9941",
"displayName": "echoco_default",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimType": "none",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 925,
"height": 1189,
"rawWidth": 925,
"rawHeight": 1189,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-462.5,
-594.5,
0,
462.5,
-594.5,
0,
-462.5,
594.5,
0,
462.5,
594.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
1189,
925,
1189,
0,
0,
925,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-462.5,
-594.5,
0
],
"maxPos": [
462.5,
594.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "1f202d42-9020-49b2-9788-3d525ca13c1f@6c48a",
"atlasUuid": ""
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "1f202d42-9020-49b2-9788-3d525ca13c1f@6c48a"
}
}
@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "c62c4f1d-3a6f-44aa-835a-db3c09000322",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "c62c4f1d-3a6f-44aa-835a-db3c09000322@6c48a",
"displayName": "zjm_2",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "c62c4f1d-3a6f-44aa-835a-db3c09000322",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "c62c4f1d-3a6f-44aa-835a-db3c09000322@f9941",
"displayName": "zjm_2",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 527,
"height": 258,
"rawWidth": 527,
"rawHeight": 258,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-263.5,
-129,
0,
263.5,
-129,
0,
-263.5,
129,
0,
263.5,
129,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
258,
527,
258,
0,
0,
527,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-263.5,
-129,
0
],
"maxPos": [
263.5,
129,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "c62c4f1d-3a6f-44aa-835a-db3c09000322@6c48a",
"atlasUuid": ""
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "c62c4f1d-3a6f-44aa-835a-db3c09000322@6c48a"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 667 KiB

@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "36254e76-ede2-4482-9f81-887c9b69efe5",
"files": [
".jpg",
".json"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "36254e76-ede2-4482-9f81-887c9b69efe5@6c48a",
"displayName": "krischya_stage_bg",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "36254e76-ede2-4482-9f81-887c9b69efe5",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "36254e76-ede2-4482-9f81-887c9b69efe5@f9941",
"displayName": "krischya_stage_bg",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 996,
"height": 1280,
"rawWidth": 996,
"rawHeight": 1280,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-498,
-640,
0,
498,
-640,
0,
-498,
640,
0,
498,
640,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
1280,
996,
1280,
0,
0,
996,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-498,
-640,
0
],
"maxPos": [
498,
640,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "36254e76-ede2-4482-9f81-887c9b69efe5@6c48a",
"atlasUuid": ""
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": false,
"fixAlphaTransparencyArtifacts": false,
"redirect": "36254e76-ede2-4482-9f81-887c9b69efe5@6c48a"
}
}
@@ -0,0 +1,966 @@
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()
//首次进入如果直接是玩家回答,则立即获取ai回复
if (GameManager.curStage == E_TalkStage.myTalk) {
this.showAiAnswer()
}
//刷新状态显示
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()
this.showAiAnswer()
} else if (gStage == E_TalkStage.myTalk) {
this.turnToMyTalk()
} else if (gStage == E_TalkStage.waitNpcTalk) {
this.turnToWaitNpcTalk()
} else if (gStage == E_TalkStage.npcTalk) {
this.turnToNpcTalk(GameManager.CurNpcTalkData)
this.showAiAnswer()
} 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) {
// this._showAiAnswerUI(data)
// }
this._showAiAnswerUI(data)
}
})
}
private _showAiAnswerUI(ansList: any) {
for (let i=1; i<=3; i++) {
let AiAnsItem: Node = this._nodeTab["AiAnsItem"+i]
let labAns = AiAnsItem.getComponentInChildren(Label)
let ans = ansList["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)
}
}
@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "c2aae745-c0e3-41c6-83d2-cca0e1ea02c9",
"files": [],
"subMetas": {},
"userData": {}
}
@@ -0,0 +1,258 @@
/**
* 公共配置文件
*/
export const G_GlobalNode: string = '__GLobal_Node';
export namespace CommonConfig {
//本地保存
export enum StorageConfigUtil {
BaseData = 'li_' + 1000, // 登录相关
Channel = 2000, //渠道相关
}
export enum StorageConfig {
SETTING_SHAKEON = StorageConfigUtil.BaseData + 1,
SETTING_MUSIC = StorageConfigUtil.BaseData + 2,
SETTING_SOUND = StorageConfigUtil.BaseData + 3,
GAME_CITY = StorageConfigUtil.BaseData + 4, //所在省
GAME_RANK_CITY = StorageConfigUtil.BaseData + 5, //省排行数据 AI
GAME_RANK_USER = StorageConfigUtil.BaseData + 6, //玩家排行数据 AI
GAME_RANK_CDTIME = StorageConfigUtil.BaseData + 7, //上次排行数据刷新时间戳 AI
GAME_SCORE = StorageConfigUtil.BaseData + 8, //玩家积分
GAME_SKIN_ID = StorageConfigUtil.BaseData + 9, //当前选择的皮肤id
GAME_PASSLV = StorageConfigUtil.BaseData + 10, //已完成关卡
DAILYCHALLENGE_PASSLV = StorageConfigUtil.BaseData + 11, //已完成每日挑战关卡
TOOL_KAIKONG = StorageConfigUtil.BaseData + 12, //开孔工具使用过
TOOL_RENYIZHI = StorageConfigUtil.BaseData + 13, //任意指工具使用过
TOOL_RENYIGUAN = StorageConfigUtil.BaseData + 14, //任意罐工具使用过
DD_REGISTTIME = StorageConfigUtil.BaseData + 15, //注册时间字符串
DD_LEVELOPER = StorageConfigUtil.BaseData + 16, //进入关卡且首次进度>0时(或第一次操作)
GUIDE_MAIN = StorageConfigUtil.BaseData + 17, //主界面引导是否完成
GUIDE_TALK = StorageConfigUtil.BaseData + 18, //聊天界面引导是否完成
DOUYIN_SIDEBAR = StorageConfigUtil.Channel + 1, //抖音渠道侧边栏奖励是否领取
}
//UI层级
export enum UILayerGroup {
Layer_ground = 0,
Layer_ui1 = 1,
Layer_ui2 = 2,
Layer_dialog = 3,
Layer_tips = 4,
Layer_top = 5,
}
}
/**关卡配置信息 */
export interface I_LevelConfig {
/**是关卡场景图资源的名称,注意关卡选择界面选中关卡后展示的场景图资源也是这个 */
bgImage: string;
/**后续进入关卡后,关卡中需要播放的音乐资源名称 */
bgm: string;
/**在关卡中,聊天历史信息展示里,角色使用的头像,圆形 80*80 */
characterAvatar: string;
/**关卡中,提示信息界面里需要展示的角色性格文本 */
characterDisposition: string;
/**角色聊天切换的表情立绘,这个暂时先不处理,后面我们需要和你沟通下,资源改成英文名看你怎么匹配(Ai 返回的判断还是中文的) */
characterEmojiSet: string;
/**关卡中,提示信息界面,喜好话题部分需要展示的文本信息 */
characterFavoriteTopic: string;
/**角色默认立绘资源名称 */
characterFullLengthPortrait: string;
/**关卡提示信息界面里使用的角色半身胸像 */
characterHalfLengthPortrait: string;
/**关卡提示信息界面里,厌恶话题的展示文本信息 */
characterHateTopic: string;
/**角色名称,注意在关卡选择界面还有关卡中的聊天窗,关卡提示信息界面这几个地方都涉及展示 */
characterName: string;
/**角色职业设定信息,关卡提示信息界面里的职业部分展示 */
characterRole: string;
/**关卡选择界面里展示的关卡介绍文本信息 */
description: string;
/**关卡中对话得到高分后,额外向玩家展示的鼓励信息 */
encourageMessage: string;
/**结算图片 关卡 0 星,挑战失败的情况下在结算界面展示的 CG 资源名称 */
failureCG: string;
/**结算图片 关卡 1 星,挑战成功的情况下在结算界面展示的 CG 资源名称 */
oneStarCG: string;
/**结算图片 关卡 2 星,挑战成功的情况下在结算界面展示的 CG 资源名称 */
twoStarCG: string;
/**结算图片 关卡 3 星,那么需要展示的 CG 资源对应的名称 */
threeStarCG: string;
/**关卡中,对话得分特别低的情况下,额外给出的向玩家展示的鼓励信息 */
hateMessage: string;
/**关卡选择界面,菱形的头像资源名称 */
icon: string;
/**唯一的关卡 id 信息 */
id: string;
/**关卡是否已解锁,注意锁定状态仍然能够选择关卡,关卡选择界面中的背景和立绘需要切换做展示,但是玩家不能开启游戏哈 */
is_unlock: boolean;
/**npc名称 */
name: string;
/**关卡展示顺序 */
no: number;
/**关卡解锁需要通关的前置关卡 id 信息,对应id字段 */
preLevelId: string;
/**进入关卡后,角色发出给到玩家的开场白信息(历史聊天记录页面中也需要显示,一定是角色发出的第一句话) */
prologueMessage: string;
/**玩家在关卡中,点击随机填充按钮,需要随机选取一句,在输入框中填入,注意填入后不发送,玩家可修改,最终发送的信息还是以玩家点击发送按钮时,填入的信息为主 */
randomInputPool: string[];
/**关卡进行中的record_id,有值时要先获取一下之前的存档 */
record_id: string;
/**关卡历史最高分 */
score: number;
/**关卡历史最高星级 */
star: number;
/**关卡中,关卡提示信息界面里底部展示的提示信息文本,目前测试数据和关卡介绍信息一致,但后续会区分开来 */
tips: string;
/**Npc结算对话 3星时 */
threeStarSummary: string;
/**Npc结算对话 2星时 */
twoStarSummary: string;
/**Npc结算对话 1星时 */
oneStarSummary: string;
/**Npc结算对话 0星时 */
failureSummary: string;
/**Npc表情立绘 害羞 */
characterShyPortrait: string;
/**Npc表情立绘 厌恶 */
characterHatePortrait: string;
/**Npc表情立绘 开心 */
characterHappyPortrait: string;
/**关卡解锁类型 -1=未解锁 0=自动解锁 1=游戏通关解锁 2=手动解锁 */
unlock_type: number;
/**私家珍藏图片列表 */
photoAwards: I_ZhengCangConfig[];
}
/**私家珍藏配置数据 */
export interface I_ZhengCangConfig {
/**图片名 */
giftImgName: string;
/**故事文本列表 */
giftStory: string[];
/**简述 */
giftSummary: string;
/**唯一id */
id: number;
/**对应关卡id */
levelId: string;
}
/**关卡对话数据 */
export interface I_LevelStepData {
/**当前聊天次数 */
current_cnt: number;
/**结束评分 */
end_star: number;
/**关卡id */
id: string;
/**最大聊天次数 */
max_cnt: number;
/**当前状态 0:成功 1:进行中 2:失败 3:剩余聊天次数不足 */
status: number;
/**可用总聊天次数 */
total_cnt: number;
/**心动次数 */
heartbeat_cnt: number;
/**剩余可看广告次数 */
ad_num: number;
/**剩余可分享次数 */
share_num: number;
/**剩余可撤回次数 */
can_use_cancel_cnt: number;
/**剩余可暴击次数 */
can_use_strength_cnt: number;
/**暴击是否生效 */
is_strength_take_effect: boolean;
/**甜蜜暴击已用次数 */
first_strength?: number;
/**撤回已用次数 */
first_cancel?: number;
}
/**npc长连接中的回复 */
export interface I_NpcTalkBack {
/**ai表情 */
aiEmoji:string;
/**ai回复 */
aiResponse:string;
/**ai评分 */
aiScore:number;
/**ai基础评分 */
aiBaseScore:number;
/**ai额外加分 */
aiAdditionalScore:number;
/**是否完成 */
isFinished:boolean;
/**聊天次数 */
sourceCnt:number;
/**玩家发的文本 */
userInput: string;
/**评价 -1=未生成 0=心动 1=普通 2=厌恶 */
judgement: number;
}
/**对话历史记录数据 */
export interface I_TalkRecordInfo {
/**对话内容 */
talk: string;
/**是否是玩家自己 */
isMe: boolean;
/**评分 小于0时不显示 */
score: number;
/**基础分 */
scoreBase: number;
/**额外加分 */
scoreAdditional: number;
}
/**玩家信息数据 */
export interface I_UserInfo {
id: number;
score: number;
status: number;
/**头像url */
avatar: string;
/**昵称 */
nickname: string;
/**剩余进入关卡次数 */
ticket: number;
/**剩余可看广告次数 - 进入关卡 */
game_ad_num: number;
/**剩余可分享次数 - 进入关卡 */
game_share_num: number;
/**剩余可看广告次数 - 聊天 */
level_ad_num: number;
/**剩余可分享次数 - 聊天 */
level_share_num: number;
/**抖音侧边栏奖励是否已领取 0未领取 1已领取 */
is_receive: number;
/**友盟关卡记录 */
levels: any[];
/**私家珍藏红点标记 0不显示 1显示 */
private_collection_mark: number;
/**心动回忆红点标记 0不显示 1显示 */
heartbeat_memories_mark: number;
/**剩余可免费获取珍藏的次数 */
free_private_collection: number;
// [property: string]: any;
}
/**心动回忆数据 */
export interface I_HuiyiInfo {
/**关卡id */
lvId: string;
/**星数 */
star: number;
/**是否解锁 */
unlock: boolean;
}
@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "0faf77b5-cbf4-4028-841f-e4888c2983f3",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "0faf77b5-cbf4-4028-841f-e4888c2983f3@6c48a",
"displayName": "jieun_laugh",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "0faf77b5-cbf4-4028-841f-e4888c2983f3",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "0faf77b5-cbf4-4028-841f-e4888c2983f3@f9941",
"displayName": "jieun_laugh",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimType": "none",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 925,
"height": 1189,
"rawWidth": 925,
"rawHeight": 1189,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-462.5,
-594.5,
0,
462.5,
-594.5,
0,
-462.5,
594.5,
0,
462.5,
594.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
1189,
925,
1189,
0,
0,
925,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-462.5,
-594.5,
0
],
"maxPos": [
462.5,
594.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "0faf77b5-cbf4-4028-841f-e4888c2983f3@6c48a",
"atlasUuid": ""
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "0faf77b5-cbf4-4028-841f-e4888c2983f3@6c48a"
}
}