【Cocos2d-x】实现可上下左右无限滚动的背景

本文通过介绍一种实现思路,包括初始化图片位置、使用定时器更新图片位置及处理图片超出边界的情况,详细讲解了如何在Cocos2d-x中创建一个可上下左右无限滚动的背景。同时提供了项目的svn地址和向左滑动效果的示例。

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


实现思路


1.根据方向初始化图片的位置,每张图片按顺序位置紧紧相邻;

2.使用定时器根据速度一直更新图片的位置,使图片整体向指定方向移动;

3.当图片超出边界时,设置当前图片的位置紧跟最后一张图片后面;



实现代码



LoopLayer = class("LoopLayer",function ()
    return cc.Sprite:create()
end)

--方向常量
--上
LoopLayer.DIRECTION_TOP = cc.p(0,1)
--下
LoopLayer.DIRECTION_BOTTOM = cc.p(0,-1)
--左
LoopLayer.DIRECTION_LEFT = cc.p(-1,0)
--右
LoopLayer.DIRECTION_RIGHT = cc.p(1,0)


--参数说明
--1.imgs(参与滚动的图片,至少两张)
--2.direction(滚动方向)
--3.speed(滚动速度)
function LoopLayer:create(imgs, direction,speed)
    local obj = LoopLayer.new()
    obj:init(imgs, direction, speed)
    return obj
end

-- 偏移(用于处理黑边)
local offset = 6
-- 四个方向的边界处理函数
local boundingHandler = {
    [LoopLayer.DIRECTION_TOP] = function (self, img)
        -- 如果当前图片已经偏移出边界        
        if img:getPositionY() > img:getContentSize().height then    
            -- 则把他的位置设置为紧跟最后一张图片
            local pos = cc.pAdd(cc.p(self.lastImg:getPosition()),cc.p(0,-self.lastImg:getContentSize().height+offset))
            img:setPosition(pos)
            -- 最后一张图片指针指向当前图片            
            self.lastImg = img
        end
    end,
    [LoopLayer.DIRECTION_BOTTOM] = function (self, img)
        if img:getPositionY() < -img:getContentSize().height then
            local pos = cc.pAdd(cc.p(self.lastImg:getPosition()),cc.p(0,self.lastImg:getContentSize().height-offset))
            img:setPosition(pos)
            self.lastImg = img
        end
    end,
    [LoopLayer.DIRECTION_LEFT] = function (self, img)
        if img:getPositionX() < -img:getContentSize().width then
            local pos = cc.pAdd(cc.p(self.lastImg:getPosition()),cc.p(self.lastImg:getContentSize().width-offset,0))
            img:setPosition(pos)
            self.lastImg = img
        end
    end,
    [LoopLayer.DIRECTION_RIGHT] = function (self, img)
        if img:getPositionX() > img:getContentSize().width then
            local pos = cc.pAdd(cc.p(self.lastImg:getPosition()),cc.p(-self.lastImg:getContentSize().width+offset,0))
            img:setPosition(pos)
            self.lastImg = img
        end
    end,
}

function LoopLayer:init(imgs, direction, speed)
    -- 图片精灵集合    
    self.imgs = {}
    
    -- 初始化偏移量
    self.offset = cc.pMul(direction,speed)
--    cclog("offset x=%s y=%s",self.offset.x,self.offset.y)
    -- 添加图片
    local posOffset = 0
    for idx, path in ipairs(imgs) do
        local img = cc.Sprite:create(path)
        img:setAnchorPoint(cc.p(0,0))
        self.imgs[idx] = img

        -- 设置图片位置
        local pos = nil
        -- 纵向
        if direction.x == 0 then
            pos = cc.pMul(cc.p(0,-posOffset),direction.y)
            posOffset = posOffset + img:getContentSize().height
        -- 横向
        else
            pos = cc.pMul(cc.p(-posOffset,0),direction.x)
            posOffset = posOffset + img:getContentSize().width
        end
        img:setPosition(pos)
--        cclog("img=%s pos.x=%s pos.y=%s",path,pos.x,pos.y)
 
        -- 设置可视区域
--        img:setTextureRect(cc.rect(0,0,size[1],size[2]))
        self:addChild(img)
    end

    -- 定义图片序列中最后的一张图片(用于获取位置)    
    self.lastImg = self.imgs[table.maxn(self.imgs)]
    -- 选择图片超出边界的处理函数
    local boundingFunc = boundingHandler[direction]

    -- 图片定时偏移
    schedule(self,function ()
        for idx, img in ipairs(self.imgs) do
            --图片当前位置加上偏移量得到图片移动的位置            
            local pos = cc.pAdd(cc.p(img:getPosition()),self.offset)
            img:setPosition(pos)
            -- 图片超出边界的处理
            boundingFunc(self, img)
        end
    end,0)
end

cc.FileUtils:getInstance():addSearchPath("src")
cc.FileUtils:getInstance():addSearchPath("res")

-- CC_USE_DEPRECATED_API = true
require "cocos.init"

-- cclog
cclog = function(...)
    print(string.format(...))
end

-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    cclog("----------------------------------------")
    cclog("LUA ERROR: " .. tostring(msg) .. "\n")
    cclog(debug.traceback())
    cclog("----------------------------------------")
    return msg
end

local function main()
    collectgarbage("collect")
    -- avoid memory leak
    collectgarbage("setpause", 100)
    collectgarbage("setstepmul", 5000)

    -- initialize director
    local director = cc.Director:getInstance()

    --turn on display FPS
    director:setDisplayStats(true)

    --set FPS. the default value is 1.0/60 if you don't call this
    director:setAnimationInterval(1.0 / 60)
    
    cc.Director:getInstance():getOpenGLView():setDesignResolutionSize(650, 365, 0)
    local visibleSize = director:getVisibleSize()
    
    
    ------------------------示例代码------------------------------
    local scene = cc.Scene:create()
    require("LoopLayer")
    -- 参与滚动的图片    
    local imgs = {"bg.jpg","bg.jpg"}
    -- 创建滚动层
    local layer = LoopLayer:create(imgs,LoopLayer.DIRECTION_LEFT,2)
    layer:setAnchorPoint(cc.p(0,0))
    layer:setPosition(cc.p(0,0))
    scene:addChild(layer)    
    ------------------------示例代码------------------------------
     
    if cc.Director:getInstance():getRunningScene() then
        cc.Director:getInstance():replaceScene(scene)
    else
        cc.Director:getInstance():runWithScene(scene)
    end
end

local status, msg = xpcall(main, __G__TRACKBACK__)
if not status then
    error(msg)
end


项目svn地址:http://code.taobao.org/svn/looplayer/trunk


向左滑动效果图(滑动的方向可以设置):


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值