local CombineEffectEditor = class("CombineEffectEditor" , require("NodeEditor")); function CombineEffectEditor:ctor() CombineEffectEditor.super.ctor(self); -- 根节点 self.node = nil; -- 源模型集合的父节点 self.sourceRootNode = nil; -- 源点集合的父节点 self.sourcePosRootNode = nil; -- 目标模型集合的父节点 self.targetRootNode = nil; -- 目标点集合的父节点 self.targetPosRootNode = nil; -- 技能action self.CombineEffectAction = nil; -- 背景场景 self.SceneFile = nil; end function CombineEffectEditor:activate() -- 基类 CombineEffectEditor.super.ctor(self); -- 设置锚点位置 app.setting.OriginAnchor = cc.p(0.5,0.5); app:refreshSetting(); -- 初始化技能环境 self:initCombineEffectEnv(); -- 创建一个文本框,用于显示技能是否为无限长 local debugLabel = cc.Text:createNode(); debugLabel:setDefaults(); local config = debugLabel:getFontConfig(); config.fontSize = 40; config.texColor = cc.c4b(255,0,0,255); debugLabel:setFontConfig(config); -- 获取可见视野的像素大小 local screenSize = cc.Director:getInstance():getWinSizeInPixels(); debugLabel:setTranslation(screenSize.width / 2 , 100 , 0) debugLabel:setText(""); self.debugText = debugLabel; self.InfinityTipTextNode = cc.Scene:create() self.InfinityTipTextNode:setActiveCamera(cc.Director:getInstance():getFixedCamera()) self.InfinityTipTextNode:addChild(self.debugText) app.mainScene:addChild(self.InfinityTipTextNode); self.InfinityTipTextNode:setVisible(false) end function CombineEffectEditor:unactivate() if self.SceneFile then self.SceneFile:removeFromParent(); self.SceneFile = nil; end self.InfinityTipTextNode:removeFromParent(); -- 清空技能环境 self:unInitCombineEffectEnv(); self:closeCombineEffect(); end -- 是否可以选中此节点 function CombineEffectEditor:canSelectNode(flag, node) return true; end -- 保存技能文件 function CombineEffectEditor:save(filename) self.ce:saveToFile(filename); -- 清空undoredoManager app.undoRedoManager:clear(); end -- 创建测试模型 local function createTestHero(modelFile) -- 这里需要跟游戏里面保持一致 -- 所有需要创建一个中间节点 local heroView; local pathName , baseName , ext = string.splitFilename(modelFile); if string.lower(ext) == "gpb" then heroView = cc.Node:create(); local skeleton = cc.ModelNode:create(modelFile); createHeroEntity(skeleton); skeleton.selectTest = function(rect)return false end heroView:addChild(skeleton); heroView.ModelNode = skeleton; heroView.getSelectBox = function()return skeleton:getSelectBox()end -- 默认播放站立动画 --animEntity:setValue("", ); else heroView = cc.Node2D:create(); heroView:setContentSize(app.setting.ResourceSize); local node = createNodeFromFile(modelFile); heroView.ModelNode = node; heroView:addChild(node); heroView.getSelectBox = function()return node:getSelectBox();end; node:visitNode(function(n) n.selectTest = function(rect)return false;end; end); end return heroView; end -- 创建目标点和目标模型 local function createPositionNode() local skeleton = cc.ModelNode:create("res/default/DefaultPoint/DefaultPoint.gpb"); -- 默认播放站立动画 --animEntity:setValue("", ); return skeleton; end -- 激活技能编辑器时创建技能环境 function CombineEffectEditor:initCombineEffectEnv() --创建一个源模型、源点、目标模型、目标点 self.defaultCEParams = createDefaultCombineEffectParams(); -- 创建所有的根节点 self.node = cc.Node:create(); app.mainLayer:addChild(self.node); self.sourceRootNode = cc.Node:create(); self.node:addChild(self.sourceRootNode); self.sourcePosRootNode = cc.Node:create(); self.node:addChild(self.sourcePosRootNode); self.targetRootNode = cc.Node:create(); self.node:addChild(self.targetRootNode); self.targetPosRootNode = cc.Node:create(); self.node:addChild(self.targetPosRootNode); end -- 激活技能编辑器时创建技能环境 function CombineEffectEditor:unInitCombineEffectEnv() self.defaultCEParams = nil; self.node:removeFromParent(); end --C#那边调用 function CombineEffectEditor:createCEParamsNode(paramType, posWithMouse) local node = nil; if paramType == "SourceModel" then -- 创建一个源模型 node = createTestHero(app.setting.SourceModelFile); -- 加入到节点系统 self.sourceRootNode:addChild(node); elseif paramType == "TargetModel" then -- 创建一个源模型 node = createTestHero(app.setting.TargetModelFile); -- 加入到节点系统 self.targetRootNode:addChild(node); elseif paramType == "SourcePos" then -- 创建一个源模型 node = createPositionNode(); -- 加入到节点系统 self.sourcePosRootNode:addChild(node); elseif paramType == "TargetPos" then -- 创建一个源模型 node = createPositionNode(); -- 加入到节点系统 self.targetPosRootNode:addChild(node); end -- 设置世界坐标 if posWithMouse then local worldPos = app.cameraController:convertScreenToWorldPos(posWithMouse.x , posWithMouse.y); local nodePos = node:getParent():convertToNodeSpace(worldPos); node:setTranslation(worldPos); end return node; end function CombineEffectEditor:play() -- 播放一个技能 if self.ce == nil then return; end -- 先停止技能 self:stop() -- 清空数据 self.defaultCEParams.SourceNode = {}; self.defaultCEParams.TargetNode = {}; self.defaultCEParams.SourcePos = {}; self.defaultCEParams.TargetPos = {}; -- 收集技能参数 self.defaultCEParams.ParentNode = app.mainLayer; self.defaultCEParams.CameraNode = app:getMainCameraShakeNode() -- 源模型 for i, v in pairs(self.sourceRootNode:getChildren()) do table.insert(self.defaultCEParams.SourceNode, v.ModelNode); end -- 目标模型 for i, v in pairs(self.targetRootNode:getChildren()) do table.insert(self.defaultCEParams.TargetNode, v.ModelNode); end -- 源点 for i, v in pairs(self.sourcePosRootNode:getChildren()) do -- 获取坐标点 local pos = getWorldPositionToNode(v, self.defaultCEParams.ParentNode); table.insert(self.defaultCEParams.SourcePos, pos); end -- 目标点 for i, v in pairs(self.targetPosRootNode:getChildren()) do -- 获取坐标点 local pos = getWorldPositionToNode(v, self.defaultCEParams.ParentNode); table.insert(self.defaultCEParams.TargetPos, pos); end -- 创建一个action来播放 self.CombineEffectAction = cc.CombineEffectAction:createWithInstance(self.ce, self.defaultCEParams, nil, nil) self.node:runAction(self.CombineEffectAction) -- 检查技能是否为无限长 self:checkCombineEffectInfinity() end function CombineEffectEditor:stop() if not tolua.isnull(self.CombineEffectAction) then self.node:stopAction(self.CombineEffectAction) self.CombineEffectAction = nil end if not tolua.isnull(self.ce) then self.ce:stop() end end -- 检测技能是否无限长 function CombineEffectEditor:checkCombineEffectInfinity() if self.ce == nil then return end local text = "" local hitCount = 0; for i , v in pairs(self.ce:getChildren()) do if v:isInfinite() then text = text .. "轨迹名字:" .. v:getName() .. " 轨迹ID:" .. tostring(v:getTrackId()) .. "为无限长,请注意!!!\n"; end if v:getStartEventName() == "OnHit" then hitCount = hitCount + 1; end end if hitCount ~= 1 then if hitCount == 0 then text = text .. "OnHit事件没配置,必须配置一个OnHit事件!!\n"; else text = text .. "OnHit事件被配置了多于1个,只能配置一个OnHit事件!!\n"; end end if text == "" then self.InfinityTipTextNode:setVisible(false) else self.debugText:setText(text); self.InfinityTipTextNode:setVisible(true) end end -- 关闭光效 function CombineEffectEditor:closeCombineEffect() if not tolua.isnull(self.CombineEffectAction) then self.node:stopAction(self.CombineEffectAction) self.CombineEffectAction = nil end -- 释放技能 if not tolua.isnull(self.ce) then self.ce:release() end end -- 创建新的光效 function CombineEffectEditor:newCombineEffect() self:closeCombineEffect(); self.ce = cc.CombineEffect:create(); self.ce:retain() return self.ce; end function CombineEffectEditor:loadCombineEffect(ceFile) self:closeCombineEffect(); local ce = createCombineEffect(ceFile); self.ce = ce; self.ce:retain() -- 检查技能是否为无限长 self:checkCombineEffectInfinity() return self.ce; end -- 删除所有选中的节点 -- 技能编辑器根其他编辑器不一样,这里不支持撤销 function CombineEffectEditor:commandDeleteSelectNodes() if next(self.SelectedNodes) == nil then return; end -- 这里需要自己搜集,因为self.sourceRootNode等空节点也会被select出来所以这里需要手动搜索 -- 搜集技能参数 local ceNodes = {} -- 源模型 for i, v in pairs(self.sourceRootNode:getChildren()) do if self.SelectedNodes[v] then table.insert(ceNodes, v); end end -- 目标模型 for i, v in pairs(self.targetRootNode:getChildren()) do if self.SelectedNodes[v] then table.insert(ceNodes, v); end end -- 源点 for i, v in pairs(self.sourcePosRootNode:getChildren()) do if self.SelectedNodes[v] then table.insert(ceNodes, v); end end -- 目标点 for i, v in pairs(self.targetPosRootNode:getChildren()) do if self.SelectedNodes[v] then table.insert(ceNodes, v); end end for i,v in pairs(ceNodes) do self:deleteNode(v); end end -- 删除一个轨迹 function CombineEffectEditor:commandDeleteTrack(track) local command = Commands:deleteTrack(self.ce, track); app.undoRedoManager:doCommand(command); end -- 通过命令创建一个轨迹 function CombineEffectEditor:commandCreateTrack(trackType) local track = cc[trackType]:create(); local command = Commands:createTrack(self.ce, track); app.undoRedoManager:doCommand(command); end -- 复制节点到另一个节点下面 function CombineEffectEditor:commandCopyNode(track) track:setTrackId(0) local command = Commands:createTrack(self.ce, track); app.undoRedoManager:doCommand(command); end -- 设置背景场景 function CombineEffectEditor:setSceneFile(sceneFile) if self.SceneFile then self.SceneFile:removeFromParent(); end local node = createNodeFromFile(sceneFile); self.SceneFile = node; self.node:addChild(node); end return CombineEffectEditor;