实现思路
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
向左滑动效果图(滑动的方向可以设置):