弹幕版本
---
--- Author: 【苏可欣】
--- AuthorID: 【384576】
--- CreateTime: 【2025-3-10 18:25:51】
--- 【FSync】
--- 【读书报告分享-新】
---
local class = require("middleclass")
local WBElement = require("mworld/worldBaseElement")
---@class fsync_cfe6e63a_0d1e_4c69_a573_32cab67b08f6 : WorldBaseElement
local FsyncElement = class("fsync_cfe6e63a-0d1e-4c69-a573-32cab67b08f6", WBElement)
local Fsync_Example_KEY = "_Example__Key_"
local TAG = "读书报告分享-新"
local readBookReport = "981791742280835/assets/Prefabs/ShareReadBookReport.prefab"
local PageId = "activity_center_share_readbook_report"
---@param worldElement CS.Tal.framesync.WorldElement
function FsyncElement:initialize(worldElement)
FsyncElement.super.initialize(self, worldElement)
---@type PageMonitorService
self.pageMonitorService = CourseEnv.BaseBusinessManager:GetPageMonitorService()
self:RegisterDownloadUaddress(readBookReport)
self.isInCountdown = true
self.hasCollectedReward = false -- 初始化为false,表示未领取奖励
-- 弹幕相关变量初始化
self.barrageRangeRectWidth = 0
self.barragePool = {} -- 对象池
self.activeBarrages = {} -- 激活的弹幕
self.barrageSpeed = 200 -- 弹幕移动速度
self.isBarrageRunning = false -- 弹幕系统运行状态
self.currentFriendIndex = 1 -- 当前使用的friend索引
--订阅KEY消息
self:InitEvent()
--订阅KEY消息
self:SubscribeMsgKey(Fsync_Example_KEY)
end
function FsyncElement:InitBarrage()
-- 获取弹幕区域宽度并初始化弹幕系统
local barrageRangeRect = self.barrageRange:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.barrageRangeRectWidth = barrageRangeRect.rect.width
local barrageRect = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.barrageRect = barrageRect
if self.shareInfo and self.shareInfo.friends and #self.shareInfo.friends > 0 and self.shareInfo.reportStatus == 2 and self.shareInfo.count > 0 then
-- 清空现有对象池
self.barragePool = {}
self.activeBarrages = {}
self.currentFriendIndex = 1
-- 开始弹幕滚动
self:StartBarrageSystem()
end
end
-- 创建空弹幕实例(不绑定数据)
function FsyncElement:CreateBarrageInstance()
local barrageInstance = GameObject.Instantiate(self.barrage.gameObject)
barrageInstance.name = "barrage" ..(#self.barragePool + #self.activeBarrages + 1)
barrageInstance.transform:SetParent(self.barrageRange)
local rectTransform = barrageInstance:GetComponent(typeof(CS.UnityEngine.RectTransform))
rectTransform.localScale = CS.UnityEngine.Vector3.one
-- 初始位置在右边界外
rectTransform.anchoredPosition = CS.UnityEngine.Vector2(self.barrageRangeRectWidth, 0)
barrageInstance.gameObject:SetActive(false)
local barrage = {
instance = barrageInstance,
rectTransform = rectTransform,
width = 0, -- 宽度会在设置数据时更新
isActive = false
}
return barrage
end
-- 设置弹幕数据
function FsyncElement:SetBarrageData(barrage, friend)
if not barrage or not friend then return end
local barrageRectTransform = barrage.instance:GetComponent(typeof(CS.UnityEngine.RectTransform))
local headImage = barrageRectTransform.transform:Find("head"):GetComponent(typeof(CS.UnityEngine.UI.Image))
local nameText = barrageRectTransform.transform:Find("name"):GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
-- 加载头像
if friend.avatar and friend.avatar ~= "" then
self.httpService:LoadNetWorkTexture(friend.avatar, function(texture)
if headImage then
headImage.sprite = texture
end
end)
end
-- 设置名称
if nameText then
nameText.text = friend.name
end
-- -- 设置位置和大小
local headRectTransform = headImage:GetComponent(typeof(CS.UnityEngine.RectTransform))
headRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4, 0)
local nameRectTransform = nameText:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 设置锚点为左居中
nameRectTransform.anchorMin = CS.UnityEngine.Vector2(0, 0.5)
nameRectTransform.anchorMax = CS.UnityEngine.Vector2(0, 0.5)
nameRectTransform.pivot = CS.UnityEngine.Vector2(0, 0.5) -- 设置轴心点也为左居中
nameRectTransform.sizeDelta = CS.UnityEngine.Vector2(nameText.preferredWidth, nameRectTransform.rect.height)
nameRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4+headRectTransform.rect.width+8, 0)
-- 更新宽度
barrageRectTransform.sizeDelta = CS.UnityEngine.Vector2(4+headRectTransform.rect.width+8+nameText.preferredWidth+8+self.barrageTextTransform.rect.width+16+70, self.barrageRect.rect.height)
barrage.width = 4+headRectTransform.rect.width+8+nameText.preferredWidth+8+self.barrageTextTransform.rect.width+16
return barrage
end
-- 从对象池获取弹幕并设置数据
function FsyncElement:GetBarrageFromPool()
if not self.shareInfo or not self.shareInfo.friends or #self.shareInfo.friends == 0 then
return nil
end
local barrage = nil
-- 检查对象池中是否有可复用的弹幕
if #self.barragePool > 0 then
-- 从对象池中取出一个弹幕
barrage = table.remove(self.barragePool, 1)
else
-- 对象池为空,创建新的弹幕实例
barrage = self:CreateBarrageInstance()
if not barrage then
g_LogError("创建弹幕实例失败")
return nil
end
end
-- 获取当前friend数据
local friend = self.shareInfo.friends[self.currentFriendIndex]
-- 设置弹幕数据
barrage = self:SetBarrageData(barrage, friend)
-- 更新friend索引,循环使用
self.currentFriendIndex = self.currentFriendIndex + 1
if self.currentFriendIndex > #self.shareInfo.friends then
self.currentFriendIndex = 1
end
-- 激活弹幕
barrage.isActive = true
barrage.instance.gameObject:SetActive(true)
barrage.rectTransform.anchoredPosition = CS.UnityEngine.Vector2(self.barrageRangeRectWidth, 0)
table.insert(self.activeBarrages, barrage)
return barrage
end
-- 回收弹幕到对象池
function FsyncElement:RecycleBarrage(barrage)
if not barrage then return end
-- 设置为非活动状态
barrage.isActive = false
barrage.rectTransform.anchoredPosition = CS.UnityEngine.Vector2(self.barrageRangeRectWidth, 0)
barrage.instance.gameObject:SetActive(false)
-- 放回对象池
table.insert(self.barragePool, barrage)
-- 从激活列表中移除
for i, active in ipairs(self.activeBarrages) do
if active == barrage then
table.remove(self.activeBarrages, i)
break
end
end
end
-- 开始弹幕系统
function FsyncElement:StartBarrageSystem()
if self.isBarrageRunning then return end
self.isBarrageRunning = true
-- 初始化第一个弹幕
local firstBarrage = self:GetBarrageFromPool()
if not firstBarrage then return end
-- 注册更新函数
self.barrageUpdateTimer = self.commonService:RegisterGlobalTimer(0.02, function()
self:UpdateBarrages()
end, true)
end
-- 更新弹幕位置
function FsyncElement:UpdateBarrages()
if not self.isBarrageRunning then return end
local deltaTime = 0.02 -- 固定帧率时间
local lastBarrage = self.activeBarrages[#self.activeBarrages]
-- 更新所有激活的弹幕位置
for i = #self.activeBarrages, 1, -1 do
local barrage = self.activeBarrages[i]
local currentPos = barrage.rectTransform.anchoredPosition
local newX = currentPos.x - self.barrageSpeed * deltaTime
-- 如果弹幕移出左边界,回收到对象池
if newX <= 0 then
self:RecycleBarrage(barrage)
else
barrage.rectTransform.anchoredPosition = CS.UnityEngine.Vector2(newX, currentPos.y)
end
end
-- 检查是否需要生成新弹幕
if lastBarrage then
local lastBarrageRightEdge = lastBarrage.rectTransform.anchoredPosition.x + lastBarrage.width
if lastBarrageRightEdge <= self.barrageRangeRectWidth - 60-70 then
local newBarrage = self:GetBarrageFromPool()
-- 新弹幕已经在GetBarrageFromPool中设置了位置和数据
end
elseif #self.activeBarrages == 0 then
-- 如果没有活动的弹幕,重新开始
local newBarrage = self:GetBarrageFromPool()
end
end
-- 停止弹幕系统
function FsyncElement:StopBarrageSystem()
self.isBarrageRunning = false
if self.barrageUpdateTimer then
self.commonService:UnregisterGlobalTimer(self.barrageUpdateTimer)
self.barrageUpdateTimer = nil
end
-- 回收所有活动的弹幕
for i = #self.activeBarrages, 1, -1 do
self:RecycleBarrage(self.activeBarrages[i])
end
-- 清空对象池中的所有弹幕
for _, barrage in ipairs(self.barragePool) do
if barrage and barrage.instance then
GameObject.Destroy(barrage.instance)
end
end
self.barragePool = {}
self.activeBarrages = {}
end
function FsyncElement:InitEvent()
--监听打开事件
self.observerService:Watch("ActivityCenter_Open_Canvas", function(key, value)
local data = value[0]
self.show = data.show
self.root = data.root
if self.show == "shareReadBook" then
self.isCurrIndex = true
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
end
end)
self:LoadingReadBookPage()
else
self.isCurrIndex = false
self:ClosePanel()
end
end)
self.observerService:Watch("ActivityCenter_Close_Canvas", function(key, value)
g_Log(TAG, "关闭读书报告分享页面7878787878787878787")
self:ClosePanel(true)
end)
end
function FsyncElement:LoadingReadBookPage()
-- 停止之前可能正在运行的弹幕系统
self:StopBarrageSystem()
-- if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == false then
if self.readBookPanel then
self.readBookPanel.gameObject:SetActive(true)
-- 如果面板已存在但被隐藏,重新显示时也要更新倒计时
if self.shareInfo then
self:InitCountDown()
-- 如果符合条件,重新初始化弹幕系统
if self.shareInfo.reportStatus == 2 and self.shareInfo.count > 0 and #self.shareInfo.friends > 0 then
self:InitBarrage()
end
end
return
end
-- if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
-- return
-- end
self.pageMonitorService:recordPageOpen(PageId, "读书报告分享")
self:LoadRemoteUaddress(readBookReport, function(success, prefab)
if self.readBookPanel then
self.readBookPanel.gameObject:SetActive(true)
return
end
if not self.isCurrIndex then
return
end
g_Log(TAG, "读书报告分享动态下载成功676767777676767676767676767676767")
if success and prefab then
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
-- g_Log(TAG, "读书报告分享动态下载成功")
local obj = GameObject.Instantiate(prefab)
self.prefab = prefab
self.objRoot = obj
self.readBookPanel = obj.transform:FindChildWithName("Root")
self.readBookPanel:SetParent(self.root)
self.dialogContentRect = self.readBookPanel:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.dialogContentRect.anchorMax = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchorMin = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchoredPosition = CS.UnityEngine.Vector2.zero
self:InitReadBookView()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
local param_one = "0"
if self.shareInfo.reportStatus == 2 then
param_one = "1"
end
self:reportData("activity_center_share_readbook_report_show", "读书报告分享显示", { param_one = param_one }, "0")
-- 确保倒计时初始化
self:InitCountDown()
end)
self.pageMonitorService:recordPageLoadComplete(PageId)
end
end, true)
end
function FsyncElement:InitReadBookView()
-- 根据图片中的节点层级结构初始化UI元素
self.root0 = self.readBookPanel
-- Bg背景
self.bg = self.root0:Find("Bg")
-- ContentPanel内容面板
self.contentPanel = self.root0:Find("ContentPanel")
self.title = self.contentPanel:Find("Title")
-- BarrageRange弹幕区域
self.barrageRange = self.contentPanel:Find("BarrageRange")
-- Barrage弹幕实例
self.barrage = self.barrageRange:Find("Barrage")
-- BarrageInfo信息
self.barrageHead = self.barrage:Find("head")
self.barrageName = self.barrage:Find("name")
self.barrageText = self.barrage:Find("text")
-- 获取必要的组件
self.barrageHeadImage = self.barrageHead:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.barrageNameText = self.barrageName:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.barrageTextTransform = self.barrageText:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.barrage.gameObject:SetActive(false)
-- RightBackImage右侧背景图
self.rightBackImage = self.contentPanel:Find("RightBackImage")
-- Jewels宝石区域
self.jewels = self.rightBackImage:Find("Jewels")
-- AwardNum奖励数量区域
self.awardNum = self.jewels:Find("AwardNum")
-- AwardInfo奖励信息
self.awardInfo = self.awardNum:Find("AwardInfo")
self.awardPlus = self.awardInfo:Find("Award+")
self.awardNum0 = self.awardInfo:Find("AwardNum0")
self.awardNum0Image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.awardNum1 = self.awardInfo:Find("AwardNum1")
self.awardNum1Image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.awardNum2 = self.awardInfo:Find("AwardNum2")
self.awardNum2Image = self.awardNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
-- HasShare已分享区域
self.hasShare = self.jewels:Find("HasShare")
-- HasShareInfo分享信息
self.hasShareInfo = self.hasShare:Find("HasShareInfo")
self.text0 = self.hasShareInfo:Find("text0")
-- NumInfo数字信息
self.hasShareNumInfo = self.hasShareInfo:Find("NumInfo")
self.hasShareNum0 = self.hasShareNumInfo:Find("num0")
self.hasShareNum0Image = self.hasShareNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.hasShareNum1 = self.hasShareNumInfo:Find("num1")
self.hasShareNum1Image = self.hasShareNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.hasShareNum2 = self.hasShareNumInfo:Find("num2")
self.hasShareNum2Image = self.hasShareNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.hasShareDiamond4 = self.hasShareInfo:Find("diamond4")
-- 右侧标题区域
self.rightStartShareTitle = self.contentPanel:Find("RightStartShareTitle")
-- 标题信息区域
self.rightStartShareInfo = self.rightStartShareTitle:Find("Info")
self.rightStartShareTitleTitle0 = self.rightStartShareTitle:Find("title0")
self.rightStartShareTitleTitle1 = self.rightStartShareInfo:Find("title1")
self.rightStartShareTitleGap2 = self.rightStartShareInfo:Find("Gap2")
self.rightStartShareTitleNum2 = self.rightStartShareInfo:Find("num2")
self.rightStartShareTitleNum2Image = self.rightStartShareTitleNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightStartShareTitleGap3 = self.rightStartShareInfo:Find("Gap3")
self.rightStartShareTitleDiamond1 = self.rightStartShareInfo:Find("diamond1")
self.rightStartShareTitleTitle2 = self.rightStartShareInfo:Find("title2")
self.rightStartShareTitleGap1 = self.rightStartShareInfo:Find("Gap1")
self.rightStartShareTitleNum3 = self.rightStartShareInfo:Find("num3")
self.rightStartShareTitleNum3Image = self.rightStartShareTitleNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightStartShareTitleNum4 = self.rightStartShareInfo:Find("num4")
self.rightStartShareTitleNum4Image = self.rightStartShareTitleNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightStartShareTitleNum5 = self.rightStartShareInfo:Find("num5")
self.rightStartShareTitleNum5Image = self.rightStartShareTitleNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightStartShareTitleGap0 = self.rightStartShareInfo:Find("Gap0")
self.rightStartShareTitleDiamond2 = self.rightStartShareInfo:Find("diamond2")
self.rightShareSuccessTitle = self.contentPanel:Find("RightShareSuccessTitle")
self.rightShareSuccessTitleNum2 = self.rightShareSuccessTitle:Find("num2")
self.rightShareSuccessTitleNum2Image = self.rightShareSuccessTitleNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightWaitCollectTitle = self.contentPanel:Find("RightWaitCollectTitle")
self.rightEndTitle = self.contentPanel:Find("RightEndTitle")
-- 底部区域
self.bottomStartShareTmp = self.rightBackImage:Find("BottomStartShareTmp")
self.bottomStartShareTmpText1 = self.bottomStartShareTmp:Find("text1")
self.bottomStartShareTmpText1Text=self.bottomStartShareTmpText1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomStartShareTmpText2 = self.bottomStartShareTmp:Find("text2")
self.bottomStartShareTmpText2Text=self.bottomStartShareTmpText2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomStartShareNum1 = self.bottomStartShareTmp:Find("num1")
self.bottomStartShareNum1Text = self.bottomStartShareNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomStartShareNum1Rect=self.bottomStartShareNum1:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomStartShareNum2 = self.bottomStartShareTmp:Find("num2")
self.bottomStartShareNum2Text = self.bottomStartShareNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomStartShareNum2Rect=self.bottomStartShareNum2:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomStartShareNum3 = self.bottomStartShareTmp:Find("num3")
self.bottomStartShareNum3Text = self.bottomStartShareNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomStartShareNum3Rect=self.bottomStartShareNum3:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomStartShareTmpRect = self.bottomStartShareTmp:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 底部分享成功区域
self.bottomShareSuccessTmp = self.rightBackImage:Find("BottomShareSuccessTmp")
self.bottomShareSuccessTmpText1 = self.bottomShareSuccessTmp:Find("text1")
self.bottomShareSuccessTmpText1Text=self.bottomShareSuccessTmpText1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomShareSuccessTmpText2 = self.bottomShareSuccessTmp:Find("text2")
self.bottomShareSuccessTmpText2Text=self.bottomShareSuccessTmpText2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomShareSuccessNum1 = self.bottomShareSuccessTmp:Find("num1")
self.bottomShareSuccessNum1Text = self.bottomShareSuccessNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomShareSuccessNum1Rect=self.bottomShareSuccessNum1Text:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomShareSuccessNum2 = self.bottomShareSuccessTmp:Find("num2")
self.bottomShareSuccessNum2Text = self.bottomShareSuccessNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomShareSuccessNum2Rect=self.bottomShareSuccessNum2Text:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomShareSuccessTmpRect = self.bottomShareSuccessTmp:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 底部等待收集区域
self.bottomWaitCollectTitle = self.rightBackImage:Find("BottomWaitCollectTitle")
self.bottomWaitCollectTitleText1 = self.bottomWaitCollectTitle:Find("text1")
self.bottomWaitCollectTitleText1Text=self.bottomWaitCollectTitleText1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitCollectTitleText2 = self.bottomWaitCollectTitle:Find("text2")
self.bottomWaitCollectTitleText2Text=self.bottomWaitCollectTitleText2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitNum1 = self.bottomWaitCollectTitle:Find("num1")
self.bottomWaitNum1Text = self.bottomWaitNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitNum1Rect=self.bottomWaitNum1:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomWaitNum2 = self.bottomWaitCollectTitle:Find("num2")
self.bottomWaitNum2Text = self.bottomWaitNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitNum2Rect=self.bottomWaitNum2:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomWaitCollectTitleRect = self.bottomWaitCollectTitle:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 底部结束区域
self.bottomEndTitle = self.rightBackImage:Find("BottomEndTitle")
self.bottomEndTitleRect = self.bottomEndTitle:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomEndText1 = self.bottomEndTitle:Find("text1")
self.bottomEndText1Text=self.bottomEndText1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomEndText2 = self.bottomEndTitle:Find("text2")
self.bottomEndText2Text=self.bottomEndText2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomEndNum1 = self.bottomEndTitle:Find("num1")
self.bottomEndNum1Text = self.bottomEndNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomEndNum1Rect=self.bottomEndNum1:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 其他区域
self.bottomNoView = self.rightBackImage:Find("BottomNoView")
self.bottomNoViewRect = self.bottomNoView:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.bottomEndNoView = self.rightBackImage:Find("BottomEndNoView")
self.bottomEndNoViewRect = self.bottomEndNoView:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 倒计时区域
self.countDown = self.rightBackImage:Find("CountDown")
self.daynum = self.countDown:Find("daynum")
self.hournum0 = self.countDown:Find("hournum0")
self.hournum1 = self.countDown:Find("hournum1")
self.minutenum0 = self.countDown:Find("minutenum0")
self.minutenum1 = self.countDown:Find("minutenum1")
self.daytext = self.countDown:Find("daytext")
self.hourtext = self.countDown:Find("hourtext")
self.minutetext = self.countDown:Find("minutetext")
self.text0 = self.countDown:Find("text0")
self.getEndLabel = self.rightBackImage:Find("GetEndLabel")
self.endLabel = self.rightBackImage:Find("EndLabel")
-- 中途分享按钮
self.halfwayShare = self.contentPanel:Find("HalfwayShare")
if self.halfwayShare then
self.halfwayShareBtn = self.halfwayShare:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.halfwayShareBtn, "onClick", function()
-- 防止短时间内重复点击
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
-- 埋点上报
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
-- 直接调用分享方法
self:ShareReadBook(function(success)
if success then
self:ShareReadBookReport()
end
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end)
end
-- 获取按钮区域
self.getBtn = self.rightBackImage:Find("GetBtn")
-- GetBtn信息区域
self.getBtnInfo = self.getBtn:Find("Info")
self.text1 = self.getBtnInfo:Find("text1")
-- NumInfo数字信息区域
self.getBtnNum1 = self.getBtnInfo:Find("num1")
self.getBtnNum1Image = self.getBtnNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.getBtnNum2 = self.getBtnInfo:Find("num2")
self.getBtnNum2Image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.getBtnNum3 = self.getBtnInfo:Find("num3")
self.getBtnNum3Image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.getBtnDiamond6 = self.getBtnInfo:Find("diamond6")
if self.getBtn then
self.getBtnButton = self.getBtn:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.getBtnButton, "onClick", function()
-- 添加标记,表示已经领取了奖励
self.hasCollectedReward = true
self:AwardPrizes(function(success)
if success then
self:SetViewByShareInfo()
end
end)
-- 禁用按钮,防止重复点击
self.getBtnButton.interactable = false
end)
end
self.btnText1 = self.getBtn:Find("text1")
self.btnNum1 = self.getBtn:Find("num1")
self.btnNum2 = self.getBtn:Find("num2")
self.btnNum3 = self.getBtn:Find("num3")
self.btnDiamond6 = self.getBtn:Find("diamond6")
-- 左侧内容和右侧副标题
self.leftContent = self.root:Find("LeftContent")
-- 图表区域
self.cutDiagram = self.root0:Find("CutDiagram")
for i = 0, 9 do
self["cutDiagram" .. i] = self.cutDiagram:Find(tostring(i))
self["cutDiagramRed" .. i] = self.cutDiagram:Find("red" .. i)
self["cutDiagramSmall" .. i] = self.cutDiagram:Find("small" .. i)
self["cutDiagramMedium" .. i] = self.cutDiagram:Find("medium" .. i)
end
-- 分享按钮
self.share = self.rightBackImage:Find("Share")
self.shareButton = self.share:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.shareButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----点击")
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
self:SetViewByShareInfo()
end
end)
return
end
self:ShareReadBook(function(success)
if success then
self:ShareReadBookReport()
self.commonService:StartCoroutine(function()
self.commonService:YieldSeconds(2)
self.shareInfo.reportStatus = 2
self:SetViewByShareInfo()
self.shareButton.interactable = false
end)
else
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
self.shareButton.interactable = true
end
end)
end)
self:SetViewByShareInfo()
end
-- 更新红色数字图片显示
function FsyncElement:UpdateNumberImage(targetImage, number)
if not targetImage or not self.redImages then
return
end
-- 处理大于9的数字(主要是天数可能大于9)
if number > 9 then
-- 如果是天数,我们只显示个位数,或者可以考虑其他处理方式
-- 这里简单处理为显示9
number = 9
end
-- 确保number在0-9范围内
number = math.max(0, math.min(9, number))
-- 获取目标Image组件
local image = targetImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if not image then
return
end
-- 获取对应数字的red图片
local redImage = self.redImages[number]
if not redImage then
return
end
-- 复制sprite到目标Image
image.sprite = redImage.sprite
end
-- 更新奖励数量显示
function FsyncElement:UpdateAwardNum()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.awardNum0 and self.awardNum0.gameObject then
if self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.awardNum0Image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
if self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.awardNum0Image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
if self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.awardNum1Image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
if self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.awardNum0Image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
if self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.awardNum1Image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
-- 使用cutDiagram中的数字图片
if self["cutDiagram" .. digits[3]] then
local sourceImage = self["cutDiagram" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.awardNum2Image.sprite = sourceImage.sprite
end
end
self.awardNum2.gameObject:SetActive(true)
end
end
-- 显示加号
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(true)
end
end
-- 添加更新最大奖励显示的函数
function FsyncElement:UpdateMaxRewardsDisplay()
if not self.shareInfo or not self.shareInfo.maxRewards then
return
end
-- 获取最大奖励值
local maxRewards = self.shareInfo.maxRewards
-- 将最大奖励值转换为字符串,然后分解为个位数
local rewardsStr = tostring(maxRewards)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #rewardsStr do
digits[i] = tonumber(string.sub(rewardsStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[1]] and self["cutDiagramMedium" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
local sourceImage2 = self["cutDiagramMedium" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.hasShareNum2Image.sprite = sourceImage.sprite
end
if sourceImage2 then
self.rightStartShareTitleNum5Image.sprite = sourceImage2.sprite
end
end
self.hasShareNum2.gameObject:SetActive(true)
self.rightStartShareTitleNum5.gameObject:SetActive(true)
self.rightStartShareTitleNum4.gameObject:SetActive(false)
self.hasShareNum1.gameObject:SetActive(false)
self.rightStartShareTitleNum3.gameObject:SetActive(false)
self.hasShareNum0.gameObject:SetActive(false)
elseif #digits == 2 then
-- 十位和个位
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[1]] and self["cutDiagramMedium" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
local sourceImage2 = self["cutDiagramMedium" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.hasShareNum1Image.sprite = sourceImage.sprite
end
if sourceImage2 then
self.rightStartShareTitleNum4Image.sprite = sourceImage2.sprite
end
end
self.hasShareNum1.gameObject:SetActive(true)
self.rightStartShareTitleNum4.gameObject:SetActive(true)
if self["cutDiagramSmall" .. digits[2]] and self["cutDiagramMedium" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
local sourceImage2 = self["cutDiagramMedium" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.hasShareNum2Image.sprite = sourceImage.sprite
end
if sourceImage2 then
self.rightStartShareTitleNum5Image.sprite = sourceImage2.sprite
end
end
self.hasShareNum2.gameObject:SetActive(true)
self.rightStartShareTitleNum5.gameObject:SetActive(true)
self.rightStartShareTitleNum3.gameObject:SetActive(false)
self.hasShareNum0.gameObject:SetActive(false)
elseif #digits == 3 then
-- 百位、十位和个位
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[3]] and self["cutDiagramMedium" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
local sourceImage2 = self["cutDiagramMedium" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.hasShareNum2Image.sprite = sourceImage.sprite
end
if sourceImage2 then
self.rightStartShareTitleNum5Image.sprite = sourceImage2.sprite
end
end
self.hasShareNum2.gameObject:SetActive(true)
self.rightStartShareTitleNum5.gameObject:SetActive(true)
if self["cutDiagramSmall" .. digits[2]] and self["cutDiagramMedium" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
local sourceImage2 = self["cutDiagramMedium" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.hasShareNum1Image.sprite = sourceImage.sprite
end
if sourceImage2 then
self.rightStartShareTitleNum4Image.sprite = sourceImage2.sprite
end
end
self.hasShareNum1.gameObject:SetActive(true)
self.rightStartShareTitleNum4.gameObject:SetActive(true)
if self["cutDiagramSmall" .. digits[1]] and self["cutDiagramMedium" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
local sourceImage2 = self["cutDiagramMedium" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.hasShareNum0Image.sprite = sourceImage.sprite
end
if sourceImage2 then
self.rightStartShareTitleNum3Image.sprite = sourceImage2.sprite
end
end
self.hasShareNum0.gameObject:SetActive(true)
self.rightStartShareTitleNum3.gameObject:SetActive(true)
end
end
-- 更新获取按钮上的数字显示
function FsyncElement:UpdateGetBtnNumbers()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.getBtnNum3Image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
self.getBtnNum2.gameObject:SetActive(false)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.getBtnNum3Image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.getBtnNum2Image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.getBtnNum3Image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.getBtnNum2Image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
-- 使用cutDiagramSmall中的数字图片
if self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
self.getBtnNum1Image.sprite = sourceImage.sprite
end
end
self.getBtnNum1.gameObject:SetActive(true)
end
end
-- 显示钻石图标
if self.getBtnDiamond6 and self.getBtnDiamond6.gameObject then
self.getBtnDiamond6.gameObject:SetActive(true)
end
end
function FsyncElement:SetViewByShareInfo()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 隐藏所有UI元素
self:HideAllUIElements()
-- 获取查看人数
local viewCount = self.shareInfo.count
if self.shareInfo.reportStatus == 2 then
-- 已分享状态
if self.isInCountdown then
-- 倒计时中
if viewCount > 0 then
self:StopBarrageSystem()
self:InitBarrage()
-- 有人查看
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
local sourceImage = self["cutDiagramSmall" .. self.shareInfo.reward_unit]:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightShareSuccessTitleNum2Image.sprite = sourceImage.sprite
self.rightShareSuccessTitle.gameObject:SetActive(true)
end
-- 设置标签为显示
if self.hasShare and self.hasShare.gameObject then
self:UpdateMaxRewardsDisplay()
self.hasShare.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
-- 更新奖励数量显示
self:UpdateAwardNum()
self.awardNum.gameObject:SetActive(true)
end
-- 设置底部分享成功模板为显示
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessNum1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.bottomShareSuccessNum2Text.text = self.shareInfo.count*5
else
self.bottomShareSuccessNum2Text.text = self.shareInfo.maxRewards
end
self.bottomShareSuccessTmp.gameObject:SetActive(true)
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self:InitCountDown()
self.countDown.gameObject:SetActive(true)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
else
-- 无人查看
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
local sourceImage = self["cutDiagramSmall" .. self.shareInfo.reward_unit]:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightShareSuccessTitleNum2Image.sprite = sourceImage.sprite
self.rightShareSuccessTitle.gameObject:SetActive(true)
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self:UpdateMaxRewardsDisplay()
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部无人查看视图为显示
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(true)
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self:InitCountDown()
self.countDown.gameObject:SetActive(true)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
end
else
-- 倒计时结束
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
end
end)
if viewCount > 0 then
-- 有人查看
self:StopBarrageSystem()
self:InitBarrage()
-- 如果已经领取了奖励,直接显示领取后的UI状态
if self.hasCollectedReward then
-- g_Log(TAG,"读课文分享新-----已领取奖励,显示领取后UI")
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self:UpdateAwardNum()
self.awardNum.gameObject:SetActive(true)
end
-- 设置底部结束标题为显示
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndNum1Text.text = self.shareInfo.count
-- self.bottomEndTitleRect.sizeDelta = CS.UnityEngine.Vector2(
-- self.bottomEndText1Text.preferredWidth+self.bottomEndText2Text.preferredWidth+self.bottomEndNum1Text.preferredWidth, self.bottomEndTitleRect.rect.height)
self.bottomEndTitle.gameObject:SetActive(true)
end
-- 设置获取结束标签为显示
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(true)
end
return
end
-- 设置等待领取UI状态
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
-- 更新奖励数量显示
self:UpdateAwardNum()
self.awardNum.gameObject:SetActive(true)
end
if self.hasShare and self.hasShare.gameObject then
self:UpdateMaxRewardsDisplay()
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部等待领取标题为显示
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitNum1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.bottomWaitNum2Text.text = self.shareInfo.count*5
else
self.bottomWaitNum2Text.text = self.shareInfo.maxRewards
end
-- self.bottomWaitCollectTitleRect.sizeDelta = CS.UnityEngine.Vector2(
-- self.bottomWaitCollectTitleText1Text.preferredWidth+self.bottomWaitCollectTitleText2Text.preferredWidth+self.bottomWaitNum1Text.preferredWidth+self.bottomWaitNum2Text.preferredWidth+22, self.bottomWaitCollectTitleRect.rect.height)
self.bottomWaitCollectTitle.gameObject:SetActive(true)
end
-- 设置领取按钮为显示
if self.getBtn and self.getBtn.gameObject then
-- 更新获取按钮上的数字显示
self:UpdateGetBtnNumbers()
self.getBtn.gameObject:SetActive(true)
end
else
-- 无人查看
-- 设置结束标签为显示
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(true)
end
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置底部结束无人查看视图为显示
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(true)
end
end
end
elseif self.shareInfo.reportStatus == 1 then
-- 未分享状态
-- 设置右侧开始分享标题为显示
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
local sourceImage = self["cutDiagramMedium" .. self.shareInfo.reward_unit]:GetComponent(typeof(CS.UnityEngine.UI.Image))
self.rightStartShareTitleNum2Image.sprite = sourceImage.sprite
-- 更新最大奖励显示
self:UpdateMaxRewardsDisplay()
self.rightStartShareTitle.gameObject:SetActive(true)
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
-- 更新最大奖励显示
self:UpdateMaxRewardsDisplay()
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部开始分享模板为显示
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareNum2Text.text = self.shareInfo.reward_unit
self.bottomStartShareNum3Text.text = self.shareInfo.maxRewards
-- self.bottomStartShareTmpRect.sizeDelta = CS.UnityEngine.Vector2(
-- self.bottomStartShareTmpText1Text.preferredWidth+self.bottomStartShareTmpText2Text.preferredWidth+self.bottomStartShareNum1Text.preferredWidth+self.bottomStartShareNum2Text.preferredWidth+self.bottomStartShareNum3Text.preferredWidth+22*2, self.bottomStartShareTmpRect.rect.height)
self.bottomStartShareTmp.gameObject:SetActive(true)
end
-- 设置分享按钮为显示
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(true)
end
elseif self.shareInfo.reportStatus == 0 then
-- 不可分享状态
end
end)
end
function FsyncElement:ClosePanel(needDestroy)
-- self:StopBarrageSystem()
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
self.readBookPanel.gameObject:SetActive(false)
end
if needDestroy and self.readBookPanel then
self:DestroyView()
end
end
-- 隐藏所有UI元素
function FsyncElement:HideAllUIElements()
-- 隐藏右侧标题区域
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(false)
end
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(false)
end
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(false)
end
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(false)
end
-- 隐藏底部区域
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(false)
end
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(false)
end
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(false)
end
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(false)
end
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(false)
end
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏奖励相关区域
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(false)
end
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(false)
end
if self.awardNum0 and self.awardNum0.gameObject then
self.awardNum0.gameObject:SetActive(false)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
-- 隐藏已分享区域
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(false)
end
-- 隐藏倒计时区域
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(false)
end
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(false)
end
-- 隐藏按钮区域
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(false)
end
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏最大奖励数字
if self.num3 and self.num3.gameObject then
self.num3.gameObject:SetActive(false)
end
if self.num4 and self.num4.gameObject then
self.num4.gameObject:SetActive(false)
end
if self.num5 and self.num5.gameObject then
self.num5.gameObject:SetActive(false)
end
end
function FsyncElement:DestroyView()
-- 移除按钮监听
if self.shareButton then
self.shareButton.onClick:RemoveAllListeners()
end
if self.halfwayShareBtn then
self.halfwayShareBtn.onClick:RemoveAllListeners()
end
if self.getBtnButton then
self.getBtnButton.onClick:RemoveAllListeners()
end
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
-- 清理弹幕相关
-- self:StopBarrageSystem()
-- 清理弹幕对象池
for _, barrage in ipairs(self.barragePool or {}) do
if barrage.instance then
CS.UnityEngine.GameObject.DestroyImmediate(barrage.instance)
end
end
self.barragePool = {}
self.activeBarrages = {}
-- 清理redImages引用
if self.redImages then
for i = 0, 9 do
self.redImages[i] = nil
end
self.redImages = nil
end
-- 销毁根物体
if self.objRoot then
CS.UnityEngine.GameObject.DestroyImmediate(self.objRoot)
self.objRoot = nil
end
-- 清理面板引用
self.readBookPanel = nil
self.dialogContentRect = nil
-- 释放预制体资源
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
self.pageMonitorService:recordPageClose(PageId)
-- 重置状态变量
self.isBarrageRunning = false
self.isInCountdown = true
self.hasCollectedReward = false
end
function FsyncElement:ShareReadBookReport()
local image = "https://static0.xesimg.com/next-studio-pub/app/1736943865007/zQsexNIiSJTCdgnwr9AZ.png"
self.content = {
title = self.shareInfo.title,
-- contentDesc = self.shareInfo.contentDesc,
url = self.shareInfo.url,
imageType = "network",
image = image,
thumbImageUrl = image,
previewImageUrl = image
}
local param = { type = "WeChatTimeline", contentType = "web", content = self.content }
APIBridge.RequestAsync('app.api.share.shareToNative', param, function(res)
if res then
g_Log(TAG, "分享微信朋友圈,回调--->" .. table.dump(res))
end
end)
end
-- 收到/恢复IRC消息
-- @param key 订阅的消息key
-- @param value 消息集合体
-- @param isResume 是否为恢复消息
function FsyncElement:ReceiveMessage(key, value, isResume)
-- TODO:
end
-- 发送KEY-VALUE 消息
-- @param key 自定义/协议key
-- @param body table 消息体
function FsyncElement:SendCustomMessage(key, body)
self:SendMessage(key,body)
end
-- 自己avatar对象创建完成
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarCreated(avatar)
end
-- 自己avatar对象人物模型加载完成ba
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarPrefabLoaded(avatar)
end
-- avatar对象创建完成,包含他人和自己
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:AvatarCreated(avatar)
end
------------------------蓝图组件相应方法---------------------------------------------
--是否是异步恢复如果是需要改成true
function FsyncElement:LogicMapIsAsyncRecorver()
return false
end
--开始恢复方法(断线重连的时候用)
function FsyncElement:LogicMapStartRecover()
FsyncElement.super:LogicMapStartRecover()
--TODO
end
--结束恢复方法 (断线重连的时候用)
function FsyncElement:LogicMapEndRecover()
FsyncElement.super:LogicMapEndRecover(self)
--TODO
end
--所有的组件恢复完成
function FsyncElement:LogicMapAllComponentRecoverComplete()
end
--收到Trigger事件
function FsyncElement:OnReceiveTriggerEvent(interfaceId)
end
--收到GetData事件
function FsyncElement:OnReceiveGetDataEvent(interfaceId)
return nil
end
------------------------蓝图组件相应方法End---------------------------------------------
---接口请求
function FsyncElement:ShareReadBook(callback)
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/do"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/do"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
-- callback(true)
callback(data.result)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
function FsyncElement:AwardPrizes(callback)
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/reward"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/reward"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
self.rewardNum=data.count
callback(true)
end
end
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
---获取分享信息
function FsyncElement:GetShareInfo(callback)
if self.shareInfo and self.requestTime and os.time() - self.requestTime < 30 then
callback(true, self.shareInfo)
return
end
self.requestTime = os.time()
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
local shareInfo = {
reward_unit = data.reward_unit,
userId = data.userId,
reportStatus = data.report_status, --2:已分享 1:未分享
bookId = data.book_id,
levelNo = data.level_no,
title = data.title,
-- contentDesc = data.contentDesc,
url = data.url,
maxRewards = data.max_rewards, -- 最大奖励
endTime = data.end_time, -- 剩余时间
count = data.count, -- 查看人数
friends = data.friends -- 好友列表
}
-- 确保maxRewards是数字
if shareInfo.maxRewards and type(shareInfo.maxRewards) == "string" then
shareInfo.maxRewards = tonumber(shareInfo.maxRewards) or 0
elseif not shareInfo.maxRewards then
shareInfo.maxRewards = 0
end
g_Log(TAG, string.format("获取分享信息成功: maxRewards=%d, count=%d", shareInfo.maxRewards, shareInfo.count or 0))
self.shareInfo = shareInfo
-- 初始化cachedFriends如果它是nil
callback(true, shareInfo)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
function FsyncElement:HttpRequest(url, params, success, fail)
if App.IsStudioClient then
self.httpService:PostForm(url, params, {}, success, fail)
else
APIBridge.RequestAsync('api.httpclient.request', {
["url"] = url,
["headers"] = {
["Content-Type"] = "application/json"
},
["data"] = params
}, function(res)
if res ~= nil and res.responseString ~= nil and res.isSuccessed then
local resp = res.responseString
success(resp)
else
fail(res)
end
end)
end
end
---埋点方法
function FsyncElement:reportData(event, label, value, action)
if not App.IsStudioClient then
NextStudioComponentStatisticsAPI.ComponentStatisticsWithParam(event, "84169", "Special-Interaction", label,
action, value)
end
end
function FsyncElement:InitCountDown()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 解析接口返回的endTime字段,格式如:"2天23小时59分"
local days, hours, minutes = 0, 0, 0
if self.shareInfo.endTime and self.shareInfo.endTime ~= "" then
local endTimeStr = self.shareInfo.endTime
-- 解析天数
local daysStr = string.match(endTimeStr, "(%d+)天")
if daysStr then
days = tonumber(daysStr) or 0
end
-- 解析小时
local hoursStr = string.match(endTimeStr, "(%d+)小时") or string.match(endTimeStr, "(%d+)时")
if hoursStr then
hours = tonumber(hoursStr) or 0
end
-- 解析分钟
local minutesStr = string.match(endTimeStr, "(%d+)分")
if minutesStr then
minutes = tonumber(minutesStr) or 0
end
g_Log(TAG, string.format("解析倒计时: %d天%02d时%02d分", days, hours, minutes))
else
g_Log(TAG, "倒计时字符串为空或不存在")
end
-- 预加载red0~red9图片
self.redImages = {}
for i = 0, 9 do
-- 假设red0~red9图片已经在CutDiagram节点下
local redImage = self.cutDiagram:Find("red" .. i)
if redImage then
self.redImages[i] = redImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
end
end
-- 更新倒计时显示,显示的分钟数比实际剩余时间多一分钟
local function updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 调整显示的分钟数,如果秒数大于0,则分钟数+1
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
-- 处理进位
if displayMinutes == 60 then
displayMinutes = 0
remainHours = remainHours + 1
if remainHours == 24 then
remainHours = 0
remainDays = remainDays + 1
end
end
end
-- 更新天数显示
self:UpdateNumberImage(self.daynum, remainDays)
-- 更新小时显示(两位数)
local hourTens = math.floor(remainHours / 10)
local hourOnes = remainHours % 10
self:UpdateNumberImage(self.hournum0, hourTens)
self:UpdateNumberImage(self.hournum1, hourOnes)
-- 更新分钟显示(两位数)
local minuteTens = math.floor(displayMinutes / 10)
local minuteOnes = displayMinutes % 10
self:UpdateNumberImage(self.minutenum0, minuteTens)
self:UpdateNumberImage(self.minutenum1, minuteOnes)
-- 记录日志
g_Log(TAG, string.format("倒计时更新: 实际剩余时间=%d天%02d小时%02d分%02d秒, 显示=%d天%02d小时%02d分",
remainDays, remainHours, remainMinutes, remainSeconds, remainDays, remainHours, displayMinutes))
end
-- 倒计时结束时更新UI状态
local function onCountdownFinished()
g_Log(TAG, "倒计时结束,更新UI状态")
-- 隐藏倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 更新UI显示
self:SetViewByShareInfo()
end
-- 计算总秒数
local totalSeconds = days * 86400 + hours * 3600 + minutes * 60
local endTime = os.time() + totalSeconds
-- 立即检查是否应该显示倒计时
if totalSeconds > 0 and self.shareInfo.reportStatus == 2 and self.isInCountdown then
g_Log(TAG,"读课文分享新-----倒计时开始显示倒计时UI1111111111111"..totalSeconds)
-- 显示倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
g_Log(TAG,"读课文分享新-----显示倒计时UI0000000000000")
end
-- 注册全局定时器,每秒更新一次倒计时(改为每秒更新以获得更流畅的体验)
self.countDownTimerId = self.commonService:RegisterGlobalTimer(1, function()
local now = os.time()
local diff = endTime - now
if diff <= 0 then
-- 倒计时结束
g_Log(TAG,"读课文分享新-----倒计时结束注销定时器3333333333333")
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.isInCountdown=false
onCountdownFinished()
return
end
local remainDays = math.floor(diff / 86400)
local remainHours = math.floor((diff % 86400) / 3600)
local remainMinutes = math.floor((diff % 3600) / 60)
local remainSeconds = diff % 60
-- 只有当秒数为0或者分钟或更高单位变化时才更新UI显示
-- 或者当秒数变化导致显示的分钟数变化时也更新UI
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
end
if remainSeconds == 0 or (not self.lastRemainingMinutes) or self.lastRemainingMinutes ~= remainMinutes or
(not self.lastRemainingHours) or self.lastRemainingHours ~= remainHours or
(not self.lastRemainingDays) or self.lastRemainingDays ~= remainDays or
(not self.lastDisplayMinutes) or self.lastDisplayMinutes ~= displayMinutes then
-- 更新UI显示
updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 记录当前时间,用于下次比较
self.lastRemainingMinutes = remainMinutes
self.lastRemainingHours = remainHours
self.lastRemainingDays = remainDays
self.lastDisplayMinutes = displayMinutes
end
end, true)
else
-- 不需要显示倒计时,确保倒计时UI被隐藏
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 如果不是倒计时状态,可能是已经结束或者未开始
if self.shareInfo.reportStatus == 2 then
-- 已分享状态但不在倒计时中,说明倒计时已结束
onCountdownFinished()
end
end
end)
end
-- 脚本释放
function FsyncElement:Exit()
-- self:StopBarrageSystem()
-- 清理对象池
for _, barrage in ipairs(self.barragePool) do
if barrage.instance then
GameObject.Destroy(barrage.instance)
end
end
self.barragePool = {}
self.activeBarrages = {}
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
FsyncElement.super.Exit(self)
end
return FsyncElement
无弹幕版本
---
--- Author: 【苏可欣】
--- AuthorID: 【384576】
--- CreateTime: 【2025-3-10 18:25:51】
--- 【FSync】
--- 【读书报告分享-新】
---
local class = require("middleclass")
local WBElement = require("mworld/worldBaseElement")
---@class fsync_4601a2d6_27d3_412e_82e0_9f0642dd34bd_1 : WorldBaseElement
local FsyncElement = class("fsync_4601a2d6-27d3-412e-82e0-9f0642dd34bd_1", WBElement)
local Fsync_Example_KEY = "_Example__Key_"
local TAG = "读书报告分享-新"
local readBookReport = "980701741877903/assets/Prefabs/ShareReadBookReport.prefab"
local PageId = "activity_center_share_readbook_report"
---@param worldElement CS.Tal.framesync.WorldElement
function FsyncElement:initialize(worldElement)
FsyncElement.super.initialize(self, worldElement)
---@type PageMonitorService
self.pageMonitorService = CourseEnv.BaseBusinessManager:GetPageMonitorService()
self:RegisterDownloadUaddress(readBookReport)
self.isInCountdown = true
self.hasCollectedReward = false -- 初始化为false,表示未领取奖励
self:InitEvent()
--订阅KEY消息
self:SubscribeMsgKey(Fsync_Example_KEY)
end
function FsyncElement:InitEvent()
--监听打开事件
self.observerService:Watch("ActivityCenter_Open_Canvas", function(key, value)
local data = value[0]
self.show = data.show
self.root = data.root
if self.show == "shareReadBook" then
self.isCurrIndex = true
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
end
end)
self:LoadingReadBookPage()
else
self.isCurrIndex = false
self:ClosePanel()
end
end)
self.observerService:Watch("ActivityCenter_Close_Canvas", function(key, value)
self:ClosePanel(true)
end)
end
function FsyncElement:LoadingReadBookPage()
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == false then
self.readBookPanel.gameObject:SetActive(true)
-- 如果面板已存在但被隐藏,重新显示时也要更新倒计时
if self.shareInfo then
self:InitCountDown()
end
return
end
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
return
end
self.pageMonitorService:recordPageOpen(PageId, "读书报告分享")
self:LoadRemoteUaddress(readBookReport, function(success, prefab)
if not self.isCurrIndex then
return
end
if success and prefab then
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
-- g_Log(TAG, "读书报告分享动态下载成功")
local obj = GameObject.Instantiate(prefab)
self.prefab = prefab
self.objRoot = obj
self.readBookPanel = obj.transform:FindChildWithName("Root")
self.readBookPanel:SetParent(self.root)
self.dialogContentRect = self.readBookPanel:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.dialogContentRect.anchorMax = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchorMin = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchoredPosition = CS.UnityEngine.Vector2.zero
self:InitReadBookView()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
local param_one = "0"
if self.shareInfo.reportStatus == 2 then
param_one = "1"
end
self:reportData("activity_center_share_readbook_report_show", "读书报告分享显示", { param_one = param_one }, "0")
-- 确保倒计时初始化
self:InitCountDown()
end)
self.pageMonitorService:recordPageLoadComplete(PageId)
end
end, true)
end
function FsyncElement:InitReadBookView()
-- 根据图片中的节点层级结构初始化UI元素
self.root = self.readBookPanel
-- Bg背景
self.bg = self.root:Find("Bg")
-- ContentPanel内容面板
self.contentPanel = self.root:Find("ContentPanel")
self.title = self.contentPanel:Find("Title")
-- Barrage弹幕区域
self.barrageRange = self.contentPanel:Find("BarrageRange")
self.barrage = self.barrageRange:Find("Barrage")
self.head = self.barrage:Find("head")
self.name = self.barrage:Find("name")
self.text = self.barrage:Find("text")
self.barrage.gameObject:SetActive(false)
-- RightBackImage右侧背景图
self.rightBackImage = self.contentPanel:Find("RightBackImage")
-- Jewels宝石区域
self.jewels = self.rightBackImage:Find("Jewels")
self.awardNum = self.jewels:Find("AwardNum")
self.awardPlus = self.awardNum:Find("Award+")
self.awardNum0 = self.awardNum:Find("AwardNum0")
self.awardNum1 = self.awardNum:Find("AwardNum1")
self.awardNum2 = self.awardNum:Find("AwardNum2")
-- HasShare已分享区域
self.hasShare = self.jewels:Find("HasShare")
self.text0 = self.hasShare:Find("text0")
self.diamond4 = self.hasShare:Find("diamond4")
self.num = self.hasShare:Find("num")
-- 右侧标题区域
self.rightStartShareTitle = self.contentPanel:Find("RightStartShareTitle")
self.rightStartShareNum3 = self.rightStartShareTitle:Find("num3")
self.rightStartShareNum3Text = self.rightStartShareNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightStartShareNum4 = self.rightStartShareTitle:Find("num4")
self.rightStartShareNum4Text = self.rightStartShareNum4:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightStartShareNum5 = self.rightStartShareTitle:Find("num5")
self.rightStartShareNum5Text = self.rightStartShareNum5:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightShareSuccessTitle = self.contentPanel:Find("RightShareSuccessTitle")
self.rightWaitCollectTitle = self.contentPanel:Find("RightWaitCollectTitle")
self.rightEndTitle = self.contentPanel:Find("RightEndTitle")
-- 底部区域
self.bottomStartShareTmp = self.rightBackImage:Find("BottomStartShareTmp")
-- 底部分享成功区域
self.bottomShareSuccessTmp = self.rightBackImage:Find("BottomShareSuccessTmp")
self.num1 = self.bottomShareSuccessTmp:Find("num1")
self.num1Text = self.num1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.num2 = self.bottomShareSuccessTmp:Find("num2")
self.num2Text = self.num2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.text1 = self.bottomShareSuccessTmp:Find("text1")
self.text2 = self.bottomShareSuccessTmp:Find("text2")
self.diamond5 = self.bottomShareSuccessTmp:Find("diamond5")
self.diamond5.gameObject:SetActive(true)
-- 底部等待收集区域
self.bottomWaitCollectTitle = self.rightBackImage:Find("BottomWaitCollectTitle")
self.bottomWaitNum1 = self.bottomWaitCollectTitle:Find("num1")
self.bottomWaitNum1Text = self.bottomWaitNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitNum2 = self.bottomWaitCollectTitle:Find("num2")
self.bottomWaitNum2Text = self.bottomWaitNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitText1 = self.bottomWaitCollectTitle:Find("text1")
self.bottomWaitText2 = self.bottomWaitCollectTitle:Find("text2")
self.bottomWaitDiamond6 = self.bottomWaitCollectTitle:Find("diamond6")
-- 底部结束区域
self.bottomEndTitle = self.rightBackImage:Find("BottomEndTitle")
self.bottomEndNum1 = self.bottomEndTitle:Find("num1")
self.bottomEndNum1Text = self.bottomEndNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomEndText1 = self.bottomEndTitle:Find("text1")
self.bottomEndText2 = self.bottomEndTitle:Find("text2")
-- 其他区域
self.bottomNoView = self.rightBackImage:Find("BottomNoView")
self.bottomEndNoView = self.rightBackImage:Find("BottomEndNoView")
-- 倒计时区域
self.countDown = self.rightBackImage:Find("CountDown")
self.daynum = self.countDown:Find("daynum")
self.hournum0 = self.countDown:Find("hournum0")
self.hournum1 = self.countDown:Find("hournum1")
self.minutenum0 = self.countDown:Find("minutenum0")
self.minutenum1 = self.countDown:Find("minutenum1")
self.daytext = self.countDown:Find("daytext")
self.hourtext = self.countDown:Find("hourtext")
self.minutetext = self.countDown:Find("minutetext")
self.text0 = self.countDown:Find("text0")
self.getEndLabel = self.rightBackImage:Find("GetEndLabel")
self.endLabel = self.rightBackImage:Find("EndLabel")
-- 中途分享按钮
self.halfwayShare = self.contentPanel:Find("HalfwayShare")
if self.halfwayShare then
self.halfwayShareBtn = self.halfwayShare:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.halfwayShareBtn, "onClick", function()
-- 防止短时间内重复点击
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
-- 埋点上报
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
-- 检查是否有分享信息
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
-- 调用分享方法
self:ShareReadBook(function(success)
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end
end)
return
end
-- 直接调用分享方法
self:ShareReadBook(function(success)
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end)
end
-- 获取按钮区域
self.getBtn = self.rightBackImage:Find("GetBtn")
self.getBtnNum1 = self.getBtn:Find("num1")
-- self.getBtnNum1Text = self.getBtnNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnNum2 = self.getBtn:Find("num2")
-- self.getBtnNum2Text = self.getBtnNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnNum3 = self.getBtn:Find("num3")
-- self.getBtnNum3Text = self.getBtnNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnDiamond6 = self.getBtn:Find("diamond6")
if self.getBtn then
self.getBtnButton = self.getBtn:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.getBtnButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----获取按钮点击999999999999")
-- 添加标记,表示已经领取了奖励
self.hasCollectedReward = true
self:SetViewByShareInfo()
-- 禁用按钮,防止重复点击
self.getBtnButton.interactable = false
end)
end
self.btnText1 = self.getBtn:Find("text1")
self.btnNum1 = self.getBtn:Find("num1")
self.btnNum2 = self.getBtn:Find("num2")
self.btnNum3 = self.getBtn:Find("num3")
self.btnDiamond6 = self.getBtn:Find("diamond6")
-- 左侧内容和右侧副标题
self.leftContent = self.root:Find("LeftContent")
-- self.rightSubTitle = self.root:Find("RightSubTitle")
-- 图表区域
self.cutDiagram = self.root:Find("CutDiagram")
for i = 0, 9 do
self["cutDiagram" .. i] = self.cutDiagram:Find(tostring(i))
self["cutDiagramRed" .. i] = self.cutDiagram:Find("red" .. i)
self["cutDiagramSmall" .. i] = self.cutDiagram:Find("small" .. i)
end
-- 分享按钮
self.share = self.rightBackImage:Find("Share")
self.shareButton = self.share:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.shareButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----点击")
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
self:SetViewByShareInfo()
end
end)
return
end
self:ShareReadBook(function(success)
if success then
self:ShareReadBookReport()
self.commonService:StartCoroutine(function()
self.commonService:YieldSeconds(2)
self.shareInfo.reportStatus = 2
self:SetViewByShareInfo()
self.shareButton.interactable = false
end)
else
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
self.shareButton.interactable = true
end
end)
end)
self:SetViewByShareInfo()
end
-- 更新红色数字图片显示
function FsyncElement:UpdateNumberImage(targetImage, number)
if not targetImage or not self.redImages then
return
end
-- 处理大于9的数字(主要是天数可能大于9)
if number > 9 then
-- 如果是天数,我们只显示个位数,或者可以考虑其他处理方式
-- 这里简单处理为显示9
number = 9
end
-- 确保number在0-9范围内
number = math.max(0, math.min(9, number))
-- 获取目标Image组件
local image = targetImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if not image then
return
end
-- 获取对应数字的red图片
local redImage = self.redImages[number]
if not redImage then
return
end
-- 复制sprite到目标Image
image.sprite = redImage.sprite
end
-- 更新奖励数量显示
function FsyncElement:UpdateAwardNum()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- g_Log(TAG, string.format("更新奖励数量: 查看人数=%d, 奖励值=%d", self.shareInfo.count, awardValue))
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[3]] then
local sourceImage = self["cutDiagram" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum2.gameObject:SetActive(true)
end
end
-- 显示加号
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(true)
end
end
-- 添加更新最大奖励显示的函数
function FsyncElement:UpdateMaxRewardsDisplay()
if not self.shareInfo or not self.shareInfo.maxRewards then
return
end
-- 获取最大奖励值
local maxRewards = self.shareInfo.maxRewards
-- g_Log(TAG, string.format("更新最大奖励显示: maxRewards=%d", maxRewards))
-- 将最大奖励值转换为字符串,然后分解为个位数
local rewardsStr = tostring(maxRewards)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #rewardsStr do
digits[i] = tonumber(string.sub(rewardsStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
self.rightStartShareNum4.gameObject:SetActive(false)
end
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum4.gameObject:SetActive(true)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum3.gameObject:SetActive(true)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum4.gameObject:SetActive(true)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
end
end
function FsyncElement:SetViewByShareInfo()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 隐藏所有UI元素
self:HideAllUIElements()
-- 获取查看人数
local viewCount = self.shareInfo.count
if self.shareInfo.reportStatus == 2 then
-- 已分享状态
if self.isInCountdown then
-- 倒计时中
if viewCount > 0 then
-- 有人查看
-- g_Log(TAG,"读课文分享新-----有人查看")
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(true)
-- g_Log(TAG,"读课文分享新-----有人查看rightShareSuccessTitle")
end
-- 设置标签为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(true)
-- 更新奖励数量显示
self:UpdateAwardNum()
end
-- 设置底部分享成功模板为显示
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(true)
self.num1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.num2Text.text = self.shareInfo.count*5
else
self.num2Text.text = self.shareInfo.maxRewards
end
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
self:InitCountDown()
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
else
-- 无人查看
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(true)
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部无人查看视图为显示
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(true)
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
self:InitCountDown()
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
end
else
-- 倒计时结束
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
end
end)
if viewCount > 0 then
-- 有人查看
-- 如果已经领取了奖励,直接显示领取后的UI状态
if self.hasCollectedReward then
-- g_Log(TAG,"读课文分享新-----已领取奖励,显示领取后UI")
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(true)
self:UpdateAwardNum()
end
-- 设置底部结束标题为显示
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(true)
self.bottomEndNum1Text.text = self.shareInfo.count
end
-- 设置获取结束标签为显示
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(true)
end
return
end
-- 设置等待领取UI状态
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
-- g_Log(TAG,"读课文分享新-----有人查看awardNum")
self.awardNum.gameObject:SetActive(true)
-- 更新奖励数量显示
self:UpdateAwardNum()
end
if self.hasShare and self.hasShare.gameObject then
-- g_Log(TAG,"读课文分享新-----有人查看hasShare")
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部等待领取标题为显示
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(true)
self.bottomWaitNum1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.bottomWaitNum2Text.text = self.shareInfo.count*5
else
self.bottomWaitNum2Text.text = self.shareInfo.maxRewards
end
end
-- 设置领取按钮为显示
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(true)
-- 更新获取按钮上的数字显示
self:UpdateGetBtnNumbers()
end
else
-- 无人查看
-- 设置结束标签为显示
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(true)
end
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置底部结束无人查看视图为显示
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(true)
end
end
end
elseif self.shareInfo.reportStatus == 1 then
-- 未分享状态
-- 设置右侧开始分享标题为显示
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(true)
-- 更新最大奖励显示
self:UpdateMaxRewardsDisplay()
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部开始分享模板为显示
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(true)
end
-- 设置分享按钮为显示
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(true)
end
elseif self.shareInfo.reportStatus == 0 then
-- 不可分享状态
end
end)
end
function FsyncElement:ClosePanel(needDestroy)
-- 停止弹幕
self.isBarrageRunning = false
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
self.readBookPanel.gameObject:SetActive(false)
end
if needDestroy and self.readBookPanel then
self:DestroyView()
end
end
-- 隐藏所有UI元素
function FsyncElement:HideAllUIElements()
-- 隐藏右侧标题区域
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(false)
end
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(false)
end
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(false)
end
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(false)
end
-- 隐藏底部区域
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(false)
end
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(false)
end
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(false)
end
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(false)
end
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(false)
end
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏奖励相关区域
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(false)
end
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(false)
end
if self.awardNum0 and self.awardNum0.gameObject then
self.awardNum0.gameObject:SetActive(false)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
-- 隐藏已分享区域
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(false)
end
-- 隐藏倒计时区域
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(false)
end
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(false)
end
-- 隐藏按钮区域
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(false)
end
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏最大奖励数字
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
self.rightStartShareNum4.gameObject:SetActive(false)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
self.rightStartShareNum5.gameObject:SetActive(false)
end
-- g_Log(TAG, "已隐藏所有UI元素")
end
function FsyncElement:DestroyView()
if self.shareButton then
self.shareButton.onClick:RemoveAllListeners()
end
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
-- 清理redImages引用
if self.redImages then
for i = 0, 9 do
self.redImages[i] = nil
end
self.redImages = nil
end
if self.objRoot then
CS.UnityEngine.GameObject.DestroyImmediate(self.objRoot)
self.objRoot = nil
end
self.readBookPanel = nil
self.dialogContentRect = nil
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
self.pageMonitorService:recordPageClose(PageId)
end
function FsyncElement:ShareReadBookReport()
local image = "https://static0.xesimg.com/next-studio-pub/app/1736943865007/zQsexNIiSJTCdgnwr9AZ.png"
self.content = {
title = self.shareInfo.title,
-- contentDesc = self.shareInfo.contentDesc,
url = self.shareInfo.url,
imageType = "network",
image = image,
thumbImageUrl = image,
previewImageUrl = image
}
local param = { type = "WeChatTimeline", contentType = "web", content = self.content }
APIBridge.RequestAsync('app.api.share.shareToNative', param, function(res)
if res then
g_Log(TAG, "分享微信朋友圈,回调--->" .. table.dump(res))
end
end)
end
-- 收到/恢复IRC消息
-- @param key 订阅的消息key
-- @param value 消息集合体
-- @param isResume 是否为恢复消息
function FsyncElement:ReceiveMessage(key, value, isResume)
-- TODO:
end
-- 发送KEY-VALUE 消息
-- @param key 自定义/协议key
-- @param body table 消息体
function FsyncElement:SendCustomMessage(key, body)
self:SendMessage(key,body)
end
-- 自己avatar对象创建完成
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarCreated(avatar)
end
-- 自己avatar对象人物模型加载完成ba
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarPrefabLoaded(avatar)
end
-- avatar对象创建完成,包含他人和自己
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:AvatarCreated(avatar)
end
------------------------蓝图组件相应方法---------------------------------------------
--是否是异步恢复如果是需要改成true
function FsyncElement:LogicMapIsAsyncRecorver()
return false
end
--开始恢复方法(断线重连的时候用)
function FsyncElement:LogicMapStartRecover()
FsyncElement.super:LogicMapStartRecover()
--TODO
end
--结束恢复方法 (断线重连的时候用)
function FsyncElement:LogicMapEndRecover()
FsyncElement.super:LogicMapEndRecover(self)
--TODO
end
--所有的组件恢复完成
function FsyncElement:LogicMapAllComponentRecoverComplete()
end
--收到Trigger事件
function FsyncElement:OnReceiveTriggerEvent(interfaceId)
end
--收到GetData事件
function FsyncElement:OnReceiveGetDataEvent(interfaceId)
return nil
end
------------------------蓝图组件相应方法End---------------------------------------------
---接口请求
function FsyncElement:ShareReadBook(callback)
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
callback(true)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
---获取分享信息
function FsyncElement:GetShareInfo(callback)
if self.shareInfo and self.requestTime and os.time() - self.requestTime < 30 then
callback(true, self.shareInfo)
return
end
self.requestTime = os.time()
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
local shareInfo = {
userId = data.userId,
reportStatus = data.report_status, --2:已分享 1:未分享
bookId = data.book_id,
levelNo = data.level_no,
title = data.title,
-- contentDesc = data.contentDesc,
url = data.url,
maxRewards = data.max_rewards, -- 最大奖励
endTime = data.end_time, -- 剩余时间
count = data.count, -- 查看人数
friends = data.friends -- 好友列表
}
-- 确保maxRewards是数字
if shareInfo.maxRewards and type(shareInfo.maxRewards) == "string" then
shareInfo.maxRewards = tonumber(shareInfo.maxRewards) or 0
elseif not shareInfo.maxRewards then
shareInfo.maxRewards = 0
end
g_Log(TAG, string.format("获取分享信息成功: maxRewards=%d, count=%d", shareInfo.maxRewards, shareInfo.count or 0))
self.shareInfo = shareInfo
-- 初始化cachedFriends如果它是nil
callback(true, shareInfo)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
function FsyncElement:HttpRequest(url, params, success, fail)
if App.IsStudioClient then
self.httpService:PostForm(url, params, {}, success, fail)
else
APIBridge.RequestAsync('api.httpclient.request', {
["url"] = url,
["headers"] = {
["Content-Type"] = "application/json"
},
["data"] = params
}, function(res)
if res ~= nil and res.responseString ~= nil and res.isSuccessed then
local resp = res.responseString
success(resp)
else
fail(res)
end
end)
end
end
---埋点方法
function FsyncElement:reportData(event, label, value, action)
if not App.IsStudioClient then
NextStudioComponentStatisticsAPI.ComponentStatisticsWithParam(event, "84169", "Special-Interaction", label,
action, value)
end
end
-- 更新获取按钮上的数字显示
function FsyncElement:UpdateGetBtnNumbers()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- g_Log(TAG, string.format("更新获取按钮数字: 奖励值=%d", awardValue))
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
self.getBtnNum2.gameObject:SetActive(false)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.getBtnNum1 and self.getBtnNum1.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum1.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
end
-- 显示钻石图标
if self.getBtnDiamond6 and self.getBtnDiamond6.gameObject then
self.getBtnDiamond6.gameObject:SetActive(true)
end
end
function FsyncElement:InitCountDown()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 解析接口返回的endTime字段,格式如:"2天23小时59分"
local days, hours, minutes = 0, 0, 0
if self.shareInfo.endTime and self.shareInfo.endTime ~= "" then
local endTimeStr = self.shareInfo.endTime
-- 解析天数
local daysStr = string.match(endTimeStr, "(%d+)天")
if daysStr then
days = tonumber(daysStr) or 0
end
-- 解析小时
local hoursStr = string.match(endTimeStr, "(%d+)小时") or string.match(endTimeStr, "(%d+)时")
if hoursStr then
hours = tonumber(hoursStr) or 0
end
-- 解析分钟
local minutesStr = string.match(endTimeStr, "(%d+)分")
if minutesStr then
minutes = tonumber(minutesStr) or 0
end
g_Log(TAG, string.format("解析倒计时: %d天%02d时%02d分", days, hours, minutes))
else
g_Log(TAG, "倒计时字符串为空或不存在")
end
-- 预加载red0~red9图片
self.redImages = {}
for i = 0, 9 do
-- 假设red0~red9图片已经在CutDiagram节点下
local redImage = self.cutDiagram:Find("red" .. i)
if redImage then
self.redImages[i] = redImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
end
end
-- 更新倒计时显示,显示的分钟数比实际剩余时间多一分钟
local function updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 调整显示的分钟数,如果秒数大于0,则分钟数+1
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
-- 处理进位
if displayMinutes == 60 then
displayMinutes = 0
remainHours = remainHours + 1
if remainHours == 24 then
remainHours = 0
remainDays = remainDays + 1
end
end
end
-- 更新天数显示
self:UpdateNumberImage(self.daynum, remainDays)
-- 更新小时显示(两位数)
local hourTens = math.floor(remainHours / 10)
local hourOnes = remainHours % 10
self:UpdateNumberImage(self.hournum0, hourTens)
self:UpdateNumberImage(self.hournum1, hourOnes)
-- 更新分钟显示(两位数)
local minuteTens = math.floor(displayMinutes / 10)
local minuteOnes = displayMinutes % 10
self:UpdateNumberImage(self.minutenum0, minuteTens)
self:UpdateNumberImage(self.minutenum1, minuteOnes)
-- 记录日志
g_Log(TAG, string.format("倒计时更新: 实际剩余时间=%d天%02d小时%02d分%02d秒, 显示=%d天%02d小时%02d分",
remainDays, remainHours, remainMinutes, remainSeconds, remainDays, remainHours, displayMinutes))
end
-- 倒计时结束时更新UI状态
local function onCountdownFinished()
g_Log(TAG, "倒计时结束,更新UI状态")
-- 隐藏倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 更新UI显示
self:SetViewByShareInfo()
end
-- 计算总秒数
local totalSeconds = days * 86400 + hours * 3600 + minutes * 60
local endTime = os.time() + totalSeconds
-- 立即检查是否应该显示倒计时
if totalSeconds > 0 and self.shareInfo.reportStatus == 2 and self.isInCountdown then
g_Log(TAG,"读课文分享新-----倒计时开始显示倒计时UI1111111111111"..totalSeconds)
-- 显示倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
g_Log(TAG,"读课文分享新-----显示倒计时UI0000000000000")
end
-- 注册全局定时器,每秒更新一次倒计时(改为每秒更新以获得更流畅的体验)
self.countDownTimerId = self.commonService:RegisterGlobalTimer(1, function()
local now = os.time()
local diff = endTime - now
if diff <= 0 then
-- 倒计时结束
g_Log(TAG,"读课文分享新-----倒计时结束注销定时器3333333333333")
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.isInCountdown=false
onCountdownFinished()
return
end
local remainDays = math.floor(diff / 86400)
local remainHours = math.floor((diff % 86400) / 3600)
local remainMinutes = math.floor((diff % 3600) / 60)
local remainSeconds = diff % 60
-- 只有当秒数为0或者分钟或更高单位变化时才更新UI显示
-- 或者当秒数变化导致显示的分钟数变化时也更新UI
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
end
if remainSeconds == 0 or (not self.lastRemainingMinutes) or self.lastRemainingMinutes ~= remainMinutes or
(not self.lastRemainingHours) or self.lastRemainingHours ~= remainHours or
(not self.lastRemainingDays) or self.lastRemainingDays ~= remainDays or
(not self.lastDisplayMinutes) or self.lastDisplayMinutes ~= displayMinutes then
-- 更新UI显示
updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 记录当前时间,用于下次比较
self.lastRemainingMinutes = remainMinutes
self.lastRemainingHours = remainHours
self.lastRemainingDays = remainDays
self.lastDisplayMinutes = displayMinutes
end
end, true)
else
-- 不需要显示倒计时,确保倒计时UI被隐藏
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 如果不是倒计时状态,可能是已经结束或者未开始
if self.shareInfo.reportStatus == 2 then
-- 已分享状态但不在倒计时中,说明倒计时已结束
onCountdownFinished()
end
end
end)
end
-- 脚本释放
function FsyncElement:Exit()
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
FsyncElement.super.Exit(self)
end
return FsyncElement
对象池版本
---
--- Author: 【苏可欣】
--- AuthorID: 【384576】
--- CreateTime: 【2025-3-10 18:25:51】
--- 【FSync】
--- 【读书报告分享-新】
---
local class = require("middleclass")
local WBElement = require("mworld/worldBaseElement")
---@class fsync_4601a2d6_27d3_412e_82e0_9f0642dd34bd_1 : WorldBaseElement
local FsyncElement = class("fsync_4601a2d6-27d3-412e-82e0-9f0642dd34bd_1", WBElement)
local Fsync_Example_KEY = "_Example__Key_"
local TAG = "读书报告分享-新"
local readBookReport = "980161741793848/assets/Prefabs/ShareReadBookReport.prefab"
local PageId = "activity_center_share_readbook_report"
---@param worldElement CS.Tal.framesync.WorldElement
function FsyncElement:initialize(worldElement)
FsyncElement.super.initialize(self, worldElement)
---@type PageMonitorService
self.pageMonitorService = CourseEnv.BaseBusinessManager:GetPageMonitorService()
self:RegisterDownloadUaddress(readBookReport)
self.isInCountdown = true
self.hasCollectedReward = false -- 初始化为false,表示未领取奖励
-- 弹幕相关变量初始化
self.barrageItems = {} -- 存储所有弹幕项
self.barrageSpeed = 100 -- 弹幕移动速度
self.barrageSpacing = 150 -- 弹幕之间的间距
self.barrageItemWidth = 0 -- 弹幕项宽度,将在创建时计算
self.barrageRangeWidth = 0 -- 弹幕范围宽度,将在初始化时计算
self.isBarrageRunning = false -- 弹幕是否正在运行
self.cachedFriends = {} -- 缓存的好友列表
self.barragePool = {} -- 弹幕对象池
self.activeBarrages = {} -- 活跃弹幕列表
-- 保存原始位置的变量
self.originalNamePosition = nil -- 原始名字位置
self.originalContentPosition = nil -- 原始内容位置
self.originalHeadPosition = nil -- 原始头像位置
self.standardNameWidth = 0 -- 标准名字宽度
self.barrageRangeWidth = 0 -- 弹幕区域宽度
self:InitEvent()
--订阅KEY消息
self:SubscribeMsgKey(Fsync_Example_KEY)
end
function FsyncElement:InitEvent()
--监听打开事件
self.observerService:Watch("ActivityCenter_Open_Canvas", function(key, value)
local data = value[0]
self.show = data.show
self.root = data.root
if self.show == "shareReadBook" then
self.isCurrIndex = true
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
end
end)
self:LoadingReadBookPage()
else
self.isCurrIndex = false
self:ClosePanel()
end
end)
self.observerService:Watch("ActivityCenter_Close_Canvas", function(key, value)
self:ClosePanel(true)
end)
end
function FsyncElement:LoadingReadBookPage()
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == false then
self.readBookPanel.gameObject:SetActive(true)
-- 如果面板已存在但被隐藏,重新显示时也要更新倒计时
if self.shareInfo then
self:InitCountDown()
end
return
end
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
return
end
self.pageMonitorService:recordPageOpen(PageId, "读书报告分享")
self:LoadRemoteUaddress(readBookReport, function(success, prefab)
if not self.isCurrIndex then
return
end
if success and prefab then
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
-- g_Log(TAG, "读书报告分享动态下载成功")
local obj = GameObject.Instantiate(prefab)
self.prefab = prefab
self.objRoot = obj
self.readBookPanel = obj.transform:FindChildWithName("Root")
self.readBookPanel:SetParent(self.root)
self.dialogContentRect = self.readBookPanel:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.dialogContentRect.anchorMax = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchorMin = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchoredPosition = CS.UnityEngine.Vector2.zero
self:InitReadBookView()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
local param_one = "0"
if self.shareInfo.reportStatus == 2 then
param_one = "1"
end
self:reportData("activity_center_share_readbook_report_show", "读书报告分享显示", { param_one = param_one }, "0")
-- 确保倒计时初始化
self:InitCountDown()
end)
self.pageMonitorService:recordPageLoadComplete(PageId)
end
end, true)
end
function FsyncElement:InitReadBookView()
-- 根据图片中的节点层级结构初始化UI元素
self.root = self.readBookPanel
-- Bg背景
self.bg = self.root:Find("Bg")
-- ContentPanel内容面板
self.contentPanel = self.root:Find("ContentPanel")
self.title = self.contentPanel:Find("Title")
-- Barrage弹幕区域
self.barrageRange = self.contentPanel:Find("BarrageRange")
self.barrage = self.barrageRange:Find("Barrage")
self.head = self.barrage:Find("head")
self.name = self.barrage:Find("name")
self.text = self.barrage:Find("text")
self.barrage.gameObject:SetActive(false)
-- 获取弹幕区域宽度
local barrageRangeRect = self.barrageRange:GetComponent(typeof(CS.UnityEngine.RectTransform))
if barrageRangeRect then
self.barrageRangeWidth = barrageRangeRect.rect.width
end
-- 在UI初始化完成后,如果已经有shareInfo数据,尝试更新弹幕
if self.shareInfo and self.shareInfo.friends and #self.shareInfo.friends > 0 then
self.commonService:StartCoroutine(function()
self.commonService:YieldEndFrame() -- 等待一帧确保UI完全初始化
local hasChanged = self:UpdateBarrageContent(self.shareInfo.friends)
if hasChanged and self.shareInfo.reportStatus == 2 then
self:StartBarrageScroll()
end
end)
end
-- RightBackImage右侧背景图
self.rightBackImage = self.contentPanel:Find("RightBackImage")
-- Jewels宝石区域
self.jewels = self.rightBackImage:Find("Jewels")
self.awardNum = self.jewels:Find("AwardNum")
self.awardPlus = self.awardNum:Find("Award+")
self.awardNum0 = self.awardNum:Find("AwardNum0")
self.awardNum1 = self.awardNum:Find("AwardNum1")
self.awardNum2 = self.awardNum:Find("AwardNum2")
-- HasShare已分享区域
self.hasShare = self.jewels:Find("HasShare")
self.text0 = self.hasShare:Find("text0")
self.diamond4 = self.hasShare:Find("diamond4")
self.num = self.hasShare:Find("num")
-- 右侧标题区域
self.rightStartShareTitle = self.contentPanel:Find("RightStartShareTitle")
self.rightStartShareNum3 = self.rightStartShareTitle:Find("num3")
self.rightStartShareNum3Text = self.rightStartShareNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightStartShareNum4 = self.rightStartShareTitle:Find("num4")
self.rightStartShareNum4Text = self.rightStartShareNum4:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightStartShareNum5 = self.rightStartShareTitle:Find("num5")
self.rightStartShareNum5Text = self.rightStartShareNum5:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightShareSuccessTitle = self.contentPanel:Find("RightShareSuccessTitle")
self.rightWaitCollectTitle = self.contentPanel:Find("RightWaitCollectTitle")
self.rightEndTitle = self.contentPanel:Find("RightEndTitle")
-- 底部区域
self.bottomStartShareTmp = self.contentPanel:Find("BottomStartShareTmp")
-- 底部分享成功区域
self.bottomShareSuccessTmp = self.contentPanel:Find("BottomShareSuccessTmp")
self.num1 = self.bottomShareSuccessTmp:Find("num1")
self.num1Text = self.num1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.num2 = self.bottomShareSuccessTmp:Find("num2")
self.num2Text = self.num2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.text1 = self.bottomShareSuccessTmp:Find("text1")
self.text2 = self.bottomShareSuccessTmp:Find("text2")
self.diamond5 = self.bottomShareSuccessTmp:Find("diamond5")
-- 底部等待收集区域
self.bottomWaitCollectTitle = self.contentPanel:Find("BottomWaitCollectTitle")
self.bottomWaitNum1 = self.bottomWaitCollectTitle:Find("num1")
self.bottomWaitNum1Text = self.bottomWaitNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitNum2 = self.bottomWaitCollectTitle:Find("num2")
self.bottomWaitNum2Text = self.bottomWaitNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitText1 = self.bottomWaitCollectTitle:Find("text1")
self.bottomWaitText2 = self.bottomWaitCollectTitle:Find("text2")
self.bottomWaitDiamond6 = self.bottomWaitCollectTitle:Find("diamond6")
-- 底部结束区域
self.bottomEndTitle = self.contentPanel:Find("BottomEndTitle")
self.bottomEndNum1 = self.bottomEndTitle:Find("num1")
self.bottomEndNum1Text = self.bottomEndNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomEndText1 = self.bottomEndTitle:Find("text1")
self.bottomEndText2 = self.bottomEndTitle:Find("text2")
-- 其他区域
self.bottomNoView = self.contentPanel:Find("BottomNoView")
self.bottomEndNoView = self.contentPanel:Find("BottomEndNoView")
-- 倒计时区域
self.countDown = self.contentPanel:Find("CountDown")
self.daynum = self.countDown:Find("daynum")
self.hournum0 = self.countDown:Find("hournum0")
self.hournum1 = self.countDown:Find("hournum1")
self.minutenum0 = self.countDown:Find("minutenum0")
self.minutenum1 = self.countDown:Find("minutenum1")
self.daytext = self.countDown:Find("daytext")
self.hourtext = self.countDown:Find("hourtext")
self.minutetext = self.countDown:Find("minutetext")
self.text0 = self.countDown:Find("text0")
self.getEndLabel = self.contentPanel:Find("GetEndLabel")
self.endLabel = self.contentPanel:Find("EndLabel")
-- 中途分享按钮
self.halfwayShare = self.contentPanel:Find("HalfwayShare")
if self.halfwayShare then
self.halfwayShareBtn = self.halfwayShare:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.halfwayShareBtn, "onClick", function()
-- 防止短时间内重复点击
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
-- 埋点上报
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
-- 检查是否有分享信息
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
-- 调用分享方法
self:ShareReadBook(function(success)
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end
end)
return
end
-- 直接调用分享方法
self:ShareReadBook(function(success)
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end)
end
-- 获取按钮区域
self.getBtn = self.contentPanel:Find("GetBtn")
self.getBtnNum1 = self.getBtn:Find("num1")
-- self.getBtnNum1Text = self.getBtnNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnNum2 = self.getBtn:Find("num2")
-- self.getBtnNum2Text = self.getBtnNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnNum3 = self.getBtn:Find("num3")
-- self.getBtnNum3Text = self.getBtnNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnDiamond6 = self.getBtn:Find("diamond6")
if self.getBtn then
self.getBtnButton = self.getBtn:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.getBtnButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----获取按钮点击999999999999")
-- 添加标记,表示已经领取了奖励
self.hasCollectedReward = true
self:SetViewByShareInfo()
-- 禁用按钮,防止重复点击
self.getBtnButton.interactable = false
end)
end
self.btnText1 = self.getBtn:Find("text1")
self.btnNum1 = self.getBtn:Find("num1")
self.btnNum2 = self.getBtn:Find("num2")
self.btnNum3 = self.getBtn:Find("num3")
self.btnDiamond6 = self.getBtn:Find("diamond6")
-- 左侧内容和右侧副标题
self.leftContent = self.root:Find("LeftContent")
-- self.rightSubTitle = self.root:Find("RightSubTitle")
-- 图表区域
self.cutDiagram = self.root:Find("CutDiagram")
for i = 0, 9 do
self["cutDiagram" .. i] = self.cutDiagram:Find(tostring(i))
self["cutDiagramRed" .. i] = self.cutDiagram:Find("red" .. i)
self["cutDiagramSmall" .. i] = self.cutDiagram:Find("small" .. i)
end
-- 分享按钮
self.share = self.contentPanel:Find("Share")
self.shareButton = self.share:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.shareButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----点击")
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
self:SetViewByShareInfo()
end
end)
return
end
self:ShareReadBook(function(success)
if success then
self:ShareReadBookReport()
self.commonService:StartCoroutine(function()
self.commonService:YieldSeconds(2)
self.shareInfo.reportStatus = 2
self:SetViewByShareInfo()
self.shareButton.interactable = false
end)
else
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
self.shareButton.interactable = true
end
end)
end)
self:SetViewByShareInfo()
-- 保存原始位置信息
self:SaveOriginalPositions()
end
-- 保存原始位置信息并计算标准宽度
function FsyncElement:SaveOriginalPositions()
if not self.barrage then
return
end
-- 获取名字、内容和头像的Transform
local nameTransform = self.barrage:Find("name")
local contentTransform = self.barrage:Find("text")
local headTransform = self.barrage:Find("head")
-- 保存原始位置
if nameTransform then
local nameRectTransform = nameTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if nameRectTransform then
self.originalNamePosition = nameRectTransform.anchoredPosition
g_Log(TAG, string.format("保存原始名字位置: x=%f, y=%f", self.originalNamePosition.x, self.originalNamePosition.y))
end
end
if contentTransform then
local contentRectTransform = contentTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if contentRectTransform then
self.originalContentPosition = contentRectTransform.anchoredPosition
g_Log(TAG, string.format("保存原始内容位置: x=%f, y=%f", self.originalContentPosition.x, self.originalContentPosition.y))
end
end
if headTransform then
local headRectTransform = headTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRectTransform then
self.originalHeadPosition = headRectTransform.anchoredPosition
g_Log(TAG, string.format("保存原始头像位置: x=%f, y=%f", self.originalHeadPosition.x, self.originalHeadPosition.y))
end
end
-- 计算标准名字宽度(使用6个字符的宽度作为标准)
local standardText = "标准名字宽度" -- 6个字符
local nameTextComponent = nameTransform:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent then
-- 保存当前文本
local originalText = nameTextComponent.text
-- 设置为标准文本
nameTextComponent.text = standardText
-- 等待一帧确保文本更新
self.commonService:StartCoroutine(function()
self.commonService:YieldEndFrame()
-- 获取标准宽度
self.standardNameWidth = nameTextComponent.preferredWidth
g_Log(TAG, string.format("计算标准名字宽度: %f", self.standardNameWidth))
-- 恢复原始文本
nameTextComponent.text = originalText
end)
end
end
-- 更新红色数字图片显示
function FsyncElement:UpdateNumberImage(targetImage, number)
if not targetImage or not self.redImages then
return
end
-- 处理大于9的数字(主要是天数可能大于9)
if number > 9 then
-- 如果是天数,我们只显示个位数,或者可以考虑其他处理方式
-- 这里简单处理为显示9
number = 9
end
-- 确保number在0-9范围内
number = math.max(0, math.min(9, number))
-- 获取目标Image组件
local image = targetImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if not image then
return
end
-- 获取对应数字的red图片
local redImage = self.redImages[number]
if not redImage then
return
end
-- 复制sprite到目标Image
image.sprite = redImage.sprite
end
-- 更新奖励数量显示
function FsyncElement:UpdateAwardNum()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- g_Log(TAG, string.format("更新奖励数量: 查看人数=%d, 奖励值=%d", self.shareInfo.count, awardValue))
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[3]] then
local sourceImage = self["cutDiagram" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum2.gameObject:SetActive(true)
end
end
-- 显示加号
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(true)
end
end
-- 添加更新最大奖励显示的函数
function FsyncElement:UpdateMaxRewardsDisplay()
if not self.shareInfo or not self.shareInfo.maxRewards then
return
end
-- 获取最大奖励值
local maxRewards = self.shareInfo.maxRewards
-- g_Log(TAG, string.format("更新最大奖励显示: maxRewards=%d", maxRewards))
-- 将最大奖励值转换为字符串,然后分解为个位数
local rewardsStr = tostring(maxRewards)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #rewardsStr do
digits[i] = tonumber(string.sub(rewardsStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
self.rightStartShareNum4.gameObject:SetActive(false)
end
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum4.gameObject:SetActive(true)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum3.gameObject:SetActive(true)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum4.gameObject:SetActive(true)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
end
end
function FsyncElement:SetViewByShareInfo()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 隐藏所有UI元素
self:HideAllUIElements()
-- 获取查看人数
local viewCount = self.shareInfo.count
if self.shareInfo.reportStatus == 2 then
-- -- 初始化并启动弹幕
-- if self.shareInfo.friends and #self.shareInfo.friends > 0 then
-- self:InitBarrage()
-- end
-- 已分享状态
if self.isInCountdown then
-- 倒计时中
if viewCount > 0 then
-- 有人查看
-- g_Log(TAG,"读课文分享新-----有人查看")
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(true)
-- g_Log(TAG,"读课文分享新-----有人查看rightShareSuccessTitle")
end
-- 设置标签为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(true)
-- 更新奖励数量显示
self:UpdateAwardNum()
end
-- 设置底部分享成功模板为显示
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(true)
self.num1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.num2Text.text = self.shareInfo.count*5
else
self.num2Text.text = self.shareInfo.maxRewards
end
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
self:InitCountDown()
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
else
-- 无人查看
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(true)
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部无人查看视图为显示
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(true)
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
self:InitCountDown()
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
end
else
-- 倒计时结束
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
end
end)
if viewCount > 0 then
-- 有人查看
-- 如果已经领取了奖励,直接显示领取后的UI状态
if self.hasCollectedReward then
-- g_Log(TAG,"读课文分享新-----已领取奖励,显示领取后UI")
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(true)
self:UpdateAwardNum()
end
-- 设置底部结束标题为显示
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(true)
self.bottomEndNum1Text.text = self.shareInfo.count
end
-- 设置获取结束标签为显示
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(true)
end
return
end
-- g_Log(TAG,"读课文分享新-----倒计时结束viewCount=0000000000000")
-- 设置等待领取UI状态
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
g_Log(TAG,"读课文分享新-----有人查看awardNum")
self.awardNum.gameObject:SetActive(true)
-- 更新奖励数量显示
self:UpdateAwardNum()
end
if self.hasShare and self.hasShare.gameObject then
g_Log(TAG,"读课文分享新-----有人查看hasShare")
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部等待领取标题为显示
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(true)
self.bottomWaitNum1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.bottomWaitNum2Text.text = self.shareInfo.count*5
else
self.bottomWaitNum2Text.text = self.shareInfo.maxRewards
end
end
-- 设置领取按钮为显示
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(true)
-- 更新获取按钮上的数字显示
self:UpdateGetBtnNumbers()
end
else
-- 无人查看
-- 设置结束标签为显示
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(true)
end
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置底部结束无人查看视图为显示
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(true)
end
end
end
elseif self.shareInfo.reportStatus == 1 then
-- 未分享状态
-- 设置右侧开始分享标题为显示
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(true)
-- 更新最大奖励显示
self:UpdateMaxRewardsDisplay()
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部开始分享模板为显示
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(true)
end
-- 设置分享按钮为显示
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(true)
end
elseif self.shareInfo.reportStatus == 0 then
-- 不可分享状态
end
end)
end
function FsyncElement:ClosePanel(needDestroy)
-- 停止弹幕
self.isBarrageRunning = false
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
self.readBookPanel.gameObject:SetActive(false)
end
if needDestroy and self.readBookPanel then
self:DestroyView()
end
end
-- 隐藏所有UI元素
function FsyncElement:HideAllUIElements()
-- 隐藏右侧标题区域
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(false)
end
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(false)
end
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(false)
end
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(false)
end
-- 隐藏底部区域
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(false)
end
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(false)
end
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(false)
end
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(false)
end
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(false)
end
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏奖励相关区域
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(false)
end
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(false)
end
if self.awardNum0 and self.awardNum0.gameObject then
self.awardNum0.gameObject:SetActive(false)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
-- 隐藏已分享区域
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(false)
end
-- 隐藏倒计时区域
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(false)
end
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(false)
end
-- 隐藏按钮区域
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(false)
end
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏最大奖励数字
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
self.rightStartShareNum4.gameObject:SetActive(false)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
self.rightStartShareNum5.gameObject:SetActive(false)
end
-- g_Log(TAG, "已隐藏所有UI元素")
end
function FsyncElement:DestroyView()
-- -- 清理弹幕资源
-- self:ClearBarrageItems()
if self.shareButton then
self.shareButton.onClick:RemoveAllListeners()
end
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
-- 清理redImages引用
if self.redImages then
for i = 0, 9 do
self.redImages[i] = nil
end
self.redImages = nil
end
if self.objRoot then
CS.UnityEngine.GameObject.DestroyImmediate(self.objRoot)
self.objRoot = nil
end
self.readBookPanel = nil
self.dialogContentRect = nil
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
self.pageMonitorService:recordPageClose(PageId)
end
function FsyncElement:ShareReadBookReport()
local image = "https://static0.xesimg.com/next-studio-pub/app/1736943865007/zQsexNIiSJTCdgnwr9AZ.png"
self.content = {
title = self.shareInfo.title,
-- contentDesc = self.shareInfo.contentDesc,
url = self.shareInfo.url,
imageType = "network",
image = image,
thumbImageUrl = image,
previewImageUrl = image
}
local param = { type = "WeChatTimeline", contentType = "web", content = self.content }
APIBridge.RequestAsync('app.api.share.shareToNative', param, function(res)
if res then
g_Log(TAG, "分享微信朋友圈,回调--->" .. table.dump(res))
end
end)
end
-- 收到/恢复IRC消息
-- @param key 订阅的消息key
-- @param value 消息集合体
-- @param isResume 是否为恢复消息
function FsyncElement:ReceiveMessage(key, value, isResume)
-- TODO:
end
-- 发送KEY-VALUE 消息
-- @param key 自定义/协议key
-- @param body table 消息体
function FsyncElement:SendCustomMessage(key, body)
self:SendMessage(key,body)
end
-- 自己avatar对象创建完成
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarCreated(avatar)
end
-- 自己avatar对象人物模型加载完成ba
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarPrefabLoaded(avatar)
end
-- avatar对象创建完成,包含他人和自己
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:AvatarCreated(avatar)
end
------------------------蓝图组件相应方法---------------------------------------------
--是否是异步恢复如果是需要改成true
function FsyncElement:LogicMapIsAsyncRecorver()
return false
end
--开始恢复方法(断线重连的时候用)
function FsyncElement:LogicMapStartRecover()
FsyncElement.super:LogicMapStartRecover()
--TODO
end
--结束恢复方法 (断线重连的时候用)
function FsyncElement:LogicMapEndRecover()
FsyncElement.super:LogicMapEndRecover(self)
--TODO
end
--所有的组件恢复完成
function FsyncElement:LogicMapAllComponentRecoverComplete()
end
--收到Trigger事件
function FsyncElement:OnReceiveTriggerEvent(interfaceId)
end
--收到GetData事件
function FsyncElement:OnReceiveGetDataEvent(interfaceId)
return nil
end
------------------------蓝图组件相应方法End---------------------------------------------
---接口请求
function FsyncElement:ShareReadBook(callback)
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
callback(true)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
---获取分享信息
function FsyncElement:GetShareInfo(callback)
if self.shareInfo and self.requestTime and os.time() - self.requestTime < 30 then
callback(true, self.shareInfo)
return
end
self.requestTime = os.time()
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
local shareInfo = {
userId = data.userId,
reportStatus = data.report_status, --2:已分享 1:未分享
bookId = data.book_id,
levelNo = data.level_no,
title = data.title,
-- contentDesc = data.contentDesc,
url = data.url,
maxRewards = data.max_rewards, -- 最大奖励
endTime = data.end_time, -- 剩余时间
count = data.count, -- 查看人数
friends = data.friends -- 好友列表
}
-- 确保maxRewards是数字
if shareInfo.maxRewards and type(shareInfo.maxRewards) == "string" then
shareInfo.maxRewards = tonumber(shareInfo.maxRewards) or 0
elseif not shareInfo.maxRewards then
shareInfo.maxRewards = 0
end
g_Log(TAG, string.format("获取分享信息成功: maxRewards=%d, count=%d", shareInfo.maxRewards, shareInfo.count or 0))
self.shareInfo = shareInfo
-- 只有在UI已经初始化的情况下才更新弹幕
if self.barrage and shareInfo.friends and #shareInfo.friends > 0 then
local hasChanged = self:UpdateBarrageContent(shareInfo.friends)
-- 如果弹幕内容有变化且需要显示弹幕,则启动弹幕滚动
if hasChanged and self.shareInfo.reportStatus == 2 then
self:StartBarrageScroll()
end
end
callback(true, shareInfo)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
function FsyncElement:HttpRequest(url, params, success, fail)
if App.IsStudioClient then
self.httpService:PostForm(url, params, {}, success, fail)
else
APIBridge.RequestAsync('api.httpclient.request', {
["url"] = url,
["headers"] = {
["Content-Type"] = "application/json"
},
["data"] = params
}, function(res)
if res ~= nil and res.responseString ~= nil and res.isSuccessed then
local resp = res.responseString
success(resp)
else
fail(res)
end
end)
end
end
---埋点方法
function FsyncElement:reportData(event, label, value, action)
if not App.IsStudioClient then
NextStudioComponentStatisticsAPI.ComponentStatisticsWithParam(event, "84169", "Special-Interaction", label,
action, value)
end
end
-- 脚本释放
function FsyncElement:Exit()
-- 清理弹幕资源
self:ClearBarrageItems()
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
-- 释放弹幕系统资源
if self.barrageSystem then
self.barrageSystem:Release()
self.barrageSystem = nil
end
FsyncElement.super.Exit(self)
end
-- 更新获取按钮上的数字显示
function FsyncElement:UpdateGetBtnNumbers()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- g_Log(TAG, string.format("更新获取按钮数字: 奖励值=%d", awardValue))
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
self.getBtnNum2.gameObject:SetActive(false)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.getBtnNum1 and self.getBtnNum1.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum1.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
end
-- 显示钻石图标
if self.getBtnDiamond6 and self.getBtnDiamond6.gameObject then
self.getBtnDiamond6.gameObject:SetActive(true)
end
end
-- function FsyncElement:InitBarrage()
-- -- 如果弹幕已经在运行,则不重复初始化
-- if self.isBarrageRunning then
-- return
-- end
-- -- g_Log(TAG, "初始化弹幕系统")
-- -- 确保弹幕区域可见
-- if self.barrageRange and self.barrageRange.gameObject then
-- self.barrageRange.gameObject:SetActive(true)
-- else
-- g_Log(TAG, "弹幕区域不存在,无法初始化弹幕")
-- return
-- end
-- -- 清理之前的弹幕项
-- self:ClearBarrageItems()
-- -- 获取弹幕范围区域的RectTransform
-- local barrageRangeRect = self.barrageRange:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- if not barrageRangeRect then
-- g_Log(TAG, "弹幕范围区域没有RectTransform组件")
-- return
-- end
-- -- 获取弹幕范围区域的宽度
-- local barrageRangeWidth = barrageRangeRect.rect.width
-- self.barrageRangeWidth = barrageRangeWidth
-- -- 创建弹幕项
-- if self.shareInfo and self.shareInfo.friends and #self.shareInfo.friends > 0 then
-- -- 先计算所有弹幕的宽度
-- self.commonService:StartCoroutine(function()
-- -- 创建临时弹幕项来计算宽度
-- local tempWidths = {}
-- for i, friend in ipairs(self.shareInfo.friends) do
-- local width = self:CalculateBarrageWidth(friend)
-- tempWidths[i] = width
-- -- g_Log(TAG, string.format("弹幕项 %d (名字: %s) 计算宽度: %f", i, friend.name or "未知", width))
-- end
-- -- 创建实际的弹幕项并设置位置
-- local lastRightEdge = barrageRangeWidth -- 第一个弹幕从屏幕右侧开始
-- for i, friend in ipairs(self.shareInfo.friends) do
-- self:CreateBarrageItem(friend, i, lastRightEdge, tempWidths[i])
-- -- 下一个弹幕的起始位置 = 当前弹幕的右边缘 + 间距
-- lastRightEdge = lastRightEdge + tempWidths[i] + self.barrageSpacing
-- end
-- -- 启动弹幕移动
-- self:StartBarrageMovement()
-- end)
-- else
-- g_Log(TAG, "没有好友数据,无法创建弹幕")
-- end
-- end
-- -- 计算弹幕宽度
-- function FsyncElement:CalculateBarrageWidth(friend)
-- -- 创建临时对象来计算宽度
-- local tempObj = GameObject.Instantiate(self.barrage.gameObject)
-- tempObj.transform:SetParent(self.barrageRange)
-- tempObj.name = "TempBarrageItem"
-- -- 设置缩放为1,确保计算准确
-- local rectTransform = tempObj:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- if rectTransform then
-- rectTransform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
-- end
-- -- 查找并设置昵称
-- local nameText = tempObj.transform:Find("name")
-- local nameTextComponent = nil
-- if nameText then
-- nameTextComponent = nameText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
-- if nameTextComponent and friend and friend.name then
-- nameTextComponent.text = friend.name
-- end
-- end
-- -- 查找并设置文本内容
-- local contentText = tempObj.transform:Find("text")
-- local contentTextComponent = nil
-- if contentText then
-- contentTextComponent = contentText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
-- if contentTextComponent then
-- contentTextComponent.text = "收听了你的报告"
-- end
-- end
-- -- 在协程中等待一帧,确保文本组件已经更新布局
-- self.commonService:StartCoroutine(function()
-- self.commonService:YieldEndFrame()
-- end)
-- -- 计算名称文本的实际宽度
-- local nameWidth = 0
-- if nameTextComponent then
-- -- 对于TextMeshProUGUI
-- if nameTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
-- nameWidth = nameTextComponent.preferredWidth
-- end
-- end
-- -- 计算内容文本的宽度
-- local contentWidth = 0
-- if contentTextComponent then
-- -- 对于TextMeshProUGUI
-- if contentTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
-- contentWidth = contentTextComponent.preferredWidth
-- end
-- end
-- -- 获取头像宽度
-- local headWidth = 0
-- local headImage = tempObj.transform:Find("head")
-- if headImage then
-- local headRect = headImage:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- if headRect then
-- headWidth = headRect.rect.width
-- end
-- end
-- -- 销毁临时对象
-- GameObject.Destroy(tempObj)
-- -- 计算所需的总宽度(头像 + 名称 + 内容 + 边距)
-- local padding = 40 -- 左右边距和元素之间的间距
-- -- 确保标准名字宽度已经计算
-- if self.standardNameWidth <= 0 then
-- self.standardNameWidth = 120 -- 默认值
-- g_Log(TAG, "使用默认标准名字宽度: 120")
-- end
-- -- 计算实际宽度与标准宽度的差异
-- local widthDifference = nameWidth - self.standardNameWidth
-- -- 根据差异调整总宽度
-- local totalWidth = headWidth + nameWidth + contentWidth + padding+16
-- g_Log(TAG, string.format("弹幕项 (名字: %s) 计算宽度: 名字宽度=%f, 标准宽度=%f, 差异=%f, 总宽度=%f",
-- friend and friend.name or "未知", nameWidth, self.standardNameWidth, widthDifference, totalWidth))
-- return totalWidth
-- end
-- -- 创建弹幕
-- function FsyncElement:CreateBarrageItem(friend, index, startX, width)
-- -- 复制模板创建新的弹幕项
-- local barrageItem = GameObject.Instantiate(self.barrage.gameObject)
-- -- 将弹幕项设置为barrageRange的子节点,确保在范围内移动
-- barrageItem.transform:SetParent(self.barrageRange)
-- barrageItem.name = "BarrageItem_" .. index
-- -- 获取RectTransform并设置位置
-- local rectTransform = barrageItem:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- if not rectTransform then
-- g_Log(TAG, "弹幕项没有RectTransform组件")
-- GameObject.Destroy(barrageItem)
-- return
-- end
-- -- 设置缩放为1,确保弹幕项大小正确
-- rectTransform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
-- -- 保持原始大小和锚点设置
-- rectTransform.anchorMin = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform)).anchorMin
-- rectTransform.anchorMax = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform)).anchorMax
-- -- 获取原始barrage的RectTransform组件
-- local barrageRectTransform = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- -- 获取其anchoredPosition.y值
-- local originalY = barrageRectTransform.anchoredPosition.y
-- -- 使用原始barrage的Y位置设置弹幕项的位置
-- rectTransform.anchoredPosition = CS.UnityEngine.Vector2(startX, originalY)
-- -- 查找并设置头像
-- local headImage = barrageItem.transform:Find("head")
-- local headRectTransform = nil
-- if headImage then
-- headRectTransform = headImage:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- local image = headImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
-- if image and friend.avatar and friend.avatar ~= "" then
-- -- 加载网络头像
-- self.httpService:LoadNetWorkTexture(friend.avatar, function(texture)
-- if image then
-- image.sprite = texture
-- end
-- end, "barrage_" .. index)
-- else
-- g_Log(TAG,"读课文分享新-----弹幕头像为空")
-- end
-- end
-- -- 查找并设置昵称
-- local nameText = barrageItem.transform:Find("name")
-- local nameTextComponent = nil
-- local nameRectTransform = nil
-- if nameText then
-- nameRectTransform = nameText:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- -- 设置名字文本的锚点为左居中
-- if nameRectTransform then
-- nameRectTransform.anchorMin = CS.UnityEngine.Vector2(0, 0.5)
-- nameRectTransform.anchorMax = CS.UnityEngine.Vector2(0, 0.5)
-- nameRectTransform.pivot = CS.UnityEngine.Vector2(0, 0.5)
-- end
-- nameTextComponent = nameText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
-- if nameTextComponent and friend.name then
-- nameTextComponent.text = friend.name
-- -- 设置文本对齐方式为左对齐
-- if nameTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
-- nameTextComponent.alignment = CS.TMPro.TextAlignmentOptions.Left
-- end
-- end
-- end
-- -- 查找并设置文本内容
-- local contentText = barrageItem.transform:Find("text")
-- local contentTextComponent = nil
-- local contentRectTransform = nil
-- if contentText then
-- contentRectTransform = contentText:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- contentTextComponent = contentText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
-- if contentTextComponent then
-- contentTextComponent.text = "收听了你的报告"
-- end
-- end
-- -- 在协程中等待一帧,确保文本组件已经更新布局
-- self.commonService:StartCoroutine(function()
-- self.commonService:YieldEndFrame()
-- -- 计算各元素的宽度
-- local headWidth = 0
-- if headRectTransform then
-- headWidth = headRectTransform.rect.width
-- end
-- local nameWidth = 0
-- if nameTextComponent then
-- if nameTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
-- nameWidth = nameTextComponent.preferredWidth
-- end
-- end
-- local contentWidth = 0
-- if contentTextComponent then
-- if contentTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
-- contentWidth = contentTextComponent.preferredWidth
-- end
-- end
-- -- 计算所需的总宽度
-- -- 总宽度 = 左边距(4) + 头像宽度 + 头像与名字间距(8) + 名字宽度 + 名字与内容间距(8) + 内容宽度 + 右边距(16)
-- local totalWidth = 4 + headWidth + 8 + nameWidth + 8 + contentWidth + 16
-- -- 设置弹幕项的宽度
-- local currentSize = rectTransform.sizeDelta
-- rectTransform.sizeDelta = CS.UnityEngine.Vector2(totalWidth, currentSize.y)
-- -- 设置头像位置(距离左边缘4像素)
-- if headRectTransform then
-- headRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4, headRectTransform.anchoredPosition.y)
-- end
-- -- 设置名字位置(头像右侧8像素处)
-- if nameRectTransform then
-- nameRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4 + headWidth + 8, nameRectTransform.anchoredPosition.y)
-- end
-- -- 设置内容文本位置(名字右侧8像素处)
-- if contentRectTransform then
-- contentRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4 + headWidth + 8 + nameWidth + 8, contentRectTransform.anchoredPosition.y)
-- end
-- g_Log(TAG, string.format("设置弹幕: name=%s, 头像宽度=%f, 名字宽度=%f, 内容宽度=%f, 总宽度=%f",
-- friend.name or "未知", headWidth, nameWidth, contentWidth, totalWidth))
-- -- 更新记录的宽度
-- for i, item in ipairs(self.barrageItems) do
-- if item.gameObject == barrageItem then
-- item.width = totalWidth
-- break
-- end
-- end
-- end)
-- -- 激活弹幕项
-- barrageItem:SetActive(true)
-- -- 将弹幕项添加到列表中
-- table.insert(self.barrageItems, {
-- gameObject = barrageItem,
-- rectTransform = rectTransform,
-- index = index,
-- userId = friend.user_id,
-- width = width or 0 -- 记录弹幕宽度,稍后会在协程中更新
-- })
-- end
-- -- 修改StartBarrageMovement函数
-- function FsyncElement:StartBarrageMovement()
-- if #self.barrageItems == 0 then
-- g_Log(TAG, "没有弹幕项,无法启动弹幕移动")
-- return
-- end
-- self.isBarrageRunning = true
-- -- 启动协程来移动弹幕
-- self.barrageCoroutine = self:StartCoroutine(function()
-- while self.isBarrageRunning do
-- -- 移动每个弹幕项
-- for _, item in ipairs(self.barrageItems) do
-- if item.gameObject and item.rectTransform then
-- -- 获取当前位置
-- local pos = item.rectTransform.anchoredPosition
-- -- 计算新位置(向左移动)
-- local newX = pos.x - self.barrageSpeed * Time.deltaTime
-- if newX < -self.barrageRangeWidth/2 then
-- -- 找到当前最右侧的弹幕
-- local rightmostX = -math.huge
-- local rightmostItem = nil
-- for _, otherItem in ipairs(self.barrageItems) do
-- if otherItem.rectTransform and otherItem.rectTransform.anchoredPosition.x > rightmostX then
-- rightmostX = otherItem.rectTransform.anchoredPosition.x
-- rightmostItem = otherItem
-- end
-- end
-- -- 将当前弹幕放置在最右侧弹幕之后
-- if rightmostItem then
-- -- 新位置 = 最右侧弹幕的位置 + 最右侧弹幕的宽度 + 间距
-- newX = rightmostX + rightmostItem.width + self.barrageSpacing
-- else
-- -- 如果没有找到最右侧弹幕,则从屏幕右侧重新开始
-- newX = self.barrageRangeWidth
-- end
-- g_Log(TAG, string.format("弹幕重置位置: index=%d, newX=%f", item.index, newX))
-- end
-- -- 更新位置
-- item.rectTransform.anchoredPosition = CS.UnityEngine.Vector2(newX, pos.y)
-- end
-- end
-- -- 等待下一帧
-- self:YieldEndFrame()
-- end
-- end)
-- end
function FsyncElement:InitCountDown()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 解析接口返回的endTime字段,格式如:"2天23小时59分"
local days, hours, minutes = 0, 0, 0
if self.shareInfo.endTime and self.shareInfo.endTime ~= "" then
local endTimeStr = self.shareInfo.endTime
-- 解析天数
local daysStr = string.match(endTimeStr, "(%d+)天")
if daysStr then
days = tonumber(daysStr) or 0
end
-- 解析小时
local hoursStr = string.match(endTimeStr, "(%d+)小时") or string.match(endTimeStr, "(%d+)时")
if hoursStr then
hours = tonumber(hoursStr) or 0
end
-- 解析分钟
local minutesStr = string.match(endTimeStr, "(%d+)分")
if minutesStr then
minutes = tonumber(minutesStr) or 0
end
g_Log(TAG, string.format("解析倒计时: %d天%02d时%02d分", days, hours, minutes))
else
g_Log(TAG, "倒计时字符串为空或不存在")
end
-- 预加载red0~red9图片
self.redImages = {}
for i = 0, 9 do
-- 假设red0~red9图片已经在CutDiagram节点下
local redImage = self.cutDiagram:Find("red" .. i)
if redImage then
self.redImages[i] = redImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
end
end
-- 更新倒计时显示,显示的分钟数比实际剩余时间多一分钟
local function updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 调整显示的分钟数,如果秒数大于0,则分钟数+1
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
-- 处理进位
if displayMinutes == 60 then
displayMinutes = 0
remainHours = remainHours + 1
if remainHours == 24 then
remainHours = 0
remainDays = remainDays + 1
end
end
end
-- 更新天数显示
self:UpdateNumberImage(self.daynum, remainDays)
-- 更新小时显示(两位数)
local hourTens = math.floor(remainHours / 10)
local hourOnes = remainHours % 10
self:UpdateNumberImage(self.hournum0, hourTens)
self:UpdateNumberImage(self.hournum1, hourOnes)
-- 更新分钟显示(两位数)
local minuteTens = math.floor(displayMinutes / 10)
local minuteOnes = displayMinutes % 10
self:UpdateNumberImage(self.minutenum0, minuteTens)
self:UpdateNumberImage(self.minutenum1, minuteOnes)
-- 记录日志
g_Log(TAG, string.format("倒计时更新: 实际剩余时间=%d天%02d小时%02d分%02d秒, 显示=%d天%02d小时%02d分",
remainDays, remainHours, remainMinutes, remainSeconds, remainDays, remainHours, displayMinutes))
end
-- 倒计时结束时更新UI状态
local function onCountdownFinished()
g_Log(TAG, "倒计时结束,更新UI状态")
-- 隐藏倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 更新UI显示
self:SetViewByShareInfo()
end
-- 计算总秒数
local totalSeconds = days * 86400 + hours * 3600 + minutes * 60
local endTime = os.time() + totalSeconds
-- 立即检查是否应该显示倒计时
if totalSeconds > 0 and self.shareInfo.reportStatus == 2 and self.isInCountdown then
g_Log(TAG,"读课文分享新-----倒计时开始显示倒计时UI1111111111111"..totalSeconds)
-- 显示倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
g_Log(TAG,"读课文分享新-----显示倒计时UI0000000000000")
end
-- 注册全局定时器,每秒更新一次倒计时(改为每秒更新以获得更流畅的体验)
self.countDownTimerId = self.commonService:RegisterGlobalTimer(1, function()
local now = os.time()
local diff = endTime - now
if diff <= 0 then
-- 倒计时结束
g_Log(TAG,"读课文分享新-----倒计时结束注销定时器3333333333333")
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.isInCountdown=false
onCountdownFinished()
return
end
local remainDays = math.floor(diff / 86400)
local remainHours = math.floor((diff % 86400) / 3600)
local remainMinutes = math.floor((diff % 3600) / 60)
local remainSeconds = diff % 60
-- 只有当秒数为0或者分钟或更高单位变化时才更新UI显示
-- 或者当秒数变化导致显示的分钟数变化时也更新UI
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
end
if remainSeconds == 0 or (not self.lastRemainingMinutes) or self.lastRemainingMinutes ~= remainMinutes or
(not self.lastRemainingHours) or self.lastRemainingHours ~= remainHours or
(not self.lastRemainingDays) or self.lastRemainingDays ~= remainDays or
(not self.lastDisplayMinutes) or self.lastDisplayMinutes ~= displayMinutes then
-- 更新UI显示
updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 记录当前时间,用于下次比较
self.lastRemainingMinutes = remainMinutes
self.lastRemainingHours = remainHours
self.lastRemainingDays = remainDays
self.lastDisplayMinutes = displayMinutes
end
end, true)
else
-- 不需要显示倒计时,确保倒计时UI被隐藏
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 如果不是倒计时状态,可能是已经结束或者未开始
if self.shareInfo.reportStatus == 2 then
-- 已分享状态但不在倒计时中,说明倒计时已结束
onCountdownFinished()
end
end
end)
end
-- -- 清除弹幕
-- function FsyncElement:ClearBarrageItems()
-- -- 停止弹幕移动
-- self.isBarrageRunning = false
-- -- 停止弹幕协程
-- if self.barrageCoroutine then
-- self:StopCoroutineSafely(self.barrageCoroutine)
-- self.barrageCoroutine = nil
-- end
-- -- 销毁所有弹幕项
-- for _, item in ipairs(self.barrageItems) do
-- if item.gameObject then
-- GameObject.Destroy(item.gameObject)
-- end
-- end
-- -- 清空弹幕项列表
-- self.barrageItems = {}
-- -- 释放网络图片资源
-- for i = 1, 100 do -- 假设最多100个弹幕项
-- self.httpService:ReleaseTextureWithBusinessId("barrage_" .. i)
-- end
-- end
--/
-- 更新弹幕内容
function FsyncElement:UpdateBarrageContent(friends)
-- 检查friends是否为nil或空
if not friends or #friends == 0 then
g_Log("BarrageSystem", "好友列表为空,不更新弹幕")
return false
end
-- 检查barrage是否已初始化
if not self.barrage then
g_Log("BarrageSystem", "弹幕模板未初始化,无法更新弹幕")
return false
end
-- 初始化cachedFriends如果它是nil
if not self.cachedFriends then
self.cachedFriends = {}
end
-- 检查是否有变化
local hasChanged = self:CheckFriendsChanged(friends)
if not hasChanged then
g_Log("BarrageSystem", "好友列表未变化,不更新弹幕")
return false
end
-- 更新缓存
self.cachedFriends = self:DeepCopyFriends(friends)
-- 清理现有弹幕
self:ClearActiveBarrages()
-- 预创建弹幕到对象池
self:PreCreateBarrages()
g_Log("BarrageSystem", "弹幕内容已更新,共 " .. #friends .. " 条弹幕")
return true
end
-- 检查好友列表是否有变化
function FsyncElement:CheckFriendsChanged(newFriends)
-- 如果缓存为空但新列表不为空,则认为有变化
if not self.cachedFriends or #self.cachedFriends == 0 then
if newFriends and #newFriends > 0 then
return true
else
return false
end
end
-- 如果长度不同,则认为有变化
if #self.cachedFriends ~= #newFriends then
return true
end
-- 简单比较用户ID是否有变化
local userIdMap = {}
for _, friend in ipairs(self.cachedFriends) do
-- 确保friend和friend.user_id不为nil
if friend and friend.user_id then
userIdMap[friend.user_id] = true
end
end
for _, friend in ipairs(newFriends) do
-- 确保friend和friend.user_id不为nil
if friend and friend.user_id then
if not userIdMap[friend.user_id] then
return true
end
else
-- 如果新列表中有元素没有user_id,也认为有变化
return true
end
end
return false
end
-- 深拷贝好友列表
function FsyncElement:DeepCopyFriends(friends)
local copy = {}
if not friends then
return copy
end
for i, friend in ipairs(friends) do
if friend then
copy[i] = {
user_id = friend.user_id or "",
name = friend.name or "",
avatar = friend.avatar or ""
}
end
end
return copy
end
-- 预创建弹幕到对象池
function FsyncElement:PreCreateBarrages()
-- 清空对象池
self:ClearBarragePool()
-- 为每个好友创建弹幕项
for i, friend in ipairs(self.cachedFriends) do
self:CreateBarrageToPool(friend, i)
end
end
-- 创建单个弹幕到对象池
function FsyncElement:CreateBarrageToPool(friend, index)
-- 实例化弹幕对象
local barrageObj = GameObject.Instantiate(self.barrage.gameObject)
barrageObj.transform:SetParent(self.barrageRange)
barrageObj.name = "BarragePool_" .. index
-- 设置缩放为1,确保大小正确
local rectTransform = barrageObj:GetComponent(typeof(CS.UnityEngine.RectTransform))
if rectTransform then
rectTransform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
end
-- 查找并设置头像
local headImage = barrageObj.transform:Find("head")
if headImage then
local image = headImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and friend.avatar and friend.avatar ~= "" then
-- 加载网络头像
self.httpService:LoadNetWorkTexture(friend.avatar, function(texture)
if image then
image.sprite = texture
end
end, "barrage_pool_" .. index)
end
end
-- 查找并设置昵称
local nameText = barrageObj.transform:Find("name")
if nameText then
local nameTextComponent = nameText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent and friend.name then
nameTextComponent.text = friend.name
end
end
-- 查找并设置文本内容
local contentText = barrageObj.transform:Find("text")
if contentText then
local contentTextComponent = contentText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if contentTextComponent then
contentTextComponent.text = "收听了你的报告"
end
end
-- 计算弹幕宽度和布局
self:CalculateBarrageLayout(barrageObj, friend)
-- 隐藏弹幕对象
barrageObj:SetActive(false)
-- 添加到对象池
table.insert(self.barragePool, {
gameObject = barrageObj,
rectTransform = rectTransform,
userId = friend.user_id,
name = friend.name,
width = 0 -- 宽度将在计算布局后更新
})
end
-- 计算弹幕布局
function FsyncElement:CalculateBarrageLayout(barrageObj, friend)
-- 在协程中计算布局,确保UI元素已更新
self.commonService:StartCoroutine(function()
-- 等待一帧确保UI元素已更新
self.commonService:YieldEndFrame()
local rectTransform = barrageObj:GetComponent(typeof(CS.UnityEngine.RectTransform))
if not rectTransform then return end
-- 获取头像、名字和内容文本的Transform
local headTransform = barrageObj.transform:Find("head")
local nameTransform = barrageObj.transform:Find("name")
local contentTransform = barrageObj.transform:Find("text")
-- 计算各元素的宽度
local headWidth = 0
if headTransform then
local headRect = headTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRect then
headWidth = headRect.rect.width
end
end
local nameWidth = 0
if nameTransform then
local nameTextComponent = nameTransform:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent then
nameWidth = nameTextComponent.preferredWidth
end
end
local contentWidth = 0
if contentTransform then
local contentTextComponent = contentTransform:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if contentTextComponent then
contentWidth = contentTextComponent.preferredWidth
end
end
-- 计算总宽度(左边距 + 头像 + 间距 + 名字 + 间距 + 内容 + 右边距)
local leftPadding = 4
local rightPadding = 16
local elementSpacing = 8
local totalWidth = leftPadding + headWidth + elementSpacing + nameWidth + elementSpacing + contentWidth + rightPadding
-- 设置弹幕项的宽度
local currentSize = rectTransform.sizeDelta
rectTransform.sizeDelta = CS.UnityEngine.Vector2(totalWidth, currentSize.y)
-- 设置头像位置
if headTransform then
local headRectTransform = headTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRectTransform then
headRectTransform.anchoredPosition = CS.UnityEngine.Vector2(leftPadding, headRectTransform.anchoredPosition.y)
end
end
-- 设置名字位置
if nameTransform then
local nameRectTransform = nameTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if nameRectTransform then
nameRectTransform.anchoredPosition = CS.UnityEngine.Vector2(leftPadding + headWidth + elementSpacing, nameRectTransform.anchoredPosition.y)
end
end
-- 设置内容文本位置
if contentTransform then
local contentRectTransform = contentTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if contentRectTransform then
contentRectTransform.anchoredPosition = CS.UnityEngine.Vector2(leftPadding + headWidth + elementSpacing + nameWidth + elementSpacing, contentRectTransform.anchoredPosition.y)
end
end
-- 更新对象池中的宽度记录
for _, item in ipairs(self.barragePool) do
if item.gameObject == barrageObj then
item.width = totalWidth
break
end
end
g_Log("BarrageSystem", string.format("弹幕布局计算完成: name=%s, 总宽度=%f", friend.name or "未知", totalWidth))
end)
end
-- 启动弹幕滚动
function FsyncElement:StartBarrageScroll()
if self.isBarrageRunning then
g_Log("BarrageSystem", "弹幕已经在运行中")
return
end
if #self.barragePool == 0 then
g_Log("BarrageSystem", "弹幕池为空,无法启动滚动")
return
end
self.isBarrageRunning = true
-- 初始化活跃弹幕
self:InitActiveBarrages()
-- 启动滚动协程
self.scrollCoroutine = self.commonService:StartCoroutine(function()
while self.isBarrageRunning do
self:UpdateBarragePositions()
self.commonService:YieldEndFrame()
end
end)
g_Log("BarrageSystem", "弹幕滚动已启动")
end
-- 初始化活跃弹幕
function FsyncElement:InitActiveBarrages()
-- 清空活跃弹幕列表
self:ClearActiveBarrages()
-- 计算初始位置
local startX = self.barrageRangeWidth -- 从屏幕右侧开始
self.barrangeTransform=self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 激活所有弹幕并设置初始位置
for i, barrageItem in ipairs(self.barragePool) do
local barrageObj = barrageItem.gameObject
local rectTransform = barrageItem.rectTransform
-- 设置初始位置
rectTransform.anchoredPosition = CS.UnityEngine.Vector2(startX, self.barrangeTransform.anchoredPosition.y)
-- 激活弹幕
barrageObj:SetActive(true)
-- 添加到活跃弹幕列表
table.insert(self.activeBarrages, {
gameObject = barrageObj,
rectTransform = rectTransform,
userId = barrageItem.userId,
name = barrageItem.name,
width = barrageItem.width
})
-- 下一个弹幕的起始位置 = 当前弹幕的右边缘 + 固定间距
startX = startX + barrageItem.width + self.barrageSpacing
end
end
-- 更新弹幕位置
function FsyncElement:UpdateBarragePositions()
if #self.activeBarrages == 0 then
return
end
-- 移动每个弹幕
for i, barrageItem in ipairs(self.activeBarrages) do
local rectTransform = barrageItem.rectTransform
if rectTransform then
-- 获取当前位置
local pos = rectTransform.anchoredPosition
-- 计算新位置(向左移动)
local newX = pos.x - self.barrageSpeed * Time.deltaTime
-- 如果弹幕完全移出屏幕左侧
if newX < -self.barrageRangeWidth/2 then
-- 找到当前最右侧的弹幕
local rightmostX = -math.huge
local rightmostIndex = 0
for j, item in ipairs(self.activeBarrages) do
if item.rectTransform and item.rectTransform.anchoredPosition.x > rightmostX then
rightmostX = item.rectTransform.anchoredPosition.x
rightmostIndex = j
end
end
-- 将当前弹幕放置在最右侧弹幕之后,保持固定间距
if rightmostIndex > 0 and rightmostIndex ~= i then
local rightmostItem = self.activeBarrages[rightmostIndex]
newX = rightmostItem.rectTransform.anchoredPosition.x + rightmostItem.width + self.barrageSpacing
else
-- 如果找不到其他弹幕或者当前弹幕就是最右侧的,则从屏幕右侧重新开始
newX = self.barrageRangeWidth
end
end
-- 更新位置
rectTransform.anchoredPosition = CS.UnityEngine.Vector2(newX, pos.y)
end
end
end
-- 停止弹幕滚动
function FsyncElement:StopBarrageScroll()
self.isBarrageRunning = false
-- 停止滚动协程
if self.scrollCoroutine then
self.commonService:StopCoroutineSafely(self.scrollCoroutine)
self.scrollCoroutine = nil
end
g_Log("BarrageSystem", "弹幕滚动已停止")
end
-- 清理活跃弹幕
function FsyncElement:ClearActiveBarrages()
for _, item in ipairs(self.activeBarrages) do
if item.gameObject then
item.gameObject:SetActive(false)
end
end
self.activeBarrages = {}
end
-- 清理弹幕对象池
function FsyncElement:ClearBarragePool()
for _, item in ipairs(self.barragePool) do
if item.gameObject then
GameObject.Destroy(item.gameObject)
end
end
self.barragePool = {}
end
-- 释放资源
function FsyncElement:Release()
-- 停止弹幕滚动
self:StopBarrageScroll()
-- 清理活跃弹幕和对象池
self:ClearActiveBarrages()
self:ClearBarragePool()
-- 释放网络图片资源
for i = 1, #self.cachedFriends do
self.httpService:ReleaseTextureWithBusinessId("barrage_pool_" .. i)
end
-- 清空缓存
self.cachedFriends = {}
g_Log("BarrageSystem", "弹幕系统资源已释放")
end
return FsyncElement
///
协程版本
---
--- 弹幕系统实现
--- 支持对象池、动态布局和循环滚动
---
-- 弹幕系统类
local BarrageSystem = {}
-- 初始化弹幕系统
function BarrageSystem:Initialize(barrageTemplate, barrageRange, commonService, httpService)
-- 基础配置
self.barrageTemplate = barrageTemplate -- 弹幕模板
self.barrageRange = barrageRange -- 弹幕显示区域
self.commonService = commonService -- 通用服务
self.httpService = httpService -- HTTP服务
-- 弹幕系统状态
self.isRunning = false -- 弹幕是否正在运行
self.cachedFriends = {} -- 缓存的好友列表
self.barragePool = {} -- 弹幕对象池
self.activeBarrages = {} -- 活跃弹幕列表
-- 弹幕配置
self.barrageSpeed = 100 -- 弹幕移动速度
self.barrageSpacing = 60 -- 弹幕之间的间距
self.barrageRangeWidth = 0 -- 弹幕区域宽度
-- 获取弹幕区域宽度
local barrageRangeRect = self.barrageRange:GetComponent(typeof(CS.UnityEngine.RectTransform))
if barrageRangeRect then
self.barrageRangeWidth = barrageRangeRect.rect.width
end
g_Log("BarrageSystem", "弹幕系统初始化完成,显示区域宽度: " .. self.barrageRangeWidth)
return self
end
-- 更新弹幕内容
function BarrageSystem:UpdateBarrageContent(friends)
if not friends or #friends == 0 then
g_Log("BarrageSystem", "好友列表为空,不更新弹幕")
return false
end
-- 检查是否有变化
local hasChanged = self:CheckFriendsChanged(friends)
if not hasChanged then
g_Log("BarrageSystem", "好友列表未变化,不更新弹幕")
return false
end
-- 更新缓存
self.cachedFriends = self:DeepCopyFriends(friends)
-- 清理现有弹幕
self:ClearActiveBarrages()
-- 预创建弹幕到对象池
self:PreCreateBarrages()
g_Log("BarrageSystem", "弹幕内容已更新,共 " .. #friends .. " 条弹幕")
return true
end
-- 检查好友列表是否有变化
function BarrageSystem:CheckFriendsChanged(newFriends)
if #self.cachedFriends ~= #newFriends then
return true
end
-- 简单比较用户ID是否有变化
local userIdMap = {}
for _, friend in ipairs(self.cachedFriends) do
userIdMap[friend.user_id] = true
end
for _, friend in ipairs(newFriends) do
if not userIdMap[friend.user_id] then
return true
end
end
return false
end
-- 深拷贝好友列表
function BarrageSystem:DeepCopyFriends(friends)
local copy = {}
for i, friend in ipairs(friends) do
copy[i] = {
user_id = friend.user_id,
name = friend.name,
avatar = friend.avatar
}
end
return copy
end
-- 预创建弹幕到对象池
function BarrageSystem:PreCreateBarrages()
-- 清空对象池
self:ClearBarragePool()
-- 为每个好友创建弹幕项
for i, friend in ipairs(self.cachedFriends) do
self:CreateBarrageToPool(friend, i)
end
end
-- 创建单个弹幕到对象池
function BarrageSystem:CreateBarrageToPool(friend, index)
-- 实例化弹幕对象
local barrageObj = GameObject.Instantiate(self.barrageTemplate.gameObject)
barrageObj.transform:SetParent(self.barrageRange)
barrageObj.name = "BarragePool_" .. index
-- 设置缩放为1,确保大小正确
local rectTransform = barrageObj:GetComponent(typeof(CS.UnityEngine.RectTransform))
if rectTransform then
rectTransform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
end
-- 查找并设置头像
local headImage = barrageObj.transform:Find("head")
if headImage then
local image = headImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and friend.avatar and friend.avatar ~= "" then
-- 加载网络头像
self.httpService:LoadNetWorkTexture(friend.avatar, function(texture)
if image then
image.sprite = texture
end
end, "barrage_pool_" .. index)
end
end
-- 查找并设置昵称
local nameText = barrageObj.transform:Find("name")
if nameText then
local nameTextComponent = nameText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent and friend.name then
nameTextComponent.text = friend.name
end
end
-- 查找并设置文本内容
local contentText = barrageObj.transform:Find("text")
if contentText then
local contentTextComponent = contentText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if contentTextComponent then
contentTextComponent.text = "收听了你的报告"
end
end
-- 计算弹幕宽度和布局
self:CalculateBarrageLayout(barrageObj, friend)
-- 隐藏弹幕对象
barrageObj:SetActive(false)
-- 添加到对象池
table.insert(self.barragePool, {
gameObject = barrageObj,
rectTransform = rectTransform,
userId = friend.user_id,
name = friend.name,
width = 0 -- 宽度将在计算布局后更新
})
end
-- 计算弹幕布局
function BarrageSystem:CalculateBarrageLayout(barrageObj, friend)
-- 在协程中计算布局,确保UI元素已更新
self.commonService:StartCoroutine(function()
-- 等待一帧确保UI元素已更新
self.commonService:YieldEndFrame()
local rectTransform = barrageObj:GetComponent(typeof(CS.UnityEngine.RectTransform))
if not rectTransform then return end
-- 获取头像、名字和内容文本的Transform
local headTransform = barrageObj.transform:Find("head")
local nameTransform = barrageObj.transform:Find("name")
local contentTransform = barrageObj.transform:Find("text")
-- 计算各元素的宽度
local headWidth = 0
if headTransform then
local headRect = headTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRect then
headWidth = headRect.rect.width
end
end
local nameWidth = 0
if nameTransform then
local nameTextComponent = nameTransform:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent then
nameWidth = nameTextComponent.preferredWidth
end
end
local contentWidth = 0
if contentTransform then
local contentTextComponent = contentTransform:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if contentTextComponent then
contentWidth = contentTextComponent.preferredWidth
end
end
-- 计算总宽度(左边距 + 头像 + 间距 + 名字 + 间距 + 内容 + 右边距)
local leftPadding = 4
local rightPadding = 16
local elementSpacing = 8
local totalWidth = leftPadding + headWidth + elementSpacing + nameWidth + elementSpacing + contentWidth + rightPadding
-- 设置弹幕项的宽度
local currentSize = rectTransform.sizeDelta
rectTransform.sizeDelta = CS.UnityEngine.Vector2(totalWidth, currentSize.y)
-- 设置头像位置
if headTransform then
local headRectTransform = headTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRectTransform then
headRectTransform.anchoredPosition = CS.UnityEngine.Vector2(leftPadding, headRectTransform.anchoredPosition.y)
end
end
-- 设置名字位置
if nameTransform then
local nameRectTransform = nameTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if nameRectTransform then
nameRectTransform.anchoredPosition = CS.UnityEngine.Vector2(leftPadding + headWidth + elementSpacing, nameRectTransform.anchoredPosition.y)
end
end
-- 设置内容文本位置
if contentTransform then
local contentRectTransform = contentTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if contentRectTransform then
contentRectTransform.anchoredPosition = CS.UnityEngine.Vector2(leftPadding + headWidth + elementSpacing + nameWidth + elementSpacing, contentRectTransform.anchoredPosition.y)
end
end
-- 更新对象池中的宽度记录
for _, item in ipairs(self.barragePool) do
if item.gameObject == barrageObj then
item.width = totalWidth
break
end
end
g_Log("BarrageSystem", string.format("弹幕布局计算完成: name=%s, 总宽度=%f", friend.name or "未知", totalWidth))
end)
end
-- 启动弹幕滚动
function BarrageSystem:StartBarrageScroll()
if self.isRunning then
g_Log("BarrageSystem", "弹幕已经在运行中")
return
end
if #self.barragePool == 0 then
g_Log("BarrageSystem", "弹幕池为空,无法启动滚动")
return
end
self.isRunning = true
-- 初始化活跃弹幕
self:InitActiveBarrages()
-- 启动滚动协程
self.scrollCoroutine = self.commonService:StartCoroutine(function()
while self.isRunning do
self:UpdateBarragePositions()
self.commonService:YieldEndFrame()
end
end)
g_Log("BarrageSystem", "弹幕滚动已启动")
end
-- 初始化活跃弹幕
function BarrageSystem:InitActiveBarrages()
-- 清空活跃弹幕列表
self:ClearActiveBarrages()
-- 计算初始位置
local startX = self.barrageRangeWidth -- 从屏幕右侧开始
-- 激活所有弹幕并设置初始位置
for i, barrageItem in ipairs(self.barragePool) do
local barrageObj = barrageItem.gameObject
local rectTransform = barrageItem.rectTransform
-- 设置初始位置
rectTransform.anchoredPosition = CS.UnityEngine.Vector2(startX, rectTransform.anchoredPosition.y)
-- 激活弹幕
barrageObj:SetActive(true)
-- 添加到活跃弹幕列表
table.insert(self.activeBarrages, {
gameObject = barrageObj,
rectTransform = rectTransform,
userId = barrageItem.userId,
name = barrageItem.name,
width = barrageItem.width
})
-- 下一个弹幕的起始位置 = 当前弹幕的右边缘 + 固定间距
startX = startX + barrageItem.width + self.barrageSpacing
end
end
-- 更新弹幕位置
function BarrageSystem:UpdateBarragePositions()
if #self.activeBarrages == 0 then
return
end
-- 移动每个弹幕
for i, barrageItem in ipairs(self.activeBarrages) do
local rectTransform = barrageItem.rectTransform
if rectTransform then
-- 获取当前位置
local pos = rectTransform.anchoredPosition
-- 计算新位置(向左移动)
local newX = pos.x - self.barrageSpeed * Time.deltaTime
-- 如果弹幕完全移出屏幕左侧
if newX < -barrageItem.width then
-- 找到当前最右侧的弹幕
local rightmostX = -math.huge
local rightmostIndex = 0
for j, item in ipairs(self.activeBarrages) do
if item.rectTransform and item.rectTransform.anchoredPosition.x > rightmostX then
rightmostX = item.rectTransform.anchoredPosition.x
rightmostIndex = j
end
end
-- 将当前弹幕放置在最右侧弹幕之后,保持固定间距
if rightmostIndex > 0 and rightmostIndex ~= i then
local rightmostItem = self.activeBarrages[rightmostIndex]
newX = rightmostItem.rectTransform.anchoredPosition.x + rightmostItem.width + self.barrageSpacing
else
-- 如果找不到其他弹幕或者当前弹幕就是最右侧的,则从屏幕右侧重新开始
newX = self.barrageRangeWidth
end
end
-- 更新位置
rectTransform.anchoredPosition = CS.UnityEngine.Vector2(newX, pos.y)
end
end
end
-- 停止弹幕滚动
function BarrageSystem:StopBarrageScroll()
self.isRunning = false
-- 停止滚动协程
if self.scrollCoroutine then
self.commonService:StopCoroutineSafely(self.scrollCoroutine)
self.scrollCoroutine = nil
end
g_Log("BarrageSystem", "弹幕滚动已停止")
end
-- 清理活跃弹幕
function BarrageSystem:ClearActiveBarrages()
for _, item in ipairs(self.activeBarrages) do
if item.gameObject then
item.gameObject:SetActive(false)
end
end
self.activeBarrages = {}
end
-- 清理弹幕对象池
function BarrageSystem:ClearBarragePool()
for _, item in ipairs(self.barragePool) do
if item.gameObject then
GameObject.Destroy(item.gameObject)
end
end
self.barragePool = {}
}
-- 释放资源
function BarrageSystem:Release()
-- 停止弹幕滚动
self:StopBarrageScroll()
-- 清理活跃弹幕和对象池
self:ClearActiveBarrages()
self:ClearBarragePool()
-- 释放网络图片资源
for i = 1, #self.cachedFriends do
self.httpService:ReleaseTextureWithBusinessId("barrage_pool_" .. i)
end
-- 清空缓存
self.cachedFriends = {}
g_Log("BarrageSystem", "弹幕系统资源已释放")
end
return BarrageSystem
协程版本 全
---
--- Author: 【苏可欣】
--- AuthorID: 【384576】
--- CreateTime: 【2025-3-10 18:25:51】
--- 【FSync】
--- 【读书报告分享-新】
---
local class = require("middleclass")
local WBElement = require("mworld/worldBaseElement")
---@class fsync_4601a2d6_27d3_412e_82e0_9f0642dd34bd_1 : WorldBaseElement
local FsyncElement = class("fsync_4601a2d6-27d3-412e-82e0-9f0642dd34bd_1", WBElement)
local Fsync_Example_KEY = "_Example__Key_"
local TAG = "读书报告分享-新"
local readBookReport = "980161741793848/assets/Prefabs/ShareReadBookReport.prefab"
local PageId = "activity_center_share_readbook_report"
---@param worldElement CS.Tal.framesync.WorldElement
function FsyncElement:initialize(worldElement)
FsyncElement.super.initialize(self, worldElement)
---@type PageMonitorService
self.pageMonitorService = CourseEnv.BaseBusinessManager:GetPageMonitorService()
self:RegisterDownloadUaddress(readBookReport)
self.isInCountdown = true
self.hasCollectedReward = false -- 初始化为false,表示未领取奖励
-- 弹幕相关变量初始化
self.barrageItems = {} -- 存储所有弹幕项
self.barrageSpeed = 100 -- 弹幕移动速度
self.barrageSpacing = 150 -- 弹幕之间的间距
self.barrageItemWidth = 0 -- 弹幕项宽度,将在创建时计算
self.barrageRangeWidth = 0 -- 弹幕范围宽度,将在初始化时计算
self.isBarrageRunning = false -- 弹幕是否正在运行
-- 保存原始位置的变量
self.originalNamePosition = nil -- 原始名字位置
self.originalContentPosition = nil -- 原始内容位置
self.originalHeadPosition = nil -- 原始头像位置
self.standardNameWidth = 0 -- 标准名字宽度
self:InitEvent()
--订阅KEY消息
self:SubscribeMsgKey(Fsync_Example_KEY)
end
function FsyncElement:InitEvent()
--监听打开事件
self.observerService:Watch("ActivityCenter_Open_Canvas", function(key, value)
local data = value[0]
self.show = data.show
self.root = data.root
if self.show == "shareReadBook" then
self.isCurrIndex = true
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
end
end)
self:LoadingReadBookPage()
else
self.isCurrIndex = false
self:ClosePanel()
end
end)
self.observerService:Watch("ActivityCenter_Close_Canvas", function(key, value)
self:ClosePanel(true)
end)
end
function FsyncElement:LoadingReadBookPage()
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == false then
self.readBookPanel.gameObject:SetActive(true)
-- 如果面板已存在但被隐藏,重新显示时也要更新倒计时
if self.shareInfo then
self:InitCountDown()
end
return
end
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
return
end
self.pageMonitorService:recordPageOpen(PageId, "读书报告分享")
self:LoadRemoteUaddress(readBookReport, function(success, prefab)
if not self.isCurrIndex then
return
end
if success and prefab then
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
-- g_Log(TAG, "读书报告分享动态下载成功")
local obj = GameObject.Instantiate(prefab)
self.prefab = prefab
self.objRoot = obj
self.readBookPanel = obj.transform:FindChildWithName("Root")
self.readBookPanel:SetParent(self.root)
self.dialogContentRect = self.readBookPanel:GetComponent(typeof(CS.UnityEngine.RectTransform))
self.dialogContentRect.anchorMax = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchorMin = CS.UnityEngine.Vector2(0.5, 0.5)
self.dialogContentRect.anchoredPosition = CS.UnityEngine.Vector2.zero
self:InitReadBookView()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
local param_one = "0"
if self.shareInfo.reportStatus == 2 then
param_one = "1"
end
self:reportData("activity_center_share_readbook_report_show", "读书报告分享显示", { param_one = param_one }, "0")
-- 确保倒计时初始化
self:InitCountDown()
end)
self.pageMonitorService:recordPageLoadComplete(PageId)
end
end, true)
end
function FsyncElement:InitReadBookView()
-- 根据图片中的节点层级结构初始化UI元素
self.root = self.readBookPanel
-- Bg背景
self.bg = self.root:Find("Bg")
-- ContentPanel内容面板
self.contentPanel = self.root:Find("ContentPanel")
self.title = self.contentPanel:Find("Title")
-- Barrage弹幕区域
self.barrageRange = self.contentPanel:Find("BarrageRange")
self.barrage = self.barrageRange:Find("Barrage")
self.head = self.barrage:Find("head")
self.name = self.barrage:Find("name")
self.text = self.barrage:Find("text")
self.barrage.gameObject:SetActive(false)
-- RightBackImage右侧背景图
self.rightBackImage = self.contentPanel:Find("RightBackImage")
-- Jewels宝石区域
self.jewels = self.rightBackImage:Find("Jewels")
self.awardNum = self.jewels:Find("AwardNum")
self.awardPlus = self.awardNum:Find("Award+")
self.awardNum0 = self.awardNum:Find("AwardNum0")
self.awardNum1 = self.awardNum:Find("AwardNum1")
self.awardNum2 = self.awardNum:Find("AwardNum2")
-- HasShare已分享区域
self.hasShare = self.jewels:Find("HasShare")
self.text0 = self.hasShare:Find("text0")
self.diamond4 = self.hasShare:Find("diamond4")
self.num = self.hasShare:Find("num")
-- 右侧标题区域
self.rightStartShareTitle = self.contentPanel:Find("RightStartShareTitle")
self.rightStartShareNum3 = self.rightStartShareTitle:Find("num3")
self.rightStartShareNum3Text = self.rightStartShareNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightStartShareNum4 = self.rightStartShareTitle:Find("num4")
self.rightStartShareNum4Text = self.rightStartShareNum4:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightStartShareNum5 = self.rightStartShareTitle:Find("num5")
self.rightStartShareNum5Text = self.rightStartShareNum5:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.rightShareSuccessTitle = self.contentPanel:Find("RightShareSuccessTitle")
self.rightWaitCollectTitle = self.contentPanel:Find("RightWaitCollectTitle")
self.rightEndTitle = self.contentPanel:Find("RightEndTitle")
-- 底部区域
self.bottomStartShareTmp = self.contentPanel:Find("BottomStartShareTmp")
-- 底部分享成功区域
self.bottomShareSuccessTmp = self.contentPanel:Find("BottomShareSuccessTmp")
self.num1 = self.bottomShareSuccessTmp:Find("num1")
self.num1Text = self.num1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.num2 = self.bottomShareSuccessTmp:Find("num2")
self.num2Text = self.num2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.text1 = self.bottomShareSuccessTmp:Find("text1")
self.text2 = self.bottomShareSuccessTmp:Find("text2")
self.diamond5 = self.bottomShareSuccessTmp:Find("diamond5")
-- 底部等待收集区域
self.bottomWaitCollectTitle = self.contentPanel:Find("BottomWaitCollectTitle")
self.bottomWaitNum1 = self.bottomWaitCollectTitle:Find("num1")
self.bottomWaitNum1Text = self.bottomWaitNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitNum2 = self.bottomWaitCollectTitle:Find("num2")
self.bottomWaitNum2Text = self.bottomWaitNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomWaitText1 = self.bottomWaitCollectTitle:Find("text1")
self.bottomWaitText2 = self.bottomWaitCollectTitle:Find("text2")
self.bottomWaitDiamond6 = self.bottomWaitCollectTitle:Find("diamond6")
-- 底部结束区域
self.bottomEndTitle = self.contentPanel:Find("BottomEndTitle")
self.bottomEndNum1 = self.bottomEndTitle:Find("num1")
self.bottomEndNum1Text = self.bottomEndNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.bottomEndText1 = self.bottomEndTitle:Find("text1")
self.bottomEndText2 = self.bottomEndTitle:Find("text2")
-- 其他区域
self.bottomNoView = self.contentPanel:Find("BottomNoView")
self.bottomEndNoView = self.contentPanel:Find("BottomEndNoView")
-- 倒计时区域
self.countDown = self.contentPanel:Find("CountDown")
self.daynum = self.countDown:Find("daynum")
self.hournum0 = self.countDown:Find("hournum0")
self.hournum1 = self.countDown:Find("hournum1")
self.minutenum0 = self.countDown:Find("minutenum0")
self.minutenum1 = self.countDown:Find("minutenum1")
self.daytext = self.countDown:Find("daytext")
self.hourtext = self.countDown:Find("hourtext")
self.minutetext = self.countDown:Find("minutetext")
self.text0 = self.countDown:Find("text0")
self.getEndLabel = self.contentPanel:Find("GetEndLabel")
self.endLabel = self.contentPanel:Find("EndLabel")
-- 中途分享按钮
self.halfwayShare = self.contentPanel:Find("HalfwayShare")
if self.halfwayShare then
self.halfwayShareBtn = self.halfwayShare:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.halfwayShareBtn, "onClick", function()
-- 防止短时间内重复点击
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
-- 埋点上报
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
-- 检查是否有分享信息
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
if success then
self.shareInfo = shareInfo
-- 调用分享方法
self:ShareReadBook(function(success)
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end
end)
return
end
-- 直接调用分享方法
self:ShareReadBook(function(success)
if not success then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
end
end)
end)
end
-- 获取按钮区域
self.getBtn = self.contentPanel:Find("GetBtn")
self.getBtnNum1 = self.getBtn:Find("num1")
-- self.getBtnNum1Text = self.getBtnNum1:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnNum2 = self.getBtn:Find("num2")
-- self.getBtnNum2Text = self.getBtnNum2:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnNum3 = self.getBtn:Find("num3")
-- self.getBtnNum3Text = self.getBtnNum3:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
self.getBtnDiamond6 = self.getBtn:Find("diamond6")
if self.getBtn then
self.getBtnButton = self.getBtn:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.getBtnButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----获取按钮点击999999999999")
-- 添加标记,表示已经领取了奖励
self.hasCollectedReward = true
self:SetViewByShareInfo()
-- 禁用按钮,防止重复点击
self.getBtnButton.interactable = false
end)
end
self.btnText1 = self.getBtn:Find("text1")
self.btnNum1 = self.getBtn:Find("num1")
self.btnNum2 = self.getBtn:Find("num2")
self.btnNum3 = self.getBtn:Find("num3")
self.btnDiamond6 = self.getBtn:Find("diamond6")
-- 左侧内容和右侧副标题
self.leftContent = self.root:Find("LeftContent")
-- self.rightSubTitle = self.root:Find("RightSubTitle")
-- 图表区域
self.cutDiagram = self.root:Find("CutDiagram")
for i = 0, 9 do
self["cutDiagram" .. i] = self.cutDiagram:Find(tostring(i))
self["cutDiagramRed" .. i] = self.cutDiagram:Find("red" .. i)
self["cutDiagramSmall" .. i] = self.cutDiagram:Find("small" .. i)
end
-- 分享按钮
self.share = self.contentPanel:Find("Share")
self.shareButton = self.share:GetComponent(typeof(CS.UnityEngine.UI.Button))
self.commonService:AddEventListener(self.shareButton, "onClick", function()
-- g_Log(TAG,"读课文分享新-----点击")
if self.clickTime and os.time() - self.clickTime < 2 then
return
end
self.clickTime = os.time()
self:reportData("activity_center_share_readbook_report_click", "读课文分享点击", {}, "0")
if not self.shareInfo then
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "未获取到分享信息,请稍后再试" })
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
self:SetViewByShareInfo()
end
end)
return
end
self:ShareReadBook(function(success)
if success then
self:ShareReadBookReport()
self.commonService:StartCoroutine(function()
self.commonService:YieldSeconds(2)
self.shareInfo.reportStatus = 2
self:SetViewByShareInfo()
self.shareButton.interactable = false
end)
else
self.observerService:Fire("ABCZONE_COMMON_TOAST", { content = "分享失败,请稍后再试" })
self.shareButton.interactable = true
end
end)
end)
self:SetViewByShareInfo()
-- 保存原始位置信息
self:SaveOriginalPositions()
end
-- 保存原始位置信息并计算标准宽度
function FsyncElement:SaveOriginalPositions()
if not self.barrage then
return
end
-- 获取名字、内容和头像的Transform
local nameTransform = self.barrage:Find("name")
local contentTransform = self.barrage:Find("text")
local headTransform = self.barrage:Find("head")
-- 保存原始位置
if nameTransform then
local nameRectTransform = nameTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if nameRectTransform then
self.originalNamePosition = nameRectTransform.anchoredPosition
g_Log(TAG, string.format("保存原始名字位置: x=%f, y=%f", self.originalNamePosition.x, self.originalNamePosition.y))
end
end
if contentTransform then
local contentRectTransform = contentTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if contentRectTransform then
self.originalContentPosition = contentRectTransform.anchoredPosition
g_Log(TAG, string.format("保存原始内容位置: x=%f, y=%f", self.originalContentPosition.x, self.originalContentPosition.y))
end
end
if headTransform then
local headRectTransform = headTransform:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRectTransform then
self.originalHeadPosition = headRectTransform.anchoredPosition
g_Log(TAG, string.format("保存原始头像位置: x=%f, y=%f", self.originalHeadPosition.x, self.originalHeadPosition.y))
end
end
-- 计算标准名字宽度(使用6个字符的宽度作为标准)
local standardText = "标准名字宽度" -- 6个字符
local nameTextComponent = nameTransform:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent then
-- 保存当前文本
local originalText = nameTextComponent.text
-- 设置为标准文本
nameTextComponent.text = standardText
-- 等待一帧确保文本更新
self.commonService:StartCoroutine(function()
self.commonService:YieldEndFrame()
-- 获取标准宽度
self.standardNameWidth = nameTextComponent.preferredWidth
g_Log(TAG, string.format("计算标准名字宽度: %f", self.standardNameWidth))
-- 恢复原始文本
nameTextComponent.text = originalText
end)
end
end
-- 更新红色数字图片显示
function FsyncElement:UpdateNumberImage(targetImage, number)
if not targetImage or not self.redImages then
return
end
-- 处理大于9的数字(主要是天数可能大于9)
if number > 9 then
-- 如果是天数,我们只显示个位数,或者可以考虑其他处理方式
-- 这里简单处理为显示9
number = 9
end
-- 确保number在0-9范围内
number = math.max(0, math.min(9, number))
-- 获取目标Image组件
local image = targetImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if not image then
return
end
-- 获取对应数字的red图片
local redImage = self.redImages[number]
if not redImage then
return
end
-- 复制sprite到目标Image
image.sprite = redImage.sprite
end
-- 更新奖励数量显示
function FsyncElement:UpdateAwardNum()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- g_Log(TAG, string.format("更新奖励数量: 查看人数=%d, 奖励值=%d", self.shareInfo.count, awardValue))
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.awardNum0 and self.awardNum0.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum0:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[1]] then
local sourceImage = self["cutDiagram" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum0.gameObject:SetActive(true)
end
if self.awardNum1 and self.awardNum1.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[2]] then
local sourceImage = self["cutDiagram" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum1.gameObject:SetActive(true)
end
if self.awardNum2 and self.awardNum2.gameObject then
-- 使用cutDiagram中的数字图片
local image = self.awardNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagram" .. digits[3]] then
local sourceImage = self["cutDiagram" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.awardNum2.gameObject:SetActive(true)
end
end
-- 显示加号
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(true)
end
end
-- 添加更新最大奖励显示的函数
function FsyncElement:UpdateMaxRewardsDisplay()
if not self.shareInfo or not self.shareInfo.maxRewards then
return
end
-- 获取最大奖励值
local maxRewards = self.shareInfo.maxRewards
-- g_Log(TAG, string.format("更新最大奖励显示: maxRewards=%d", maxRewards))
-- 将最大奖励值转换为字符串,然后分解为个位数
local rewardsStr = tostring(maxRewards)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #rewardsStr do
digits[i] = tonumber(string.sub(rewardsStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
self.rightStartShareNum4.gameObject:SetActive(false)
end
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum4.gameObject:SetActive(true)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum3.gameObject:SetActive(true)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum4:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum4.gameObject:SetActive(true)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.rightStartShareNum5:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.rightStartShareNum5.gameObject:SetActive(true)
end
end
end
function FsyncElement:SetViewByShareInfo()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 隐藏所有UI元素
self:HideAllUIElements()
-- 获取查看人数
local viewCount = self.shareInfo.count
if self.shareInfo.reportStatus == 2 then
-- 初始化并启动弹幕
if self.shareInfo.friends and #self.shareInfo.friends > 0 then
self:InitBarrage()
end
-- 已分享状态
if self.isInCountdown then
-- 倒计时中
if viewCount > 0 then
-- 有人查看
-- g_Log(TAG,"读课文分享新-----有人查看")
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(true)
-- g_Log(TAG,"读课文分享新-----有人查看rightShareSuccessTitle")
end
-- 设置标签为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(true)
-- 更新奖励数量显示
self:UpdateAwardNum()
end
-- 设置底部分享成功模板为显示
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(true)
self.num1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.num2Text.text = self.shareInfo.count*5
else
self.num2Text.text = self.shareInfo.maxRewards
end
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
self:InitCountDown()
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
else
-- 无人查看
-- 设置右侧分享成功标题为显示
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(true)
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部无人查看视图为显示
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(true)
end
-- 设置倒计时为显示
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
self:InitCountDown()
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(true)
end
end
else
-- 倒计时结束
self:GetShareInfo(function(success, shareInfo)
self.shareButton.interactable = true
if success then
self.shareInfo = shareInfo
end
end)
if viewCount > 0 then
-- 有人查看
-- 如果已经领取了奖励,直接显示领取后的UI状态
if self.hasCollectedReward then
-- g_Log(TAG,"读课文分享新-----已领取奖励,显示领取后UI")
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(true)
self:UpdateAwardNum()
end
-- 设置底部结束标题为显示
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(true)
self.bottomEndNum1Text.text = self.shareInfo.count
end
-- 设置获取结束标签为显示
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(true)
end
return
end
-- g_Log(TAG,"读课文分享新-----倒计时结束viewCount=0000000000000")
-- 设置等待领取UI状态
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(true)
end
-- 设置奖励数量为显示
if self.awardNum and self.awardNum.gameObject then
g_Log(TAG,"读课文分享新-----有人查看awardNum")
self.awardNum.gameObject:SetActive(true)
-- 更新奖励数量显示
self:UpdateAwardNum()
end
if self.hasShare and self.hasShare.gameObject then
g_Log(TAG,"读课文分享新-----有人查看hasShare")
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部等待领取标题为显示
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(true)
self.bottomWaitNum1Text.text = self.shareInfo.count
if self.shareInfo.count*5 <= self.shareInfo.maxRewards then
self.bottomWaitNum2Text.text = self.shareInfo.count*5
else
self.bottomWaitNum2Text.text = self.shareInfo.maxRewards
end
end
-- 设置领取按钮为显示
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(true)
-- 更新获取按钮上的数字显示
self:UpdateGetBtnNumbers()
end
else
-- 无人查看
-- 设置结束标签为显示
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(true)
end
-- 设置右侧结束标题为显示
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(true)
end
-- 设置底部结束无人查看视图为显示
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(true)
end
end
end
elseif self.shareInfo.reportStatus == 1 then
-- 未分享状态
-- 设置右侧开始分享标题为显示
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(true)
-- 更新最大奖励显示
self:UpdateMaxRewardsDisplay()
end
-- 设置已分享区域为显示
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(true)
end
-- 设置底部开始分享模板为显示
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(true)
end
-- 设置分享按钮为显示
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(true)
end
elseif self.shareInfo.reportStatus == 0 then
-- 不可分享状态
end
end)
end
function FsyncElement:ClosePanel(needDestroy)
-- 停止弹幕
self.isBarrageRunning = false
if self.readBookPanel and self.readBookPanel.gameObject.activeSelf == true then
self.readBookPanel.gameObject:SetActive(false)
end
if needDestroy and self.readBookPanel then
self:DestroyView()
end
end
-- 隐藏所有UI元素
function FsyncElement:HideAllUIElements()
-- 隐藏右侧标题区域
if self.rightStartShareTitle and self.rightStartShareTitle.gameObject then
self.rightStartShareTitle.gameObject:SetActive(false)
end
if self.rightShareSuccessTitle and self.rightShareSuccessTitle.gameObject then
self.rightShareSuccessTitle.gameObject:SetActive(false)
end
if self.rightWaitCollectTitle and self.rightWaitCollectTitle.gameObject then
self.rightWaitCollectTitle.gameObject:SetActive(false)
end
if self.rightEndTitle and self.rightEndTitle.gameObject then
self.rightEndTitle.gameObject:SetActive(false)
end
-- 隐藏底部区域
if self.bottomStartShareTmp and self.bottomStartShareTmp.gameObject then
self.bottomStartShareTmp.gameObject:SetActive(false)
end
if self.bottomShareSuccessTmp and self.bottomShareSuccessTmp.gameObject then
self.bottomShareSuccessTmp.gameObject:SetActive(false)
end
if self.bottomWaitCollectTitle and self.bottomWaitCollectTitle.gameObject then
self.bottomWaitCollectTitle.gameObject:SetActive(false)
end
if self.bottomEndTitle and self.bottomEndTitle.gameObject then
self.bottomEndTitle.gameObject:SetActive(false)
end
if self.bottomNoView and self.bottomNoView.gameObject then
self.bottomNoView.gameObject:SetActive(false)
end
if self.bottomEndNoView and self.bottomEndNoView.gameObject then
self.bottomEndNoView.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏奖励相关区域
if self.awardNum and self.awardNum.gameObject then
self.awardNum.gameObject:SetActive(false)
end
if self.awardPlus and self.awardPlus.gameObject then
self.awardPlus.gameObject:SetActive(false)
end
if self.awardNum0 and self.awardNum0.gameObject then
self.awardNum0.gameObject:SetActive(false)
end
if self.awardNum1 and self.awardNum1.gameObject then
self.awardNum1.gameObject:SetActive(false)
end
if self.awardNum2 and self.awardNum2.gameObject then
self.awardNum2.gameObject:SetActive(false)
end
-- 隐藏已分享区域
if self.hasShare and self.hasShare.gameObject then
self.hasShare.gameObject:SetActive(false)
end
-- 隐藏倒计时区域
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
if self.endLabel and self.endLabel.gameObject then
self.endLabel.gameObject:SetActive(false)
end
if self.getEndLabel and self.getEndLabel.gameObject then
self.getEndLabel.gameObject:SetActive(false)
end
-- 隐藏按钮区域
if self.getBtn and self.getBtn.gameObject then
self.getBtn.gameObject:SetActive(false)
end
if self.share and self.share.gameObject then
self.share.gameObject:SetActive(false)
end
if self.halfwayShare and self.halfwayShare.gameObject then
self.halfwayShare.gameObject:SetActive(false)
end
-- 隐藏最大奖励数字
if self.rightStartShareNum3 and self.rightStartShareNum3.gameObject then
self.rightStartShareNum3.gameObject:SetActive(false)
end
if self.rightStartShareNum4 and self.rightStartShareNum4.gameObject then
self.rightStartShareNum4.gameObject:SetActive(false)
end
if self.rightStartShareNum5 and self.rightStartShareNum5.gameObject then
self.rightStartShareNum5.gameObject:SetActive(false)
end
-- g_Log(TAG, "已隐藏所有UI元素")
end
function FsyncElement:DestroyView()
-- 清理弹幕资源
self:ClearBarrageItems()
if self.shareButton then
self.shareButton.onClick:RemoveAllListeners()
end
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
-- 清理redImages引用
if self.redImages then
for i = 0, 9 do
self.redImages[i] = nil
end
self.redImages = nil
end
if self.objRoot then
CS.UnityEngine.GameObject.DestroyImmediate(self.objRoot)
self.objRoot = nil
end
self.readBookPanel = nil
self.dialogContentRect = nil
if self.prefab then
ResourceManager:ReleaseObject(self.prefab)
self.prefab = nil
end
self.pageMonitorService:recordPageClose(PageId)
end
function FsyncElement:ShareReadBookReport()
local image = "https://static0.xesimg.com/next-studio-pub/app/1736943865007/zQsexNIiSJTCdgnwr9AZ.png"
self.content = {
title = self.shareInfo.title,
-- contentDesc = self.shareInfo.contentDesc,
url = self.shareInfo.url,
imageType = "network",
image = image,
thumbImageUrl = image,
previewImageUrl = image
}
local param = { type = "WeChatTimeline", contentType = "web", content = self.content }
APIBridge.RequestAsync('app.api.share.shareToNative', param, function(res)
if res then
g_Log(TAG, "分享微信朋友圈,回调--->" .. table.dump(res))
end
end)
end
-- 收到/恢复IRC消息
-- @param key 订阅的消息key
-- @param value 消息集合体
-- @param isResume 是否为恢复消息
function FsyncElement:ReceiveMessage(key, value, isResume)
-- TODO:
end
-- 发送KEY-VALUE 消息
-- @param key 自定义/协议key
-- @param body table 消息体
function FsyncElement:SendCustomMessage(key, body)
self:SendMessage(key,body)
end
-- 自己avatar对象创建完成
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarCreated(avatar)
end
-- 自己avatar对象人物模型加载完成ba
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:SelfAvatarPrefabLoaded(avatar)
end
-- avatar对象创建完成,包含他人和自己
-- @param avatar 对应自己的Fsync_avatar对象
function FsyncElement:AvatarCreated(avatar)
end
------------------------蓝图组件相应方法---------------------------------------------
--是否是异步恢复如果是需要改成true
function FsyncElement:LogicMapIsAsyncRecorver()
return false
end
--开始恢复方法(断线重连的时候用)
function FsyncElement:LogicMapStartRecover()
FsyncElement.super:LogicMapStartRecover()
--TODO
end
--结束恢复方法 (断线重连的时候用)
function FsyncElement:LogicMapEndRecover()
FsyncElement.super:LogicMapEndRecover(self)
--TODO
end
--所有的组件恢复完成
function FsyncElement:LogicMapAllComponentRecoverComplete()
end
--收到Trigger事件
function FsyncElement:OnReceiveTriggerEvent(interfaceId)
end
--收到GetData事件
function FsyncElement:OnReceiveGetDataEvent(interfaceId)
return nil
end
------------------------蓝图组件相应方法End---------------------------------------------
---接口请求
function FsyncElement:ShareReadBook(callback)
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
callback(true)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
---获取分享信息
function FsyncElement:GetShareInfo(callback)
if self.shareInfo and self.requestTime and os.time() - self.requestTime < 30 then
callback(true, self.shareInfo)
return
end
self.requestTime = os.time()
self.domain = "https://app.chuangjing.com/abc-api"
local url = self.domain .. "/v3/article-share/info"
if App.IsStudioClient then
url = "https://yapi.xesv5.com/mock/2041/v3/article-share/info"
end
local params = {
}
local success = function(resp)
if resp and resp ~= "" then
local msg = nil
if type(resp) == "string" then
msg = self.jsonService:decode(resp)
end
if msg and msg.code == 0 then
local data = msg.data
if data and type(data) == "table" then
local shareInfo = {
userId = data.userId,
reportStatus = data.report_status, --2:已分享 1:未分享
bookId = data.book_id,
levelNo = data.level_no,
title = data.title,
-- contentDesc = data.contentDesc,
url = data.url,
maxRewards = data.max_rewards, -- 最大奖励
endTime = data.end_time, -- 剩余时间
count = data.count, -- 查看人数
friends = data.friends -- 好友列表
}
-- 确保maxRewards是数字
if shareInfo.maxRewards and type(shareInfo.maxRewards) == "string" then
shareInfo.maxRewards = tonumber(shareInfo.maxRewards) or 0
elseif not shareInfo.maxRewards then
shareInfo.maxRewards = 0
end
g_Log(TAG, string.format("获取分享信息成功: maxRewards=%d, count=%d", shareInfo.maxRewards, shareInfo.count or 0))
self.shareInfo = shareInfo
callback(true, shareInfo)
end
end
else
callback(false)
end
end
local fail = function(err)
callback(false)
end
self:HttpRequest(url, params, success, fail)
end
function FsyncElement:HttpRequest(url, params, success, fail)
if App.IsStudioClient then
self.httpService:PostForm(url, params, {}, success, fail)
else
APIBridge.RequestAsync('api.httpclient.request', {
["url"] = url,
["headers"] = {
["Content-Type"] = "application/json"
},
["data"] = params
}, function(res)
if res ~= nil and res.responseString ~= nil and res.isSuccessed then
local resp = res.responseString
success(resp)
else
fail(res)
end
end)
end
end
---埋点方法
function FsyncElement:reportData(event, label, value, action)
if not App.IsStudioClient then
NextStudioComponentStatisticsAPI.ComponentStatisticsWithParam(event, "84169", "Special-Interaction", label,
action, value)
end
end
-- 脚本释放
function FsyncElement:Exit()
-- 清理弹幕资源
self:ClearBarrageItems()
-- 取消倒计时定时器
if self.countDownTimerId then
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.countDownTimerId = nil
end
FsyncElement.super.Exit(self)
end
-- 更新获取按钮上的数字显示
function FsyncElement:UpdateGetBtnNumbers()
if not self.shareInfo or not self.shareInfo.count then
return
end
-- 计算奖励值 = 查看人数 * 5
local awardValue = self.shareInfo.count * 5
-- 确保奖励值不超过最大奖励
if self.shareInfo.maxRewards and awardValue > self.shareInfo.maxRewards then
awardValue = self.shareInfo.maxRewards
end
-- g_Log(TAG, string.format("更新获取按钮数字: 奖励值=%d", awardValue))
-- 将奖励值转换为字符串,然后分解为个位数
local awardStr = tostring(awardValue)
local digits = {}
-- 从字符串中提取每一位数字
for i = 1, #awardStr do
digits[i] = tonumber(string.sub(awardStr, i, i))
end
-- 根据位数更新显示
if #digits == 1 then
-- 只有个位数
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
self.getBtnNum2.gameObject:SetActive(false)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 2 then
-- 十位和个位
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
if self.getBtnNum1 and self.getBtnNum1.gameObject then
self.getBtnNum1.gameObject:SetActive(false)
end
elseif #digits == 3 then
-- 百位、十位和个位
if self.getBtnNum1 and self.getBtnNum1.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum1:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[1]] then
local sourceImage = self["cutDiagramSmall" .. digits[1]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum1.gameObject:SetActive(true)
end
if self.getBtnNum2 and self.getBtnNum2.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum2:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[2]] then
local sourceImage = self["cutDiagramSmall" .. digits[2]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum2.gameObject:SetActive(true)
end
if self.getBtnNum3 and self.getBtnNum3.gameObject then
-- 使用cutDiagramSmall中的数字图片
local image = self.getBtnNum3:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and self["cutDiagramSmall" .. digits[3]] then
local sourceImage = self["cutDiagramSmall" .. digits[3]]:GetComponent(typeof(CS.UnityEngine.UI.Image))
if sourceImage then
image.sprite = sourceImage.sprite
end
end
self.getBtnNum3.gameObject:SetActive(true)
end
end
-- 显示钻石图标
if self.getBtnDiamond6 and self.getBtnDiamond6.gameObject then
self.getBtnDiamond6.gameObject:SetActive(true)
end
end
function FsyncElement:InitBarrage()
-- 如果弹幕已经在运行,则不重复初始化
if self.isBarrageRunning then
return
end
-- g_Log(TAG, "初始化弹幕系统")
-- 确保弹幕区域可见
if self.barrageRange and self.barrageRange.gameObject then
self.barrageRange.gameObject:SetActive(true)
else
g_Log(TAG, "弹幕区域不存在,无法初始化弹幕")
return
end
-- 清理之前的弹幕项
self:ClearBarrageItems()
-- 获取弹幕范围区域的RectTransform
local barrageRangeRect = self.barrageRange:GetComponent(typeof(CS.UnityEngine.RectTransform))
if not barrageRangeRect then
g_Log(TAG, "弹幕范围区域没有RectTransform组件")
return
end
-- 获取弹幕范围区域的宽度
local barrageRangeWidth = barrageRangeRect.rect.width
self.barrageRangeWidth = barrageRangeWidth
-- 创建弹幕项
if self.shareInfo and self.shareInfo.friends and #self.shareInfo.friends > 0 then
-- 先计算所有弹幕的宽度
self.commonService:StartCoroutine(function()
-- 创建临时弹幕项来计算宽度
local tempWidths = {}
for i, friend in ipairs(self.shareInfo.friends) do
local width = self:CalculateBarrageWidth(friend)
tempWidths[i] = width
-- g_Log(TAG, string.format("弹幕项 %d (名字: %s) 计算宽度: %f", i, friend.name or "未知", width))
end
-- 创建实际的弹幕项并设置位置
local lastRightEdge = barrageRangeWidth -- 第一个弹幕从屏幕右侧开始
for i, friend in ipairs(self.shareInfo.friends) do
self:CreateBarrageItem(friend, i, lastRightEdge, tempWidths[i])
-- 下一个弹幕的起始位置 = 当前弹幕的右边缘 + 间距
lastRightEdge = lastRightEdge + tempWidths[i] + self.barrageSpacing
end
-- 启动弹幕移动
self:StartBarrageMovement()
end)
else
g_Log(TAG, "没有好友数据,无法创建弹幕")
end
end
-- 计算弹幕宽度
function FsyncElement:CalculateBarrageWidth(friend)
-- 创建临时对象来计算宽度
local tempObj = GameObject.Instantiate(self.barrage.gameObject)
tempObj.transform:SetParent(self.barrageRange)
tempObj.name = "TempBarrageItem"
-- 设置缩放为1,确保计算准确
local rectTransform = tempObj:GetComponent(typeof(CS.UnityEngine.RectTransform))
if rectTransform then
rectTransform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
end
-- 查找并设置昵称
local nameText = tempObj.transform:Find("name")
local nameTextComponent = nil
if nameText then
nameTextComponent = nameText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent and friend and friend.name then
nameTextComponent.text = friend.name
end
end
-- 查找并设置文本内容
local contentText = tempObj.transform:Find("text")
local contentTextComponent = nil
if contentText then
contentTextComponent = contentText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if contentTextComponent then
contentTextComponent.text = "收听了你的报告"
end
end
-- 在协程中等待一帧,确保文本组件已经更新布局
self.commonService:StartCoroutine(function()
self.commonService:YieldEndFrame()
end)
-- 计算名称文本的实际宽度
local nameWidth = 0
if nameTextComponent then
-- 对于TextMeshProUGUI
if nameTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
nameWidth = nameTextComponent.preferredWidth
end
end
-- 计算内容文本的宽度
local contentWidth = 0
if contentTextComponent then
-- 对于TextMeshProUGUI
if contentTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
contentWidth = contentTextComponent.preferredWidth
end
end
-- 获取头像宽度
local headWidth = 0
local headImage = tempObj.transform:Find("head")
if headImage then
local headRect = headImage:GetComponent(typeof(CS.UnityEngine.RectTransform))
if headRect then
headWidth = headRect.rect.width
end
end
-- 销毁临时对象
GameObject.Destroy(tempObj)
-- 计算所需的总宽度(头像 + 名称 + 内容 + 边距)
local padding = 40 -- 左右边距和元素之间的间距
-- 确保标准名字宽度已经计算
if self.standardNameWidth <= 0 then
self.standardNameWidth = 120 -- 默认值
g_Log(TAG, "使用默认标准名字宽度: 120")
end
-- 计算实际宽度与标准宽度的差异
local widthDifference = nameWidth - self.standardNameWidth
-- 根据差异调整总宽度
local totalWidth = headWidth + nameWidth + contentWidth + padding+16
g_Log(TAG, string.format("弹幕项 (名字: %s) 计算宽度: 名字宽度=%f, 标准宽度=%f, 差异=%f, 总宽度=%f",
friend and friend.name or "未知", nameWidth, self.standardNameWidth, widthDifference, totalWidth))
return totalWidth
end
-- 创建弹幕
function FsyncElement:CreateBarrageItem(friend, index, startX, width)
-- 复制模板创建新的弹幕项
local barrageItem = GameObject.Instantiate(self.barrage.gameObject)
-- 将弹幕项设置为barrageRange的子节点,确保在范围内移动
barrageItem.transform:SetParent(self.barrageRange)
barrageItem.name = "BarrageItem_" .. index
-- 获取RectTransform并设置位置
local rectTransform = barrageItem:GetComponent(typeof(CS.UnityEngine.RectTransform))
if not rectTransform then
g_Log(TAG, "弹幕项没有RectTransform组件")
GameObject.Destroy(barrageItem)
return
end
-- 设置缩放为1,确保弹幕项大小正确
rectTransform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
-- 保持原始大小和锚点设置
rectTransform.anchorMin = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform)).anchorMin
rectTransform.anchorMax = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform)).anchorMax
-- 获取原始barrage的RectTransform组件
local barrageRectTransform = self.barrage:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 获取其anchoredPosition.y值
local originalY = barrageRectTransform.anchoredPosition.y
-- 使用原始barrage的Y位置设置弹幕项的位置
rectTransform.anchoredPosition = CS.UnityEngine.Vector2(startX, originalY)
-- 查找并设置头像
local headImage = barrageItem.transform:Find("head")
local headRectTransform = nil
if headImage then
headRectTransform = headImage:GetComponent(typeof(CS.UnityEngine.RectTransform))
local image = headImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
if image and friend.avatar and friend.avatar ~= "" then
-- 加载网络头像
self.httpService:LoadNetWorkTexture(friend.avatar, function(texture)
if image then
image.sprite = texture
end
end, "barrage_" .. index)
else
g_Log(TAG,"读课文分享新-----弹幕头像为空")
end
end
-- 查找并设置昵称
local nameText = barrageItem.transform:Find("name")
local nameTextComponent = nil
local nameRectTransform = nil
if nameText then
nameRectTransform = nameText:GetComponent(typeof(CS.UnityEngine.RectTransform))
-- 设置名字文本的锚点为左居中
if nameRectTransform then
nameRectTransform.anchorMin = CS.UnityEngine.Vector2(0, 0.5)
nameRectTransform.anchorMax = CS.UnityEngine.Vector2(0, 0.5)
nameRectTransform.pivot = CS.UnityEngine.Vector2(0, 0.5)
end
nameTextComponent = nameText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if nameTextComponent and friend.name then
nameTextComponent.text = friend.name
-- 设置文本对齐方式为左对齐
if nameTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
nameTextComponent.alignment = CS.TMPro.TextAlignmentOptions.Left
end
end
end
-- 查找并设置文本内容
local contentText = barrageItem.transform:Find("text")
local contentTextComponent = nil
local contentRectTransform = nil
if contentText then
contentRectTransform = contentText:GetComponent(typeof(CS.UnityEngine.RectTransform))
contentTextComponent = contentText:GetComponent(typeof(CS.TMPro.TextMeshProUGUI))
if contentTextComponent then
contentTextComponent.text = "收听了你的报告"
end
end
-- 在协程中等待一帧,确保文本组件已经更新布局
self.commonService:StartCoroutine(function()
self.commonService:YieldEndFrame()
-- 计算各元素的宽度
local headWidth = 0
if headRectTransform then
headWidth = headRectTransform.rect.width
end
local nameWidth = 0
if nameTextComponent then
if nameTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
nameWidth = nameTextComponent.preferredWidth
end
end
local contentWidth = 0
if contentTextComponent then
if contentTextComponent:GetType() == typeof(CS.TMPro.TextMeshProUGUI) then
contentWidth = contentTextComponent.preferredWidth
end
end
-- 计算所需的总宽度
-- 总宽度 = 左边距(4) + 头像宽度 + 头像与名字间距(8) + 名字宽度 + 名字与内容间距(8) + 内容宽度 + 右边距(16)
local totalWidth = 4 + headWidth + 8 + nameWidth + 8 + contentWidth + 16
-- 设置弹幕项的宽度
local currentSize = rectTransform.sizeDelta
rectTransform.sizeDelta = CS.UnityEngine.Vector2(totalWidth, currentSize.y)
-- 设置头像位置(距离左边缘4像素)
if headRectTransform then
headRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4, headRectTransform.anchoredPosition.y)
end
-- 设置名字位置(头像右侧8像素处)
if nameRectTransform then
nameRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4 + headWidth + 8, nameRectTransform.anchoredPosition.y)
end
-- 设置内容文本位置(名字右侧8像素处)
if contentRectTransform then
contentRectTransform.anchoredPosition = CS.UnityEngine.Vector2(4 + headWidth + 8 + nameWidth + 8, contentRectTransform.anchoredPosition.y)
end
g_Log(TAG, string.format("设置弹幕: name=%s, 头像宽度=%f, 名字宽度=%f, 内容宽度=%f, 总宽度=%f",
friend.name or "未知", headWidth, nameWidth, contentWidth, totalWidth))
-- 更新记录的宽度
for i, item in ipairs(self.barrageItems) do
if item.gameObject == barrageItem then
item.width = totalWidth
break
end
end
end)
-- 激活弹幕项
barrageItem:SetActive(true)
-- 将弹幕项添加到列表中
table.insert(self.barrageItems, {
gameObject = barrageItem,
rectTransform = rectTransform,
index = index,
userId = friend.user_id,
width = width or 0 -- 记录弹幕宽度,稍后会在协程中更新
})
end
-- 修改StartBarrageMovement函数
function FsyncElement:StartBarrageMovement()
if #self.barrageItems == 0 then
g_Log(TAG, "没有弹幕项,无法启动弹幕移动")
return
end
self.isBarrageRunning = true
-- 启动协程来移动弹幕
self.barrageCoroutine = self:StartCoroutine(function()
while self.isBarrageRunning do
-- 移动每个弹幕项
for _, item in ipairs(self.barrageItems) do
if item.gameObject and item.rectTransform then
-- 获取当前位置
local pos = item.rectTransform.anchoredPosition
-- 计算新位置(向左移动)
local newX = pos.x - self.barrageSpeed * Time.deltaTime
if newX < -self.barrageRangeWidth/2 then
-- 找到当前最右侧的弹幕
local rightmostX = -math.huge
local rightmostItem = nil
for _, otherItem in ipairs(self.barrageItems) do
if otherItem.rectTransform and otherItem.rectTransform.anchoredPosition.x > rightmostX then
rightmostX = otherItem.rectTransform.anchoredPosition.x
rightmostItem = otherItem
end
end
-- 将当前弹幕放置在最右侧弹幕之后
if rightmostItem then
-- 新位置 = 最右侧弹幕的位置 + 最右侧弹幕的宽度 + 间距
newX = rightmostX + rightmostItem.width + self.barrageSpacing
else
-- 如果没有找到最右侧弹幕,则从屏幕右侧重新开始
newX = self.barrageRangeWidth
end
g_Log(TAG, string.format("弹幕重置位置: index=%d, newX=%f", item.index, newX))
end
-- 更新位置
item.rectTransform.anchoredPosition = CS.UnityEngine.Vector2(newX, pos.y)
end
end
-- 等待下一帧
self:YieldEndFrame()
end
end)
end
function FsyncElement:InitCountDown()
self.commonService:StartCoroutine(function()
self.commonService:Yield(self.commonService:WaitUntil(function()
return self.shareInfo
end))
-- 解析接口返回的endTime字段,格式如:"2天23小时59分"
local days, hours, minutes = 0, 0, 0
if self.shareInfo.endTime and self.shareInfo.endTime ~= "" then
local endTimeStr = self.shareInfo.endTime
-- 解析天数
local daysStr = string.match(endTimeStr, "(%d+)天")
if daysStr then
days = tonumber(daysStr) or 0
end
-- 解析小时
local hoursStr = string.match(endTimeStr, "(%d+)小时") or string.match(endTimeStr, "(%d+)时")
if hoursStr then
hours = tonumber(hoursStr) or 0
end
-- 解析分钟
local minutesStr = string.match(endTimeStr, "(%d+)分")
if minutesStr then
minutes = tonumber(minutesStr) or 0
end
g_Log(TAG, string.format("解析倒计时: %d天%02d时%02d分", days, hours, minutes))
else
g_Log(TAG, "倒计时字符串为空或不存在")
end
-- 预加载red0~red9图片
self.redImages = {}
for i = 0, 9 do
-- 假设red0~red9图片已经在CutDiagram节点下
local redImage = self.cutDiagram:Find("red" .. i)
if redImage then
self.redImages[i] = redImage:GetComponent(typeof(CS.UnityEngine.UI.Image))
end
end
-- 更新倒计时显示,显示的分钟数比实际剩余时间多一分钟
local function updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 调整显示的分钟数,如果秒数大于0,则分钟数+1
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
-- 处理进位
if displayMinutes == 60 then
displayMinutes = 0
remainHours = remainHours + 1
if remainHours == 24 then
remainHours = 0
remainDays = remainDays + 1
end
end
end
-- 更新天数显示
self:UpdateNumberImage(self.daynum, remainDays)
-- 更新小时显示(两位数)
local hourTens = math.floor(remainHours / 10)
local hourOnes = remainHours % 10
self:UpdateNumberImage(self.hournum0, hourTens)
self:UpdateNumberImage(self.hournum1, hourOnes)
-- 更新分钟显示(两位数)
local minuteTens = math.floor(displayMinutes / 10)
local minuteOnes = displayMinutes % 10
self:UpdateNumberImage(self.minutenum0, minuteTens)
self:UpdateNumberImage(self.minutenum1, minuteOnes)
-- 记录日志
g_Log(TAG, string.format("倒计时更新: 实际剩余时间=%d天%02d小时%02d分%02d秒, 显示=%d天%02d小时%02d分",
remainDays, remainHours, remainMinutes, remainSeconds, remainDays, remainHours, displayMinutes))
end
-- 倒计时结束时更新UI状态
local function onCountdownFinished()
g_Log(TAG, "倒计时结束,更新UI状态")
-- 隐藏倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 更新UI显示
self:SetViewByShareInfo()
end
-- 计算总秒数
local totalSeconds = days * 86400 + hours * 3600 + minutes * 60
local endTime = os.time() + totalSeconds
-- 立即检查是否应该显示倒计时
if totalSeconds > 0 and self.shareInfo.reportStatus == 2 and self.isInCountdown then
g_Log(TAG,"读课文分享新-----倒计时开始显示倒计时UI1111111111111"..totalSeconds)
-- 显示倒计时UI
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(true)
g_Log(TAG,"读课文分享新-----显示倒计时UI0000000000000")
end
-- 注册全局定时器,每秒更新一次倒计时(改为每秒更新以获得更流畅的体验)
self.countDownTimerId = self.commonService:RegisterGlobalTimer(1, function()
local now = os.time()
local diff = endTime - now
if diff <= 0 then
-- 倒计时结束
g_Log(TAG,"读课文分享新-----倒计时结束注销定时器3333333333333")
self.commonService:UnregisterGlobalTimer(self.countDownTimerId)
self.isInCountdown=false
onCountdownFinished()
return
end
local remainDays = math.floor(diff / 86400)
local remainHours = math.floor((diff % 86400) / 3600)
local remainMinutes = math.floor((diff % 3600) / 60)
local remainSeconds = diff % 60
-- 只有当秒数为0或者分钟或更高单位变化时才更新UI显示
-- 或者当秒数变化导致显示的分钟数变化时也更新UI
local displayMinutes = remainMinutes
if remainSeconds > 0 then
displayMinutes = remainMinutes + 1
end
if remainSeconds == 0 or (not self.lastRemainingMinutes) or self.lastRemainingMinutes ~= remainMinutes or
(not self.lastRemainingHours) or self.lastRemainingHours ~= remainHours or
(not self.lastRemainingDays) or self.lastRemainingDays ~= remainDays or
(not self.lastDisplayMinutes) or self.lastDisplayMinutes ~= displayMinutes then
-- 更新UI显示
updateCountdownDisplay(remainDays, remainHours, remainMinutes, remainSeconds)
-- 记录当前时间,用于下次比较
self.lastRemainingMinutes = remainMinutes
self.lastRemainingHours = remainHours
self.lastRemainingDays = remainDays
self.lastDisplayMinutes = displayMinutes
end
end, true)
else
-- 不需要显示倒计时,确保倒计时UI被隐藏
if self.countDown and self.countDown.gameObject then
self.countDown.gameObject:SetActive(false)
end
-- 如果不是倒计时状态,可能是已经结束或者未开始
if self.shareInfo.reportStatus == 2 then
-- 已分享状态但不在倒计时中,说明倒计时已结束
onCountdownFinished()
end
end
end)
end
-- 清除弹幕
function FsyncElement:ClearBarrageItems()
-- 停止弹幕移动
self.isBarrageRunning = false
-- 停止弹幕协程
if self.barrageCoroutine then
self:StopCoroutineSafely(self.barrageCoroutine)
self.barrageCoroutine = nil
end
-- 销毁所有弹幕项
for _, item in ipairs(self.barrageItems) do
if item.gameObject then
GameObject.Destroy(item.gameObject)
end
end
-- 清空弹幕项列表
self.barrageItems = {}
-- 释放网络图片资源
for i = 1, 100 do -- 假设最多100个弹幕项
self.httpService:ReleaseTextureWithBusinessId("barrage_" .. i)
end
end
return FsyncElement