Cocos2d-X lua 学习笔记之消息弹窗

本文详细介绍了如何在游戏开发中实现消息提示弹窗的动态显示与管理,包括弹窗的创建、配置、显示逻辑、以及如何在特定时间后渐隐消失,同时当有新消息时原有弹窗的上移与渐隐处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现游戏中需要在屏幕底部弹出消息提示弹窗,经过特定时间后渐隐消失。当有新的消息提示时,原来没有消失的弹窗会上移,并继续渐隐直至消失。

转载声明:http://blog.youkuaiyun.com/operhero1990/article/details/47165365

1、使用cocostudio建立一个最简单的弹窗界面,命名为hintFrame


设置黑底的透明度为100/255,这样能起到一个蒙版的效果。两个Label分别显示消息题目和内容。

2、创建控制弹窗的lua类脚本,命名为UI_hintFrame


local SPACING = 5

--init
function UI_hintFrame:init()
	-- data
	-- ===============================

	-- ui
	-- ===============================
	self.wigetRoot = ccs.GUIReader:getInstance():widgetFromJsonFile(config.dirUI.root .. "hintFrame.json")
	self.content = self.wigetRoot:getChildByName("Panel_4")

	-- addCCNode
	-- ===============================

	-- hp.uiHelper.uiAdaption(self.wigetRoot)
	self.x, self.y = self.wigetRoot:getPosition()
	-- 适应屏幕高度
	self.y = self.y * hp.uiHelper.RA_scaleY
	local back_ = self.wigetRoot:getChildByName("Panel_2")

	self.component = {}
	for i = 1, 9 do
		self.component[i] = back_:getChildByName(tostring(i))
	end	

	for i, v in ipairs(widgetName) do
		self.component[i + 9] = self.content:getChildByName(v)
	end
	self.labelSize = self.component[13]:getSize()
	local size_ = self.component[10]:getSize()
	self.noImageSize = {height=self.labelSize.height, width=self.labelSize.width + size_.width}

	self.opacity = {}
	for i, v in ipairs(self.component) do
		self.opacity[i] = v:getOpacity()
	end

	self:addCCNode(self.wigetRoot)
end

function UI_hintFrame:setInfo(param_)
	-- 初始化显示内容
end

function UI_hintFrame:pop(callBack_)
	cclog_("popHintFrame")
	local x_, y_ = self.wigetRoot:getPosition()

	local trigOver_ = false
	-- call back
	local function onActionOver()
		if trigOver_ == true then
			cclog_("not possible")
			return
		end
		trigOver_ = true
		self.wigetRoot:setVisible(false)
		self.wigetRoot:stopAllActions()
		for i, v in ipairs(self.component) do
			v:stopAllActions()
		end
		if callBack_ ~= nil then
			callBack_()
		end
	end

	local function playerAnimation()
		local delay_ = cc.DelayTime:create(2)
		local fadeOut_ = cc.FadeOut:create(1)
		for i, v in ipairs(self.component) do
			v:runAction(cc.Sequence:create(delay_:clone(), fadeOut_:clone(), cc.CallFunc:create(onActionOver)))
		end
	end

	self.wigetRoot:setVisible(true)
	-- 透明度还原
	for i, v in ipairs(self.component) do
		v:setOpacity(self.opacity[i])
	end
	-- 位置还原
	self.wigetRoot:setPosition(self.x, self.y)
	playerAnimation()
end

function UI_hintFrame:moveUp(pos_)
	local x_, y_ = self.wigetRoot:getPosition()
	local sz_ = self.wigetRoot:getSize()
	local newY_ = sz_.height + SPACING + y_
	self.wigetRoot:runAction(cc.MoveTo:create(1, cc.p(x_, newY_)))
end




3、创建弹窗管理脚本,命名为hintFrameMgr.lua

local hintFrameMgr = {}
local index = 1

-- 本地数据
-- ==================
hintFrameMgr.hintFrameInfoList = {}  --新的弹窗需求会先储存在此
hintFrameMgr.popedHintFrame = {}     --存储需要上移的弹窗
hintFrameMgr.hintFrames = {}         --存储可用于显示的弹窗实体

local function popNextHintFrame()
	while hintFrameMgr.hintFrameInfoList[1] ~= nil do
		if table.getn(hintFrameMgr.hintFrames) > 0 then
			local function popHintFrameOver()
				table.insert(hintFrameMgr.hintFrames, hintFrameMgr.popedHintFrame[1])
				table.remove(hintFrameMgr.popedHintFrame, 1)
				popNextHintFrame()
			end			
			local ui_ = hintFrameMgr.hintFrames[1]			
			if ui_:setInfo(hintFrameMgr.hintFrameInfoList[1]) then
				for i, v in ipairs(hintFrameMgr.popedHintFrame) do  --第二个弹窗需求出现时,第一个才做上移操作
					v:moveUp(pos_)
				end
				ui_:pop(popHintFrameOver)
				table.insert(hintFrameMgr.popedHintFrame, ui_)
				table.remove(hintFrameMgr.hintFrames, 1)
			end
			table.remove(hintFrameMgr.hintFrameInfoList, 1)
		else
			break
		end		
	end	
end

-- 全局方法
-- ==================
function hintFrameMgr.popHintFrame(param_)  --提交新的弹窗需求
	table.insert(hintFrameMgr.hintFrameInfoList, param_)
	popNextHintFrame()
end

function hintFrameMgr.attachHintFrame(uis_)  --初始化弹窗实例
	hintFrameMgr.hintFrames = uis_
	hintFrameMgr.popedHintFrame = {}
end

function hintFrameMgr.detachHintFrame()
end

return hintFrameMgr

3、在scene中调用UI_hintFrame和hintFrameMgr类,进行初始化

	local HINT_MAX_FRAMES = 3  --一次显示最多弹窗数

	self.hintFrames = {}
	for i = 1, HINT_MAX_FRAMES do
		local ui_ = UI_hintFrame.new()  
		self:addMsgUI(ui_.layer)
		self.hintFrames[i] = ui_
	end
	self.hintFrameMgr = require("obj/hintFrameMgr")
	self.hintFrameMgr.attachHintFrame(self.hintFrames) --调用hintFrameMgr初始化HINT_MAX_FRAMES个弹窗实例


4、在scene中提交弹窗需求

hintFrameMgr.popHintFrame(param_)

5、代码逻辑

UI_hintFrame:读取hintFrame.json,获得UI实体。并实现上移和渐隐方法

hintFrameMgr:提供方法attachHintFrame将UI实体存储在hintFrames表中。每次有新的弹窗需求,会从hintFrames提取一个实体并初始化显示信息

      提供方法popHintFrame接收新的弹窗需求,并调用私有方法popNextHintFrame来实现多个弹窗显示逻辑:

1、新的弹窗需求先存储在hintFrameInfoList中。

2、从hintFrameInfoList提取一个需求,从hintFrames取出一个实例并初始化显示。

3、执行渐隐效果。

4、压入popedHintFrame中。

由于第一个弹窗不需要移动,所以没有调用上移方法。当有新的弹窗需求到来时,重复步骤1~3,执行popedHintFrame弹窗的上移方法,最后执行步骤4。这样整个显示逻辑就完整了


6、显示效果展示




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值