鱼阵的LUA实现

--[[
------------------------------------
一条鱼
------------------------------------
Ivan_han@2013/4/16 11:08:17
------------------------------------
]]

function CreateObj(pSpriteFrame)
    return CCSprite:createWithSpriteFrame(pSpriteFrame)
end

Fish = class("Fish", CreateObj)

Fish.__index = Fish
Fish.isCatch = false
--Fish.fishType=1

CCLuaLog("Fish...................."..tostring(Fish.__index))

function Fish:spriteWithSpriteFrame(pSpriteFrame)
    local fish = Fish.new(pSpriteFrame)
    if (fish~=nil)then
    fish:autorelease()
          fish:retain()
 end
 return fish
end

function Fish:spriteWithSpriteFrameName(pszSpriteFrameName)
    if(pszSpriteFrameName == nil) then
        CCLuaLog("Fish.spriteWithSpriteFrameName.pszSpriteFrameName.Nil!")
        return nil
    end
    local pFrame = CCSpriteFrameCache:sharedSpriteFrameCache():spriteFrameByName(pszSpriteFrameName)
    if (pFrame~=nil)then
  return self:spriteWithSpriteFrame(pFrame)
 end
end

function Fish:randomCatch(level)
 local rnd = SIX_Utility:new():RNDNUM(0,9)
 if(rand >= level) then
        return true
    end
    return false
end

 

function Fish:getIsCatch()
    return isCatch
end

function Fish:setIsCatch(IsCatch)
    isCatch=IsCatch
end

--[[
三阶贝塞尔曲线(P_0,P_1,P_2,P_3)退化为二阶贝塞尔曲线(P_0,P_1,P_2,即抛物线:起点P_0=控制点P_1,控制点P_2,终点P_3)
参数说明:
startP----轨迹起点
endP----轨迹终点
startAngle----
endAngle----
time----动画时长
]]
function Fish:moveWithParabola(startP,endP,startAngle,endAngle,time)
 local sx = startP.x;
 local sy = startP.y;
 local ex =endP.x;
 local ey =endP.y;

 local h = self:getContentSize().height * 0.5;
 local pos=CCPoint(sx,sy);
 self:setPosition(pos);
 self:setRotation(startAngle);

 -- 贝塞尔曲线
 local bezier=ccBezierConfig:new();
 -- 控制点1(起点)
 bezier.controlPoint_1 = ccp(sx, sy);
 -- 控制点2
 --bezier.controlPoint_2 = ccp(sx+(ex-sx)*0.5, sy+(ey-sy)*0.5);
 bezier.controlPoint_2 = ccp(sx+(ex-sx)*0.5, sy+(ey-sy)*0.5+100); 
 -- 终点
 bezier.endPosition = ccp(endP.x, endP.y);

 local actionMove = CCBezierTo:create(time, bezier);
 local actionRotate = CCRotateTo:create(time, endAngle);
 local action = CCSpawn:createWithTwoActions(actionMove, actionRotate);
 local pcc=CCCallFunc:create(function()
          self:removeFromParentAndCleanup(true)
    end)
 local sq = CCSequence:createWithTwoActions(action,pcc); 
 self:runAction(sq);
end

function CircleTrace(t)
          --圆中心为(350,300),半径为150,轨迹起点为(500,300)的逆时针圆轨迹
          local x=150*math.cos(2*math.pi*t)
          local y=150*math.sin(2*math.pi*t)
          return ccp(350+x,300+y)
end

function EllipseTrace(t)
          --椭圆中心为(350,300),长半径为150,短半径为120,轨迹起点为(500,300),焦点F_1为(260,300),焦点F_2为(440,300)的逆时针椭圆轨迹
          local C=ccp(350,300)
          local a=150
          local b=120
          local c=90
          local x=a*math.cos(2*math.pi*t)
          local y=b*math.sin(2*math.pi*t)
          return ccp(C.x+x,C.y+y)
end

function SinTrace(t)
          --轨迹起点为(500,300),振幅为150的正弦曲线轨迹
          local C=ccp(350,300)
          local a=150
          local x=a*2*math.pi*t
          local y=a*math.sin(2*math.pi*t)
          return ccp(C.x+x,C.y+y)
