从网上看到,很多关于lua队列的,但是都没有具体的使用方式,有空将自己做的贴出来,希望大家能指点一二。
栈和队列概念理解:
**相同点:**从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同。
**不同点:**栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。 队列(Queue)是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。它们是完全不同的数据类型。除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的"限定"。
**栈:**必须按==“后进先出”==的规则进行操作:举个例子比较容易理解,老师批改试卷,(不考虑打乱顺序),老师批改的试卷,就会从最后交试卷的那个同学开始批改,试卷看作是一个栈中的元素,那么最后一个同学交的试卷就是栈顶元素,而第一个同学交的,也就是最低端的作业本,就是栈底元素,这就是对栈的读取规则。
**队列:**按照==“先进先出”==的规则进行操作:举个例子,排队取钱,(就别说插队这种可能啦~~遵守道德规范人人有责~),排在前面的人一定会先取到钱,然后最先离开银行,一个接一个顺序执行,这些等候服务的人看作是队的元素,第一个人就是对头元素,相应的,最后一个人就是队尾元素。这是队的读取规则。
以下是lua队列的数据结构:
LuaQueue = class("LuaQueue")
LuaQueue.CAPACITY_INFINITE = 0
LuaQueue._dataList = nil
LuaQueue._dataCapacity = nil
function LuaQueue:ctor(capacity)
self._dataCapacity = capacity or LuaQueue.CAPACITY_INFINITE
self._dataList = {}
end
--将数据存入表里
function LuaQueue:push(data)
if self:isFull() then
self:pop()
end
self._dataList[#self._dataList+1] = data
end
--取出数据
function LuaQueue:pop()
if self:isEmpty() then
return
end
local data = table.remove(self._dataList, 1)
return data
end
--获得队列里面的长度
function LuaQueue:size()
return #self._dataList
end
function LuaQueue:setCapacity(capacity)
if not capacity or capacity < LuaQueue.CAPACITY_INFINITE then
return
end
if capacity > LuaQueue.CAPACITY_INFINITE and capacity < self:size() then
local num = self:size() - capacity
for i=1,num do
self:pop()
end
end
self._dataCapacity = capacity
end
function LuaQueue:capacity()
return self._dataCapacity
end
function LuaQueue:isEmpty()
return self:size() == 0
end
function LuaQueue:isFull()
if self:capacity() == LuaQueue.CAPACITY_INFINITE then
return false
end
return self:capacity() == self:size()
end
function LuaQueue:clear()
self._dataList = {}
end
队列的使用
下面是做一个短信通知动作,如下图:如有多条短信一起下发 需要一条一条完成动画,大概需求就是跟微信消息提醒差不多了,有消息时,从顶部菜单栏位置出现,过了3秒上滑自动消失,也可以手动让短信UI上滑消失
为了以后方便 ,封装一下
SmsAlert = class("SmsAlert")
function SmsAlert:ctor()
self:init()
end
function Alert:init()
end
require "LuaQueue"
require("SmsData")
local ALERT_WORLD_LIMIT_NUM = 15 –-设置队列数据的长度
local _worldMsgQueue = LuaQueue:create(ALERT_WORLD_LIMIT_NUM)
local _isShowAlertWorld = false
local _alertWorldItem = nil
local isHide = false
local _smsAlertList = {}
local _smsItemList = {}
function SmsAlert:showWorld(data)
_worldMsgQueue:push(data)
SmsAlert:showNextWorld(data)
end
function SmsAlert:showNextWorld(data)
–-当前有短信正在显示动作的时候 先return
--但是数据还存在队列里面
if _isShowAlertWorld then
return
end
_isShowAlertWorld = true
isHide = false
local msg = _worldMsgQueue:pop()
if not msg then return end
--创建短信通知节点
local layer = GameLayerManager:getInstance():getLayerByType(GameLayerTypes.SMS)—-创建一个渲染层级比较高的节点 这样就不会被游戏内其他UI挡住
local item = SmsAlert:getSmsItem()
layer:addChild(item)
table.insert( _smsAlertList, 1, item)
item:showMsg(msg, CallbackData:create(function()
_isShowAlertWorld = false
SmsAlert:showNextWorld()
end))
item:setClickCallBack(function()
if item then
--print("移除短信提醒节点!!!!!!!!")
isHide = true
SmsAlert:giveSmsItem(item)
end
--_worldMsgQueue:clear()
_isShowAlertWorld = false
SmsAlert:showNextWorld()
end)
item.imgBg:setVisible(not isHide)
item:setVisible(not isHide)
item:setImgClickCallBack(function()
if item then
--item.imgBg:setVisible(true)
SmsAlert:giveSmsItem(item)
isHide = false
end
end)
SmsAlert:handleComm()
end
function SmsAlert:handleComm()
local num = #_smsAlertList
--移除多余的
for i = num,ALERT_WORLD_LIMIT_NUM+1,-1 do
SmsAlert:giveSmsItem(_smsAlertList[i])
_smsAlertList[i] = nil
end
--显示已有短信的动画
num = #_smsAlertList
local item
for i=2,num do
item = _smsAlertList[i]
item:SetAction()
end
item = _smsAlertList[1]
item:setPosition(375, 1270)
Utils.alignMidTop(item)
item:SetAction()
local delayAction = cc.DelayTime:create(3)
local callAction = cc.CallFunc:create(function()
item:closeAction()
end)
local hideAction = cc.Sequence:create(delayAction, callAction)
hideAction:setTag(10001)
item:runAction(hideAction)
end
function SmsAlert:getSmsItem()
local item = _smsItemList[#_smsItemList]
if not item then
item = SmsAlertItem:create()
else
_smsItemList[#_smsItemList] = nil
end
return item
end
function SmsAlert:giveSmsItem(item)
_smsItemList[#_smsItemList + 1] = item
--item:stopAllActions()
if item:getReferenceCount() <= 2 then
item:retain()
end
item:removeFromParent()
end
下面是自己短信UI了 自定义
其实UI方面比较简单就不贴出来了,上滑让UI隐藏的比较简单,使用触摸事件做的:
display.setClickEventByType(self.imgBg,function(sender,eventType)
if eventType == ccui.TouchEventType.began then
sender.isDragging = false
self.isDrag = false
--开始触摸
elseif eventType == ccui.TouchEventType.moved then
local pos = sender:getTouchBeganPosition()
local pos2 = sender:getTouchMovePosition()
--移动触摸
--判断鼠标移动两点之间的距离
if Utils.getDistance(sender:getTouchBeganPosition(),sender:getTouchMovePosition()) > 7 then
sender.isDragging = true
self.isDrag = true
self:closeAction(self.imgBg)
end
elseif eventType == ccui.TouchEventType.ended or eventType == ccui.TouchEventType.canceled then
--触摸结束
if not sender.isDragging then
WindowManager:getInstance():open(WindowNames.SmsChatView,self.data)
SmsManager:getInstance():reqAllSmsInfo()
if self._callback then
self._callback()
end
end
end
end,{isBCE=true})
动作就是使用cocos 2dx 自带的动作函数就可以完成了,整体大概就是这样的,不知道哪里有不足之处,还请各位大神不吝赐教,感谢感谢。