scv.lua [Old]

local scroll = {}
local MARGIN_UP = 0
local MARGIN_LEFT = 0
local MARGIN_V_BETWEEN = 0
local MARGIN_H_BETWEEN
local NUM_PER_ROW
local THRESHOLD -- 与self['node' .. iHead]相对Container的高度差阈值
local NODE_IHEAD_POS --inner的子节点位置高度 ,每次inner height 有变化都要更新


--[[
    marginV: item间垂直间距,默认为 0
    marginUp: 上下空白长度, 默认为 0
    marginLeft: 左右空白长度,默认为 0
]]
function scroll:set_margin(marginV, marginUp, marginLeft) --如果不调set_margin将使用上次的margin,整个游戏第一次调用前为上面的值
    print("set_margin  enter")
    MARGIN_V_BETWEEN = marginV or 0 
    MARGIN_UP = marginUp or 0
    MARGIN_LEFT = marginLeft or 0
end




--[[
    modName: 模块名
    refScv: scroll view
    refItem: item,要能克隆 item:clone() ,和获得item大小 item:getContentSize()
    refData: 数据table, 用 #refData可获取长度
    numPerRow: 每行item个数 ,默认为 1
    startRow: 希望从第几行开始显示, 默认为 1 ,程序会根据情况调整至合理位置
]]
function scroll:create( modName, refScv, refItem, refData, numPerRow, startRow)--一个页面中打开一个标签使用一次,上次的scv作废,但下面有方法还原状态
    print("create  enter  ")
    if self.iHead then
        self:onExit() --主要为释放上一次的资源
    end
    self.modName = modName
    self.scv = refScv
    self.inner= self.scv:getInnerContainer()
    self.item = refItem
    self.item:ignoreAnchorPointForPosition(false)
    self.item:setAnchorPoint(0, 0)
    self.item:retain()
    self.data = refData
    self.item_width = self.item:getContentSize().width
    self.item_height = self.item:getContentSize().height
    self.scv_width = self.scv:getContentSize().width
    self.scv_height = self.scv:getContentSize().height
    self.scv:setInnerContainerSize(cc.size(self.scv_width, self.scv_height)) --这个很重要,否则inner会有偏移(受上次位置影响)
    NUM_PER_ROW = numPerRow or 1
    MARGIN_H_BETWEEN = 0
    if NUM_PER_ROW ~= 1 then
        MARGIN_H_BETWEEN = (self.scv_width - 2 * MARGIN_LEFT - NUM_PER_ROW * self.item_width) / (NUM_PER_ROW - 1)
        MARGIN_H_BETWEEN = math.max(0, MARGIN_H_BETWEEN)
    end
    THRESHOLD = self.scv_height + (self.item_height + MARGIN_V_BETWEEN) / 2 + self.item_height
    self.iHead = startRow or 1
    self:set_new_iHead_iTail() --首尾行需修正(首行为self.iHead,尾行为self.iTail)
    self.pre_iHead = self.iHead
    
    self:reuse_pre_rows()   --这个函数有复用,删除,新增综合功能
    self:head_tail_head_tail()
    
    self.delY = 0   -- monitor()内会率先用到
    local function monitor()
        self:monitor()
    end
    self.handle = cc.Director:getInstance():getScheduler():scheduleScriptFunc(monitor, 0, false)
    
    local function onTouchBegan(touch, event)
        self.delY = 0
        return true
    end
    local function onTouchMoved(touch, event)
        self.delY = touch:getLocation().y - touch:getPreviousLocation().y
    end
    local function onTouchEnded(touch, event) 
--        if self.delY == 0 then
--            if self.item_touch_enabled and self.iTail ~= 0 then --不为空
--                local touchX = touch:getLocation().x
--                local touchY = touch:getLocation().y
--                local item_i = self:get_the_item_touched(touchX,touchY)
--                if item_i then
--                    _G[modName].getInstance():touch_an_item(self['item' .. item_i], item_i) -- item, i
--                end
--            end
--        end
    end


    self.listener1 = cc.EventListenerTouchOneByOne:create()
    self.listener1:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
    self.listener1:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
    self.listener1:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
    cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(self.listener1, -1)