end

--[[
获得圆上点的坐标
参数说明:
startP--轨迹起点坐标
centerP--圆心坐标
deltArg--相对于轨迹起点的辐角主值增量 
]]
function GetCirclePos(startP,centerP,deltArg)
          local startarg=math.atan2(startP.y-centerP.y,startP.x-centerP.x);--轨迹起点相对于圆心的辐角主值
          local tempx=(startP.x-centerP.x)*(startP.x-centerP.x);
    local tempy=(startP.y-centerP.y)*(startP.y-centerP.y);
    local r=math.sqrt(tempx+tempy);--圆的半径
          local x=r*math.cos(startarg+deltArg)--圆上点相对于圆心的X坐标偏移
          local y=r*math.sin(startarg+deltArg)--圆上点相对于圆心的Y坐标偏移
          return ccp(centerP.x+x,centerP.y+y)
end

--[[
圆轨迹
参数说明:
t----轨迹参数方程中的参数
startP----轨迹起点坐标
centerP----圆心坐标
direction----取值浮点数,表示圈数,正、负圈数分别表示逆、顺时针旋转
]]
--function CircleTraceFunc(t,startP,centerP,direction)
function CircleTraceFunc(t,startPx,startPy,centerPx,centerPy,direction)
          local startP=ccp(startPx,startPy)
          local centerP=ccp(centerPx,centerPy)
          --圆中心为centerP,半径为r,轨迹起点为startP的direction弧度圆轨迹
          local startarg=math.atan2(startP.y-centerP.y,startP.x-centerP.x);--轨迹起点相对于圆心的辐角主值
          local tempx=(startP.x-centerP.x)*(startP.x-centerP.x);
    local tempy=(startP.y-centerP.y)*(startP.y-centerP.y);
    local r=math.sqrt(tempx+tempy);--圆的半径
          local x=r*math.cos(startarg+2*math.pi*t*direction)
          local y=r*math.sin(startarg+2*math.pi*t*direction)
          --return ccp(centerP.x+x-startPx,centerP.y+y-startPy)--改为相对位置以支持CCRepeatForever无限次重复动画
          return ccp(centerP.x+x,centerP.y+y)
end


--[[
直线运动和匀速圆周运动合成的轨迹,我们称之为摆线
过原点startP=(0,0)、半径为r的摆线参数方程为
x=r(a-sina)
y=r(1-cosa)
在这里实参数a是在弧度之下,圆滚动的角度。对每一个给出的a ,圆心的坐标为(ra,r)。
参数说明:
t----轨迹参数方程中的参数
]]
function CycloidTrace(t)
          local startP=ccp(200,300)--摆线轨迹起点
          local direction=3
    local r=50;
          local a=2*math.pi*t*direction
          local x=r*(a-math.sin(a))
          local y=r*(1-math.cos(a))
          return ccp(startP.x+x,startP.y+y)
end

--[[
摆线轨迹
参数说明:
t----轨迹参数方程中的参数
startP----轨迹起点坐标
r----圆的半径
deltArg----取值浮点数,相对于轨迹起点的辐角主值增量
direction----拱形的个数
reserved----保留参数
]]
--function CycloidTraceFunc(t,startPx,startPy,r,deltArg,direction)
function CycloidTraceFunc(t,startPx,startPy,r,deltArg,direction,reservedx,reservedy)
          local a=2*math.pi*t*direction        
          local x=r*(a-math.sin(a))
          local y=r*(1-math.cos(a))
          local startPt=ccp(x,y)
          local centerPt=ccp(r*a,r)--圆心坐标
    local retPt=GetCirclePos(startPt,centerPt,deltArg)
          local startP=ccp(startPx,startPy)--摆线轨迹起点deltArg=0
          return ccp(startP.x+retPt.x,startP.y+retPt.y)     
end

--[[
具体的运动轨迹由轨迹类型、轨迹起点坐标、轨迹速度等相互独立的参数来控制
参数说明:
pathType--轨迹类型
arg1--第一个额外参数,圆轨迹要用到
]]
function Fish:addPath(pathType,arg1)
if(pathType==1)then
   --给定轨迹起点和恒定速度矢量(恒定速率和恒定方向)的匀速直线运动
   --self:setPosition(CCPoint(200,300));
