实话说这个玩意也不是我原创的,网上只能找到C++版本的,我改写成了Lua版。
初学cocos-lua各种记不住API也是醉了……总之写的很苦逼但是最后结果是好的,我在有一些地方做了少许微调使操作杆更符合现实逻辑。
下面上代码:
local HRocker = class("HRocker",function()
return cc.Layer:create();
end)
function HRocker.create(cpoint, radius, control, background)
local rocker = HRocker.new(cpoint,radius,control,background);
local eventDispatcher = rocker:getEventDispatcher();
eventDispatcher:addEventListenerWithSceneGraphPriority(rocker:bindListener(), rocker);
return rocker;
end
function HRocker:ctor(cpoint, radius, control, background)
self.isActive = false;
self.radius = radius;
self.max_radius = radius - control:getContentSize().width;
self.currentPoint = cpoint;
self.centerPoint = cpoint;
self.controlSprite = control;
self.controlSprite:setPosition(cpoint);
background:setPosition(cpoint);
background:setTag(88);
self:addChild(background);
self:addChild(self.controlSprite);
self.schedulerID = nil;
self:setCascadeOpacityEnabled(true);
cclog("%s", type(cpoint));
self.bindListener();
self:active();
end
function HRocker:active()
if( not self.isActive ) then
self.isActive = true;
local updatePos = function()
local now_point = cc.p(self.controlSprite:getPosition()) ;
local point = cc.pAdd(
now_point,
cc.pMul(
cc.pSub(self.currentPoint, now_point) ,
0.5
)
);
self.controlSprite:setPosition(point);
end
self.schedulerID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(updatePos , 1.0 / 60, false);
end
end
function HRocker:inactive()
if( self.isActive ) then
self.isActive = false;
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.schedulerID);
end
end
function HRocker:bindListener()
local ccTouchBegan = function(pTouch, pEvent)
if( not self.isActive ) then
return false;
end
local touchPoint = pTouch.getLocation(pTouch);
if ( cc.pGetDistance(touchPoint, self.centerPoint) > self.radius) then
return false;
end
self:setOpacity(255);
self.currentPoint = touchPoint;
return true;
end
local ccTouchMoved = function(pTouch, pEvent)
local touchPoint = pTouch.getLocation(pTouch);
if (cc.pGetDistance(touchPoint, self.centerPoint) > self.radius) then
self.currentPoint =cc.pAdd( self.centerPoint, cc.pMul(cc.pNormalize(cc.pSub(touchPoint, self.centerPoint)),( self.radius - self.max_radius )));
else
self.currentPoint = touchPoint;
end
end
local ccTouchEnded = function(pTouch, pEvent)
cclog("touch end");
self.currentPoint = self.centerPoint;
self:setOpacity(255 * 0.4);
end
local listener = cc.EventListenerTouchOneByOne:create();
listener:registerScriptHandler(ccTouchBegan ,cc.Handler.EVENT_TOUCH_BEGAN );
listener:registerScriptHandler(ccTouchMoved ,cc.Handler.EVENT_TOUCH_MOVED );
listener:registerScriptHandler(ccTouchEnded ,cc.Handler.EVENT_TOUCH_ENDED );
return listener;
end
function HRocker:getDirection()
return cc.pNormalize(cc.pSub(self.centerPoint,self.currentPoint));
end
function HRocker:getVelocity()
return cc.pDistanceSQ(self.centerPoint,self.currentPoint);
end
return HRocker;
使用时,需要指定中心点位置,指定操作杆大小的半径,背景图片sprite和操作点的sprite。