end


function scroll:jump_to( i) -- jump to i'th row
    self.pre_iHead = self.iHead
    self.iHead = i
    self:reuse_pre_rows()
    self:head_tail_head_tail()
    if self.max_row - i + 1 < self.visible_rows then -- 为了能完全显示最后一个item
        self.inner:setPosition(0, 0)
    end
end


function scroll:refresh() --外部刷新
    print("refresh  enter")   
    self.pre_iHead = self.iHead
    self.pre_iTail = self.iTail
    self.pre_max_row = self.max_row   
    self.pre_innerY = self.inner:getPositionY()
    self:reuse_pre_rows()
    self:tail_tail_head_head()
    if self.pre_max_row >= self.max_row then --行数减少或不变
        if self.iTail == self.pre_iTail then
            self.inner:setPosition(0, self.pre_innerY)
        else
            self.inner:setPosition(0, 0)
        end
    else            --行数增多
        if self.iTail == self.pre_iTail then
            self.inner:setPosition(0, self.pre_innerY)
        else
            local pre_height = 2 * MARGIN_UP + (self.pre_iTail - self.pre_iHead + 1) * (self.item_height + MARGIN_V_BETWEEN) - MARGIN_V_BETWEEN
            pre_height = math.max(self.scv_height, pre_height)
            local pre_y = self.scv_height - pre_height
            local del_y = self.pre_innerY - pre_y 
            local height = 2 * MARGIN_UP + (self.iTail - self.iHead + 1) * (self.item_height + MARGIN_V_BETWEEN) - MARGIN_V_BETWEEN
            height = math.max(self.scv_height, height)
            local y = self.scv_height - height
            self.inner:setPosition(0, y + del_y)
        end
    end
end


--function scroll:register_item_touch()
--    self.item_touch_enabled = true
--end
--
--function scroll:unregister_item_touch()
--    self.item_touch_enabled = false
--end


function scroll:get_current_state()  --离开标签时获取信息 “info”
    local innerY = self.inner:getPositionY() --有两种情况要调整位置
    if self.iHead == 1 then
        if innerY < self.scv_height - (NODE_IHEAD_POS + MARGIN_UP) then
            innerY = self.scv_height - (NODE_IHEAD_POS + MARGIN_UP)
        end
    end
    if self.iTail == #self.data then
        if innerY > 0 then
            innerY = 0
        end
    end
    return {self.iHead, self.iTail, innerY}
end


function scroll:set_current_state(state) --再次回到标签,先调用set_margin, create,再用参数“info”调
    self.pre_iHead = self.iHead  -- 考虑到之前的标签会有items个数变化
    self.iHead = state[1]
    self:reuse_pre_rows()
    self:tail_tail_head_head()
    if self.iTail - self.iHead == state[2] - state[1] and self.iHead == state[1] then
        self.inner:setPosition(0, state[3])
    else
        self.inner:setPosition(0, 0)
    end
end


function scroll:onExit() --前端关闭页面前一定要调用,页面中不用手动调用
    print("onExit enter")
    if self.handle then
        cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.handle)
        self.handle = nil
    end
    if self.listener1 then
        cc.Director:getInstance():getEventDispatcher():removeEventListener(self.listener1)
        self.listener1 = nil
    end
    if self.item then
        self.item:release()
        self.item = nil
    end
    local j =self.iHead
    if self['node' .. j] then
        self['node' .. j]:removeFromParent()
    end
    while self['node' .. j] do  --虽然上面已经释放,但是self内相关引用值不为nil,需赋为nil
        self['node' .. j]:release()
        self['node' .. j] = nil
        for k = 1, NUM_PER_ROW do
            local index = (j - 1) * NUM_PER_ROW + k
            self['item' .. index] =nil
        end
        j = j + 1
    end
    self.iHead = nil
end


----------------------------------------------------------------------------
------------------------------以上函数外部可调用-----------------------------
----------------------------------------------------------------------------