--[[  
   local  actionBy = CCMoveBy:create(1, ccp(300,300));
   local  ac = CCRepeatForever:create(actionBy);
   self:runAction(ac);
  ]]
--右上角45度直线轨迹
   local pAction=CCMoveBy:create(15.0, ccp(1500,1500));
   self:runAction(pAction);  
end
if(pathType==2)then
   --self:setPosition(CCPoint(200,300));
--[[  
   local pAction=CCMoveBy:create(3.0, ccp(300,0));
   --self:runAction(pAction);
   local  ac = CCRepeatForever:create(pAction);
   self:runAction(ac);
]]
--水平向右直线轨迹
   local pAction=CCMoveBy:create(15.0, ccp(1500,0));
   self:runAction(pAction);  
   --local pAction=CCMoveTo:create(3.0, ccp(500,300));--直线轨迹。参数一为动画时长,参数二为要移动到的目标点。
     --创建一个加速直线运动(a>0)。1<r<2时,△a<0;r=2时,△a=0,a=2;r>2时,△a>0。 
   --local move_ease_in = CCEaseIn:create(pAction,2);--参数二r=2,加速度为a=2的匀加速直线运动
   --local move_ease_in = CCEaseIn:create(pAction,5);--参数二r>2,加速度越来越大的变加速直线运动
    --local move_ease_in = CCEaseIn:create(pAction,1.5);--参数二1<r<2,加速度越来越小的变加速直线运动
    --self:runAction(move_ease_in);  
    --创建一个加速度越来越大的减速直线运动(a<0),r>1,△a>0 
   --local move_ease_out = CCEaseOut:create(pAction,2);
   --self:runAction(move_ease_out);
end 
if(pathType==3)then
   --轨迹起点
   --self:setPosition(CCPoint(200,300));
   --圆逆时针运动轨迹,参数一为动画时长,参数二为当前圆上位置的对径点坐标,参数三为轨迹方向
   --给定轨迹起点和恒定速率的匀速圆周运动
   --self:setPosition(CCPoint(200,300));
--[[
   local  actionBy = CircleAction:create(1.0, ccp(500,300),1);
   local  ac = CCRepeatForever:create(actionBy);
   self:runAction(ac);
]]
  local startP=CCPoint(self:getPositionX(),self:getPositionY());
  --对于圆轨迹,arg1代表圆心坐标
   if(arg1==nil)then
      arg1=CCPoint(self:getPositionX()+150,self:getPositionY());
  end
  --对径点P
   local P=CCPoint(arg1.x*2-self:getPositionX(),arg1.y*2-self:getPositionY());
  --local P=CCPoint(self:getPositionX()+300,self:getPositionY());
   local  actionBy = CircleAction:create(5.0,P,1);
   local  ac = CCRepeatForever:create(actionBy);
   self:runAction(ac); 
end
if(pathType==4)then
   --轨迹起点
   --self:setPosition(CCPoint(200,300));
   --圆顺时针运动轨迹,参数一为动画时长,参数二为当前圆上位置的对径点坐标,参数三为轨迹方向
   self:runAction(CircleAction:create(3.0, ccp(500,300),-1));
end
if(pathType==5)then
   --自定义运动轨迹,参数一为动画时长,参数二为表示轨迹参数方程的LUA函数名
   --self:runAction(myAction:create(3.0,"CircleTrace"));
   --self:runAction(myAction:createCircle(3.0,"CircleTraceFunc",ccp(500,300),ccp(350,300),2));
  local startP=CCPoint(self:getPositionX(),self:getPositionY());
  --对于圆轨迹,arg1代表圆心坐标
   if(arg1==nil)then
      arg1=CCPoint(self:getPositionX()-150,self:getPositionY());
  end   
   self:runAction(myAction:createCircle(60.0,"CircleTraceFunc",startP,arg1,20)); 
end
if(pathType==6)then
   --圆中心为(350,300),半径为150,轨迹起点为(500,300)的逆时针圆轨迹
   --圆运动轨迹,参数一为动画时长,参数二为表示圆轨迹参数方程的LUA函数名,参数三为轨迹起点坐标,参数四为圆心坐标,参数五为正负圈数
   --self:runAction(myAction:createCircle(3.0,"CircleTraceFunc",ccp(500,300),ccp(350,300),1));
   --self:runAction(myAction:createMoveCircle(3.0,"MoveCircleTraceFunc",ccp(500,300),ccp(350,300),1,ccp(0,0)));
   --self:runAction(myAction:createMoveCircle(3.0,"MoveCircleTraceFunc",ccp(500,300),ccp(350,300),1,ccp(-250,0)));
   --local  actionBy =myAction:createMoveCircle(3.0,"MoveCircleTraceFunc",ccp(500,300),ccp(350,300),1,ccp(-50,0)); 
    --去掉了createMoveCircle,用createCycloid代替 
   local  actionBy =myAction:createCycloid(3.0,"CycloidTraceFunc",ccp(200,300),ccp(50,0),3,ccp(-50,0));
   local  ac = CCRepeatForever:create(actionBy);
   self:runAction(ac);
end
if(pathType==7)then
   --自定义运动轨迹,参数一为动画时长,参数二为表示轨迹参数方程的LUA函数名
   --self:runAction(myAction:create(3.0,"EllipseTrace"));
   --self:runAction(myAction:create(3.0,"CycloidTrace"));
   --local rdeltArg=ccp(50,0)--表示圆的半径是50,辐角主值增量是0
   --self:runAction(myAction:createCircle(3.0,"CycloidTraceFunc",ccp(200,300),ccp(50,0),3));
   local startP=CCPoint(self:getPositionX(),self:getPositionY());
  --对于摆线轨迹,arg1代表半径和辐角主值增量
    if(arg1==nil)then
      arg1=CCPoint(50,0);
  end  
   self:runAction(myAction:createCircle(3.0,"CycloidTraceFunc",startP,arg1,3));
end
if(pathType==8)then
   --自定义运动轨迹,参数一为动画时长,参数二为表示轨迹参数方程的LUA函数名
   --self:runAction(myAction:create(3.0,"SinTrace"));
    --创建一个先加速再减速的正弦曲线轨迹运动
   local pAction=myAction:create(3.0,"SinTrace");
   local move_ease_inout = CCEaseInOut:create(pAction,2);
   self:runAction(move_ease_inout);  
end
if(pathType==9)then
   self:moveWithParabola(ccp(200, 300), ccp(500, 300), 0.0, 20.0, 3.0);
end    
end

--[[
------------------------------------
鱼精灵对象用到的精灵帧的管理
------------------------------------
Ivan_han@2013/4/20 14:15:17
------------------------------------
]]
FishManage = class("FishManage")
FishManage.__index = FishManage
FishManage.s_AllFish1 = nil

function FishManage:Init(pNode)
  local fishType=1
 CCSpriteFrameCache:sharedSpriteFrameCache():addSpriteFramesWithFile("./action/Fish01/Fish01.plist");
 local pBatchName = CCString:create( "./action/Fish01/Fish01.png" );

 self.s_AllFish1 = CCSpriteBatchNode:create( pBatchName:getCString() );
 pNode:addChild( self.s_AllFish1 );--鱼精灵批处理结点对象s_AllFish1挂接到节点pNode上
 --FishManage:addOneFish(1) 
end

function FishManage:Release()
 CCSpriteFrameCache:sharedSpriteFrameCache():removeSpriteFramesFromFile("./action/Fish01/Fish01.plist")
 self.s_AllFish1:removeAllChildrenWithCleanup( true )
end


function FishManage:addOneGroupFish(fishgroupType)
--水平直线轨迹阵
if(fishgroupType==1)then
   FishManage:addOneFish(1,2);
   FishManage:addOneFish(1,2,ccp(0,350));
   FishManage:addOneFish(1,2,ccp(0,250));  