function scroll:get_the_item_touched(x, y) --注意前提:缩放均为 100% ,scv的父源点和世界源点重合
    local scv_x = self.scv:getPositionX()
    local scv_y = self.scv:getPositionY()
    local inner_x = self.inner:getPositionX()
    local inner_y = self.inner:getPositionY()
    local head_x = self['node' .. self.iHead]:getPositionX()
    local head_y = self['node' .. self.iHead]:getPositionY()
    x = x - scv_x
    y = y - scv_y
    x = x - inner_x
    y = y - inner_y
    x = x - head_x
    y = y - head_y
    x = x * -1
    y = y * -1
    x = x - (MARGIN_LEFT - MARGIN_H_BETWEEN / 2)
    y = y + MARGIN_V_BETWEEN / 2
    local num_x = math.ceil(x / (self.item_width + MARGIN_H_BETWEEN))
    local num_y = math.ceil(y / (self.item_height + MARGIN_V_BETWEEN))
    if num_x < 1 or num_x > NUM_PER_ROW then
        return false
    end
    if num_y < 1 or self.iHead + num_y - 1 > self.max_row then
        return false
    end
    local item_i = (self.iHead + num_y - 1 - 1) * NUM_PER_ROW + num_x
    if item_i > #self.data then
        return false
    end
    return item_i
end


function scroll:show_a_row( i) -- i'th row
    print("show_a_row enter  " .. i)
    for j = 1, NUM_PER_ROW do
        local index = (i - 1)*NUM_PER_ROW + j
        if index > #self.data then
            if not self['item' .. index] then
                self['item' .. index] = self.item:clone()
                self['item' .. index]:setPosition(MARGIN_LEFT + (self.item_width + MARGIN_H_BETWEEN) * (j - 1), -self.item_height)
                self['node' .. i]:addChild(self['item' .. index])
            end
            self['item' .. index]:setVisible(false)
        else
            if not self['item' .. index] then
                self['item' .. index] = self.item:clone()
                self['item' .. index]:setPosition(MARGIN_LEFT + (self.item_width + MARGIN_H_BETWEEN) * (j - 1), -self.item_height)
                self['node' .. i]:addChild(self['item' .. index])
            else
                if not self['item' .. index]:isVisible() then
                    self['item' .. index]:setVisible(true)
                end
            end
            
            self:set_an_item(self['item' .. index], index) 
        end
    end
end


function scroll:set_an_item( item, i)
    _G[self.modName].getInstance():set_an_item(item, i) 
end




function scroll:reuse_pre_rows()  -- 包括复用已有的行资源和删除多余资源和创建新资源
    local j = self.pre_iHead  -- the previous index of head row
    while self['node' .. j] do -- 必须重命名,不然会错,比如从第1行(1,2,3)跳转至第2行(2,3,4),这样1,2,3 和 2,3,4有交错 
        for k = 1, NUM_PER_ROW do
            local index = (j - 1) * NUM_PER_ROW + k
            self['item_pre' .. index] = self['item' .. index]
            self['item' .. index] = nil
        end
        self['node_pre' .. j] = self['node' .. j]
        self['node' .. j] = nil
        j = j + 1
    end
    j = self.pre_iHead  -- the previous index of head row
    self:set_new_iHead_iTail()
    local height = 2 * MARGIN_UP + (self.iTail - self.iHead + 1) * (self.item_height + MARGIN_V_BETWEEN) - MARGIN_V_BETWEEN --现在所需的inner高度
    height = math.max(self.scv_height, height)
    self.scv:setInnerContainerSize(cc.size(self.scv_width, height))   
    NODE_IHEAD_POS =  height - MARGIN_UP -- 头节点的位置(相对于inner) ,其余node(i)的父节点是其上面的节点node(i - 1)
    local i = self.iHead  -- the current index of head row
    local father
    while i <= self.iTail do  
        if j == self.pre_iHead then
            if not self['node_pre' .. j] then
                self['node_pre' .. j] = cc.Node:create()
                self['node_pre' .. j]:retain() --如果不retain,后面调用removeFromParent会报错
                self.inner:addChild(self['node_pre' .. j])
            end
            self['node_pre' .. j]:setPosition(0, NODE_IHEAD_POS)
        else  
            if not self['node_pre' .. j] then
                self['node_pre' .. j] = cc.Node:create()
                self['node_pre' .. j]:retain()
                self['node_pre' .. j]:setPosition(0, -(self.item_height + MARGIN_V_BETWEEN))
                --self['node_pre' .. j - 1]:addChild(self['node_pre' .. j])  -- 错! self['node_pre' .. j - 1]已经在上一步置为nil
                father:addChild(self['node_pre' .. j])
            end
        end
        self['node' .. i] = self['node_pre' .. j]
        for k = 1, NUM_PER_ROW do 
            local index1 = (j - 1) * NUM_PER_ROW + k
            local index2 = (i - 1) * NUM_PER_ROW + k
            self['item' .. index2] = self['item_pre' .. index1]
            self['item_pre' .. index1] = nil
        end
        father = self['node_pre' .. j]
        self['node_pre' .. j] = nil 
        self:show_a_row(i)
        i = i + 1
        j = j + 1      --这里 j不用担心上界,如果item是nil则会在show_a_row里创建
    end
    father = nil


    if self['node_pre' .. j] then   --因为node(i)的父节点是node(i - 1),所以remove一个就行
        self['node_pre' .. j]:removeFromParent()
    end
    while self['node_pre' .. j] do  --虽然上面已经释放,但是self内相关引用值不为nil,需赋为nil
        self['node_pre' .. j]:release()
        self['node_pre' .. j] = nil
        for k = 1, NUM_PER_ROW do
            local index = (j - 1) * NUM_PER_ROW + k
            self['item_pre' .. index] =nil
        end
        j = j + 1
    end