end
--斜直线轨迹阵
if(fishgroupType==2)then
   FishManage:addOneFish(1,1,ccp(-50,50))
   FishManage:addOneFish(1,1,ccp(-25,75))
   FishManage:addOneFish(1,1,ccp(0,100))
   FishManage:addOneFish(1,1,ccp(-70,25))  
end
--圆轨迹阵 
if(fishgroupType==3)then
    local startP=ccp(0,300)
    local centerP=ccp(150,300)  
 local deltArg=math.pi*0.2
 for i=1,10 do
  local startP=GetCirclePos(startP,centerP,deltArg*(i-1))
  FishManage:addOneFish(1,3,startP,centerP)
 end 
end
--圆轨迹阵 
if(fishgroupType==4)then
    local startP=ccp(500,300)
    local centerP=ccp(350,300)  
 local deltArg=math.pi*0.2
 for i=1,10 do
  local startP=GetCirclePos(startP,centerP,deltArg*(i-1))
  FishManage:addOneFish(1,5,startP,centerP)
 end 
end
--摆线轨迹阵 
if(fishgroupType==5)then
    local startP=ccp(200,300)
    local rdeltArg=ccp(50,0)
 local deltArg=math.pi*0.2
 for i=1,10 do
  rdeltArg.y=deltArg*(i-1)
  FishManage:addOneFish(1,7,startP,rdeltArg)
 end 
end 
end

function FishManage:addOneFish(fishType,pathType,startP,arg1)
    if(startP==nil)then
        startP=ccp(0,300)
    end
    --[[
     if(arg1==nil)then
        arg1=ccp(150,300)
    end
   ]]   
 local pArray = CCArray:create()
 for i=1,9 do
  local pStrBuffer = string.format('fish0%d_%d.png',fishType,i)
  local pSpriteFrame = CCSpriteFrameCache:sharedSpriteFrameCache():spriteFrameByName( pStrBuffer )
  pArray:addObject( pSpriteFrame )
 end  
 -- 由帧缓存生成action,帧延迟0.1f
 local pAnimation =CCAnimation:createWithSpriteFrames(pArray,0.1);
    local fish_act = CCRepeatForever:create(CCAnimate:create(pAnimation));
 -- 通过起始帧生成鱼实体
 local Name="fish0"..tostring(fishType).."_1.png"
 local pFish = Fish:spriteWithSpriteFrameName(Name)
 if (pFish) then
   pFish:setScale(1.0);
   pFish:setTag(fishType);
   pFish:setPosition(startP);
   pFish:setIsCatch(false);
   pFish:runAction(fish_act);
   pFish:addPath(pathType,arg1);
   --self.s_AllFish1:addChild(pFish)--生成的鱼精灵对象挂接到鱼精灵批处理结点对象s_AllFish1上
   --生成的鱼精灵对象挂接到鱼精灵批处理结点对象s_AllFish1的父节点上
      local pNode=self.s_AllFish1:getParent()
   pNode:addChild( pFish );
 end
 CCLuaLog("pFish="..tostring(pFish)) 
end

SceneGame.lua中调用Fish.lua:
-- 弹起(鼠标在控件区域内)
function onCCControlEventTouchUpInside(pSender,name)
 CCLuaLog("SceneGame.pSender["..tostring(pSender).."].name["..name.."].onCCControlEventTouchUpInside")
 --add by Ivan_han
    if name=="MyDepot" then
     --FishManage:addOneFish(1,1,ccp(0,100))
     FishManage:addOneGroupFish(2)
 elseif name=="Task" then
     FishManage:addOneGroupFish(1)
 elseif name=="Help" then
     --FishManage:addOneFish(1,3)
     FishManage:addOneGroupFish(3)
 elseif name=="Shop" then
     FishManage:addOneFish(1,4)
 elseif name=="Supplement" then
     --FishManage:addOneFish(1,5,ccp(500,300),ccp(350,300))
     FishManage:addOneGroupFish(4)
 elseif name=="Bullet" then
     FishManage:addOneFish(1,6)
 elseif name=="Set" then
     --FishManage:addOneFish(1,7)
        FishManage:addOneGroupFish(5)    
 else
     FishManage:addOneFish(1,8)
 end
end:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值