end


function scroll:head_tail_head_tail()
    self.count = 0
    if self.count < 2 then
        self:one_more_row_to_head()
    end
    if self.count < 2 then
        self:one_more_row_to_tail()
    end
    if self.count < 2 then
        self:one_more_row_to_head()
    end
    if self.count < 2 then
        self:one_more_row_to_tail()
    end
end


function scroll:tail_tail_head_head()
    self.count = 0
    if self.count < 2 then
        self:one_more_row_to_tail()
    end
    if self.count < 2 then
        self:one_more_row_to_tail()
    end
    if self.count < 2 then
        self:one_more_row_to_head()
    end
    if self.count < 2 then
        self:one_more_row_to_head()
    end
end


function scroll:one_more_row_to_head()
    if self.iHead == 1 then
        return
    end
    self.count = self.count + 1
    local height = self.inner:getContentSize().height
    height = height + (self.item_height + MARGIN_V_BETWEEN)
    self.inner:setContentSize(cc.size(self.scv_width, height)) --这和setInnerContainerSize( 延伸方向不同
    NODE_IHEAD_POS =  height - MARGIN_UP
    self['node' .. self.iHead - 1] = cc.Node:create()
    self['node' .. self.iHead - 1]:retain()
    self['node' .. self.iHead - 1]:setPosition(0, NODE_IHEAD_POS)
    self.inner:addChild(self['node' .. self.iHead - 1])
    self['node' .. self.iHead]:removeFromParent()
    self['node' .. self.iHead]:setPosition(0, -(self.item_height + MARGIN_V_BETWEEN))
    self['node' .. self.iHead - 1]:addChild(self['node' .. self.iHead])
    self:show_a_row(self.iHead - 1)
    self.iHead = self.iHead - 1
end


function scroll:one_more_row_to_tail()
    if self.iTail == self.max_row then
        return
    end
    self.count = self.count + 1
    local height = self.inner:getContentSize().height
    height = height + (self.item_height + MARGIN_V_BETWEEN)
    self.scv:setInnerContainerSize(cc.size(self.scv_width, height))
    NODE_IHEAD_POS =  height - MARGIN_UP
    self['node' .. self.iHead]:setPosition(0, NODE_IHEAD_POS)
    self['node' .. self.iTail + 1] = cc.Node:create()
    self['node' .. self.iTail + 1]:retain()
    self['node' .. self.iTail + 1]:setPosition(0, -(self.item_height + MARGIN_V_BETWEEN))
    self['node' .. self.iTail]:addChild(self['node' .. self.iTail + 1])
    self:show_a_row(self.iTail + 1)
    self.iTail = self.iTail + 1
end




--当删除或添加items后应该调整之前的头尾位置
function scroll:set_new_iHead_iTail()
    self.visible_rows = math.ceil(self.scv_height / (self.item_height + MARGIN_V_BETWEEN)) --可视域行数
    self.max_row = math.ceil(#self.data / NUM_PER_ROW)
    self.iTail = self.iHead + self.visible_rows - 1
    self.iTail = math.min(self.max_row, self.iTail)
    self.iHead = self.iTail - self.visible_rows + 1
    self.iHead = math.max(1, self.iHead)
end


function scroll:monitor()
    local innerY = self.inner:getPositionY()
    if self.delY > 0 and innerY + NODE_IHEAD_POS > THRESHOLD then --把头行移至尾后
        if self.iTail == self.max_row then
            return
        end
        self['node' .. self.iHead + 1]:removeFromParent()
        self['node' .. self.iHead + 1]:setPosition(0, NODE_IHEAD_POS)
        self.inner:addChild(self['node' .. self.iHead + 1])
        self['node' .. self.iHead]:removeFromParent()
        self['node' .. self.iHead]:setPosition(0, -(self.item_height + MARGIN_V_BETWEEN))
        self['node' .. self.iTail]:addChild(self['node' .. self.iHead])
        self.inner:setPosition(0, innerY - (self.item_height + MARGIN_V_BETWEEN))
    
        self['node' .. self.iTail + 1] = self['node' .. self.iHead]
        self['node' .. self.iHead] = nil
        for j = 1, NUM_PER_ROW do
            local index1 = (self.iHead - 1) * NUM_PER_ROW + j
            local index2 = (self.iTail + 1 - 1) * NUM_PER_ROW + j
            self['item' .. index2] = self['item' .. index1]
            self['item' .. index1] = nil
        end
        if _G[self.modName].getInstance().item_change_i_to_j then
            _G[self.modName].getInstance():item_change_i_to_j(self['item'..self.iTail + 1], self.iHead, self.iTail + 1) --从第几个变成第几个
        end
        self.iHead = self.iHead + 1
        self.iTail = self.iTail + 1
        self:show_a_row(self.iTail)
    end
    if self.delY < 0 and innerY + NODE_IHEAD_POS < THRESHOLD - self.item_height then   --这里的第二个判断不能为上面第二个判断的补集,否则滑动会出现空白
        if self.iHead == 1 then
            return
        end
        self['node' .. self.iTail]:removeFromParent()
        self['node' .. self.iTail]:setPosition(0, NODE_IHEAD_POS)
        self.inner:addChild(self['node' .. self.iTail])
        self['node' .. self.iHead]:removeFromParent()
        self['node' .. self.iHead]:setPosition(0, -(self.item_height + MARGIN_V_BETWEEN))
        self['node' .. self.iTail]:addChild(self['node' .. self.iHead])
        self.inner:setPosition(0, innerY + (self.item_height + MARGIN_V_BETWEEN))


        self['node' .. self.iHead - 1] = self['node' .. self.iTail]
        self['node' .. self.iTail] = nil
        for j = 1, NUM_PER_ROW do
            local index1 = (self.iTail - 1) * NUM_PER_ROW + j
            local index2 = (self.iHead - 1 - 1) * NUM_PER_ROW + j
            self['item' .. index2] = self['item' .. index1]
            self['item' .. index1] = nil 
            if not self['item' .. index2]:isVisible() then
                self['item' .. index2]:setVisible(true)
            end
        end
        if _G[self.modName].getInstance().item_change_i_to_j then
            _G[self.modName].getInstance():item_change_i_to_j(self['item'..self.iHead - 1], self.iTail, self.iHead - 1) --从第几个变成第几个
        end
        self.iHead = self.iHead - 1
        self.iTail = self.iTail - 1
        self:show_a_row(self.iHead)
    end
end


_G['scroll'] = scroll
内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值