quick-cocos2d-x 学习系列之十六 塔防完结
quick-cocos2d-x 学习系列之十六 塔防完结
1.math2d.lua文件该文件实现了常用的数学函数。 Dist函数实现两点的距离。 radians4point求两点的夹角(弧度) pointAtCircle求圆上一个点的位置 pointAtLineToPoint求线段上与指定点距离最近的点 degrees2radians角度转换为弧度 radians2degrees弧度转换为角度 2.utils.lua文件2.1drawCircle返回newCircle. 根据utils.useNVGDrawNode变量采用不同的方式。 如果utils.useNVGDrawNode为true,则返回NVGDrawNode. 2.2drawRect同drawCircle函数,返回矩形。 2.3drawPolygon同drawCircle函数,返回多变形。 Editor文件夹这个文件夹中都是和地图编辑相关的文件。 1.AutoLayout.lua定义了函数function AutoLayout.alignItemsHorizontally(items,x,y,padding,lines) 用于实现Item水平对齐。 2.EditorConstants.lua该文件定义里一个表结构EditorConstants local EditorConstants = {} EditorConstants.CHECK_POINT_DIST= 6 EditorConstants.SELECTED_COLOR= {255,255, 255} EditorConstants.SELECTED_LABEL_COLOR= {0,0,255} EditorConstants.UNSELECTED_COLOR= {180,180, 180} EditorConstants.UNSELECTED_LABEL_COLOR = {0,0} EditorConstants.LABEL_OFFSET_Y= 4 EditorConstants.LABEL_FONT= display.DEFAULT_TTF_FONT EditorConstants.LABEL_FONT_SIZE= 14 EditorConstants.LABEL_ZORDER= 100 EditorConstants.POLYGON_ZORDER= 1000 EditorConstants.CIRCLE_ZORDER= 2000 EditorConstants.FLAG_ZORDER= 3000 EditorConstants.RANGE_HANDLER_ZORDER= 4000 EditorConstants.BINDING_LABEL_ZORDER= 5000 EditorConstants.PANEL_ZORDER= 10000 EditorConstants.MAP_PADDING= 200 EditorConstants.MAP_TOOLBAR_HEIGHT= 48 EditorConstants.PROPERTY_PREFIX_LEN= 16 EditorConstants.BEHAVIOR_LABEL_WIDTH= 110 EditorConstants.INSPECTOR_WIDTH= 360 EditorConstants.PANEL_BUTTON_SIZE= 40 EditorConstants.PANEL_BUTTON_OFFSET= 4 EditorConstants.PANEL_OFFSET= 4 EditorConstants.PANEL_LABEL_FONT= "Courier" EditorConstants.PANEL_LABEL_FONT_SIZE= 13 EditorConstants.TOOLBAR_PADDING= 40 return EditorConstants 3.EditorScene.lua定义一个EditorScene类。是编辑类的入口。 ctor构造函数,设置变量self.toolbarLines = 1 self.editorUIScale = 1 self.statusCount_ = 1,根据平台设置变量editorUIScale,toolbarLines。 通过图片EditorBg创建newTilesSprite。 创建mapLayer,包含地图的整个视图 self.mapLayer_ = display.newNode() self.mapLayer_:align(display.LEFT_BOTTOM,0) self:addChild(self.mapLayer_) 创建touchLayer用于接收触摸事件 self.touchLayer_ = display.newLayer() self:addChild(self.touchLayer_) 创建uiLayer 用于显示编辑器的 UI(工具栏等) self.uiLayer_ = display.newNode() self.uiLayer_:setPosition(display.cx,display.cy) self:addChild(self.uiLayer_) -- 创建地图对象,地图项次查看app.map.Map.lua文件 self.map_ = require("app.map.Map").new(LEVEL_ID,true) -- 参数:地图ID,是否是编辑器模式 self.map_:init() self.map_:createView(self.mapLayer_) -- 创建工具栏 self.toolbar_ = require("editor.Toolbar").new(self.map_) self.toolbar_:addTool(require("editor.GeneralTool").new(self.toolbar_,self.map_)) self.toolbar_:addTool(require("editor.ObjectTool").new(self.toolbar_,self.map_)) self.toolbar_:addTool(require("editor.PathTool").new(self.toolbar_,self.map_)) self.toolbar_:addTool(require("editor.RangeTool").new(self.toolbar_,self.map_)) -- 创建工具栏的视图 self.toolbarView_ =self.toolbar_:createView(self.uiLayer_, "#ToolbarBg.png",EditorConstants.TOOLBAR_PADDING,self.editorUIScale,self.toolbarLines) self.toolbarView_:setPosition(display.c_left,display.c_bottom) self.toolbar_:setDefaultTouchTool("GeneralTool") self.toolbar_:selectButton("GeneralTool",1) -- 创建对象信息面板 local objectInspectorScale = 1 self.objectInspector_ = require("editor.ObjectInspector").new(self.map_,objectInspectorScale,self.toolbarLines) self.objectInspector_:addEventListener("UPDATE_OBJECT",function(event) self.toolbar_:dispatchEvent(event) end) self.objectInspector_:createView(self.uiLayer_) -- 创建地图名称文字标签 self.mapNameLabel_ = cc.ui.UILabel.new({ text= string.format("module: %s,image: %s",self.map_.mapModuleName_,self.map_.imageName_), size= 16 *self.editorUIScale, align = cc.ui.TEXT_ALIGN_LEFT, x= display.left + 10, y= display.bottom + EditorConstants.MAP_TOOLBAR_HEIGHT *self.editorUIScale * self.toolbarLines + 20, }):align(display.CENTER) self.mapNameLabel_:enableOutline(cc.c4b(255,0), 2) self.mapLayer_:addChild(self.mapNameLabel_) -- 注册工具栏事件 self.toolbar_:addEventListener("SELECT_OBJECT",function(event) self.objectInspector_:setObject(event.object) end) self.toolbar_:addEventListener("UPDATE_OBJECT",function(event) self.objectInspector_:setObject(event.object) end) self.toolbar_:addEventListener("UNSELECT_OBJECT",function(event) self.objectInspector_:removeObject() end) self.toolbar_:addEventListener("PLAY_MAP",function() self:playMap() end) -- 创建运行地图时的工具栏 self.playToolbar_ = display.newNode() if (device.platform == "mac" or device.platform == "windows") then cc.ui.UIPushButton.new({normal = "#ToggleDebugButton.png",pressed = "#ToggleDebugButtonSelected.png"}) :onButtonClicked(function(event) self.map_:setDebugViewEnabled(notself.map_:isDebugViewEnabled()) end) :align(display.CENTER,display.left + 32 *self.editorUIScale,display.top - 32 * self.editorUIScale) :addTo(self.playToolbar_) :setScale(self.editorUIScale) cc.ui.UIPushButton.new({normal = "#StopMapButton.png",pressed = "#StopMapButtonSelected.png"}) :onButtonClicked(function(event) self:editMap() end) :align(display.CENTER,display.left + 88 * self.editorUIScale,display.top - 32 *self.editorUIScale) :addTo(self.playToolbar_) :setScale(self.editorUIScale) else self.recordBtnBg_ =cc.LayerColor:create(cc.c4b(255, 120)):addTo(self) self.recordBtnBg_:setTouchEnabled(false) self.recordBtn_ = cc.ui.UIPushButton.new("GreenButton.png",{scale9 = true}) :setButtonLabel(cc.ui.UILabel.new({text= "开始性能测试",size = 20,color =display.COLOR_BLACK})) :setButtonSize(130, 40) :align(display.CENTER,display.cx,display.cy) :addTo(self.recordBtnBg_) :onButtonClicked(function() self.mapLayer_:setPositionY(60) -- self.mapRuntime_:setPositionY(60) self.mapRuntime_:startPlay() self:disabelResult() self:disableStatus() self:showStatusCurve() self:statusTimerBegin() self.recordBtnBg_:removeSelf() self.recordBtnBg_ = nil end) end
self.playToolbar_:setVisible(false) self:addChild(self.playToolbar_) --根据运行平台选择运行editMap还是playMap if (device.platform == "mac" or device.platform == "windows") then self:editMap() else self:playMap() end 1.1playMap隐藏编辑器界面,保存地图当前状态,强制垃圾回收,执行地图. 1.2editMap编辑地图 1.3tick1.4onTouch1.5onEnter1.6onExit1.7showStatusCurve1.8disableStatus1.9addFPS1.10statusTimerBegin1.11statusTimerEnd1.12showResult1.13disabelResult4.GeneralTool.lua基于ToolBase类。 5.ObjectInspector.lua创建类ObjectInspector。 6.ObjectTool.lua基于ToolBase类。 7.PathTool.lua基于ToolBase类。 8.RangeTool.lua基于ToolBase类。 9.Toolbar.lua创建类Toolbar。 10.ToolBase.lua创建类toolbase。是其他tool类的基类。 创建变量如下 ToolBase.TOUCH_IGNORED= "ignored" ToolBase.DEFAULT_TOUCH_ENDED = "ended" 初始化构造函数中设置类中变量 self.name_ = name self.toolbar_= toolbar self.map_= map self.selectedButtonName_= nil
APP.properties文件夹这个文件夹中的文件定义的是全是属性,包括建筑、NPC、Player、静态对象、静态对象装饰以及箭塔。 1.BuildingProperties.lua(完)该文件定义建筑的属性。 返回一个变量BuildingProperties,该变量中实现了一个函数 BuildingProperties.get(id)。
2.NPCProperties.lua(完)定义NPC的属性,返回变量NPCProperties,其中规定函数 function NPCProperties.get(id) return clone(defines[id]) end 3.PlayerProperties.lua(完)定义Player的属性,返回变量PlayerProperties,其中规定函数 function PlayerProperties.get(id) return clone(defines[id]) end 4.StaticObjectsDecorationProperties.lua(完)定义静态物体的装饰属性,StaticObjectsDecorationProperties 包括建筑和舰船。 5.StaticObjectsProperties.lua(完)定义了所有的静态对象,StaticObjectsProperties 6.TowerProperties.lua(完)定义塔的属性,返回TowerProperties,箭塔4个级别。 App.map文件夹定义的是和地图相关文件,主要入口是MAP.LUA文件。包含了bullets文件夹和behaviors文件夹。Bullets文件夹中定义了和子弹相关的类。Behaviors文件夹中定义了以BehaviorBase为基类的类。 1.Map.lua这个是地图相关的入口。 该文件中先导入4个文件如下: local MapConstants = require("app.map.MapConstants") local MapCamera = require("app.map.MapCamera") local ObjectFactory = require("app.map.ObjectFactory") local Path = require("app.map.Path") 创建一个Map类。 Map.new() 创建 Map 对象实例 Map:init() 初始化 Map 对象 Map:createView() 创建 Map 对象的视图 Map:removeView() 删除 Map 对象的视图 Map:updateView() 更新 Map 对象的视图 Map:destroy() 销毁 Map 对象 Map:newObject() 创建新的地图子对象,并绑定行为 如果此时视图已经创建,则调用子对象的 createView()
1.1ctor在EditorScene.lus的构造函数中调用,如下: self.map_ = require("app.map.Map").new(LEVEL_ID,是否是编辑器模式 self.map_:init() self.map_:createView(self.mapLayer_)
构造函数中两个参数一个是id,一个是debug。 self.mapModuleName_ = string.format("maps.Map%sData", id) self.eventModuleName_ = string.format("maps.Map%sEvents",id) 得到地图的数据文件和时间文件。指向maps.MapA0002Data,maps.MapA0002Events. 此处会使用pcall函数,获取maps.Map0002Data中数据,详解后面解释。 见该数据复制给self.data_变量。(注意clone函数并非lua脚本的命令)
1.2Init函数从self.data_变量中获取 self.width_ = self.data_.size.width self.height_= self.data_.size.height self.imageName_ = self.data_.imageName 如果没有得到imageName_值,则再手动创建之。 -- 添加地图数据中的对象,state本身还是个table类。其中string.split函数 --传入字符串和分隔符,返回分割后的table,classId此处是range,path,static这3种字符串。 for id,state in pairs(self.data_.objects) do local classId = unpack(string.split(id,":")) self:newObject(classId,state,id) end -- 验证所有的路径 for i,path in pairs(self:getObjectsByClassId("path")) do path:validate() if not path:isValid() then echoInfo(string.format("Map:init() - invalid path %s",path:getId())) self:removeObject(path) end end -- 验证其他对象 for id,object in pairs(self.objects_) do local classId = object:getClassId() if classId ~= "path" then object:validate() if not object:isValid() then echoInfo(string.format("Map:init() - invalid object %s",object:getId())) self:removeObject(object) end end end -- 计算地图位移限定值 self.camera_ = MapCamera.new(self) self.camera_:resetOffsetLimit() -- 地图已经准备好 self.ready_ = true
--init函数完成map的初始化工作。 1.3newObject输入参数classId,state,id State是object的table变量,包含一个索引为points的x,y坐标集。Id是一个类似 path:1的字符串,classId是一个path,static或则range。 函数中调用ObjectFactory.newObject函数。 ObjectFactory是在ObjectFactory.lua文件中定义的函数。 调用object:setDebug(self.debug_)函数 调用object:setDebugViewEnabled(self.debugViewEnabled_) object:resetAllBehaviors() 这些函数都在ObjectBase类中定义的原型。 1.4removeObject1.5getClassId1.6getObjectsByClassId2.BulletFactory.lua创建一个子弹对象。 3.BulletType.lua(完)该文件定义里子弹类型 定义了变量BulletType local BulletType = {} BulletType.ARROW = 1 BulletType.CANNON = 2 return BulletType 4.Decoration.lua创建一个Decoration类,这个是个装饰类。 5.MapConstants(完)该文件中定义里一个表结构MapConstants,相关变量都设置在此处。 local MapConstants = {} MapConstants.SIDE_BAR_WIDTH= 110 MapConstants.PLAY_DEFAULT_SCALE= 0.7 MapConstants.ZOOM_TIME= 0.1 MapConstants.FIRE_RANGE_SIZE= 128 MapConstants.FIRE_RANGE_SCALE_Y= 0.8 MapConstants.FIRE_RANGE_ZORDER= 150 MapConstants.DEFAULT_OBJECT_ZORDER= 100 MapConstants.MAX_OBJECT_ZORDER= 20000 MapConstants.BULLET_ZORDER= 21000 MapConstants.NORMAL_TRACKING_SPEED= 3 MapConstants.FAST_TRACKING_SPEED= 12 MapConstants.SET_FAST_TRACKING_DIST = display.height / 3 MapConstants.CROSS_POINT_TAP_RADIUS = 50 MapConstants.HP_BAR_ZORDER= 30000 MapConstants.HP_BAR_OFFSET_Y= 20 MapConstants.RADIUS_CIRCLE_SCALE_Y= 0.85 MapConstants.LEVEL_LABEL_OFFSET_Y= 26 MapConstants.LEVEL_LABEL_FONT= display.DEFAULT_TTF_FONT MapConstants.LEVEL_LABEL_FONT_SIZE= 16 MapConstants.PLAYER_CAMP= 1 MapConstants.ENEMY_CAMP= 2 return MapConstants 6.MapCamera该函数导入MapConstants变量,创建MapCamera类。 主要是实现地图的一些视角。主要函数如下: 1.1getMargin1.2setMargin1.3getScale地方 1.4setScale1.5zoomTo1.6getOffset1.7setOffset1.8moveOffset1.9getOffsetLimit1.10resetOffsetLimit1.11convertToMapPosition1.12convertToWorldPosition1.13convertToCameraPosition7.MapEvent.lua地图中相关事件的定义。如下: local MapEvent = {} MapEvent.MAP_PREPARE_PLAY= "MAP_PREPARE_START" MapEvent.MAP_START_PLAY= "MAP_START_PLAY" MapEvent.MAP_STOP_PLAY= "MAP_STOP_PLAY" MapEvent.MAP_PAUSE_PLAY= "MAP_PAUSE_PLAY" MapEvent.MAP_RESUME_PLAY= "MAP_RESUMT_PLAY" MapEvent.MAP_TIME= "MAP_TIME" MapEvent.OBJECT_ENTER_RANGE= "OBJECT_ENTER_RANGE" MapEvent.OBJECT_EXIT_RANGE= "OBJECT_EXIT_RANGE" MapEvent.OBJECT_IN_RANGE= "OBJECT_IN_RANGE" MapEvent.OBJECT_COLLISION_BEGAN= "OBJECT_COLLISION_BEGAN" MapEvent.OBJECT_COLLISION_ENDED= "OBJECT_COLLISION_ENDED" MapEvent.OBJECT_DESTROY= "OBJECT_DESTROY" return MapEvent 8.MapEventHandler.lua定义一个类。需要其他文件 local MapConstants = require("app.map.MapConstants") local MapEvent = require("app.map.MapEvent") local MovableBehavior = require("app.map.behaviors.MovableBehavior") local BulletBase = require("app.map.bullets.BulletBase") 9.MapRuntime.lua创建一个MapRuntime类。 10.ObjectFactory导入3个文件如下 local StaticObject = require("app.map.StaticObject") local Path = require("app.map.Path") local Range = require("app.map.Range") 1.1newObject在ObjectFactory文件中主要定义了这个函数。 输入4个参数classId,id,map. 根据map是否是debug,设置变量debug. 根据classId的三个字符串static,range设置3条执行路径。 分别是 StaticObject.new(id,map) Path.new(id,map) Range.new(id,map) 注:StaticObject,Path,Range都是基于ObjectBase的 类, 最后返回得到一个object对象,然后调用object:init(). 如果不是三个字符串static,range字符串中一个则退出。 此外还判断是否是isDebug,如果是调试则分别执行 object:bindBehavior("StaticObjectEditorBehavior") object:bindBehavior("PathEditorBehavior") object:bindBehavior("RangeEditorBehavior") (完) 11.Path该文件创建了一个Path类,基于ObjectBase类。 1.1Path:ctor三个参数id,map.其中state是一个表结构object,里面有一个points={}的值。其索引必定是path:1之类的。 获取points表结构的x,赋值给state.x,state.y同时调用父类的ctor(self,map),参数和传给path:ctor 相比多了一个self参数。说明Path:ctor把自己这个对象传给了父类,可谓父子情深。最后返回包含变量points_给自己。 最后设置变量valid_ ,如果# self.points_ > 0 则就是true. (完) 1.2Path:getPoint(index)1.3Path:getPointsCount()1.4Path:appendPoint(x,y)1.5Path:insertPointAfterIndex1.6Path:movePoint(index,y)1.7Path:removePoint(index)1.8Path:checkPointAtPoint(x,checkDist)1.9Path:checkPointAtSegment(x,checkDist)1.10Path:vardump()1.11Path:dump(label)12.StaticObject创建StaticObject类也基于ObjectBase类。 13.Range创建range类也基于ObjectBase类。 14.ObjectBase创建一个ObjectBase类。 创建3个变量 ObjectBase.CLASS_INDEX_PATH= 1 ObjectBase.CLASS_INDEX_RANGE= 2 ObjectBase.CLASS_INDEX_STATIC = 3 有3个儿子类么。 ObjectBase:ctor(id,map)构造函数先判断state是否是table,如果不是则报错。 将state的索引类似path:1或者state:3或者range:3和points表重新赋值给 self[kn]=v( k是points,v是点集合)如下 for k,v in pairs(state) do local kn = k .. "_" self[kn] = v end 同时设置其他的变量值如下 local classId,index = unpack(string.split(id,":")) self.map_ = map self.id_ = id self.classId_ = classId self.classIndex_ = ObjectBase.CLASS_INDEX[classId] self.index_ = checkint(index) self.x_ = checkint(self.x_) self.y_ = checkint(self.y_) self.offsetX_ = checkint(self.offsetX_) self.offsetY_ = checkint(self.offsetY_) self.state_ = state self.valid_ = false self.play_ = false self.tag_ = 0 self.sprite_ = nil self.debug_ = false self.debugViewEnabled_ = false if type(self.viewZOrdered_) ~= "boolean" then self.viewZOrdered_ = true end 返回给子类(完) ObjectBase:init()该函数在ObjectFactory.newObject函数中被调用, 判断self.behaviors_变量,如果为false就直接退出。 处理类似 local object = { behaviors = { "CampBehavior", "CollisionBehavior", "DecorateBehavior", "DestroyedBehavior", "FireBehavior", "TowerBehavior", }, campId = 1, collisionEnabled = true, decorationsMore = { }, defineId = "PlayerTower01", flipSprite = false, tag = 0, towerId = "PlayerTower01L01", x = 454, y = 465, } objects["static:1"] = object的对象 如果没有behaviors则就退出。不过static:1这种的就肯定会执行了。 判断是一个string还是其他(table),赋值给函数中的局部变量。 然后循环执行self:bindBehavior(behaviorName) (完) ObjectBase:isDebug()ObjectBase:setDebug(isDebugEnabled)ObjectBase:isDebugViewEnabled()ObjectBase:setDebugViewEnabled(isDebugViewEnabled)ObjectBase:getId()ObjectBase:getClassId()ObjectBase:getIndex()ObjectBase:validate()ObjectBase:isValid()ObjectBase:getTag()ObjectBase:setTag(tag)ObjectBase:getPosition()ObjectBase:setPosition(x,y)ObjectBase:isViewCreated()ObjectBase:isViewZOrdered()ObjectBase:getView()ObjectBase:createView(batch,marksLayer,debugLayer)ObjectBase:removeView()ObjectBase:updateView()ObjectBase:preparePlay()ObjectBase:startPlay()ObjectBase:stopPlay()ObjectBase:isPlay()ObjectBase:hasBehavior(behaviorName)ObjectBase:bindBehavior(behaviorName)该函数被init()函数调用。 该函数的参数是"CampBehavior", "CollisionBehavior","DecorateBehavior", "DestroyedBehavior","FireBehavior","TowerBehavior"等等中的一个字符串。 判断self.behaviorObjects_,如果没有值则设置为{}。(第一次调用时候会使用) 判断self.behaviorObjects_[behaviorName]如果不为空,说明已经设置了,就直接退出。 然后调用BehaviorFactory.createBehavior(behaviorName)返回给behavior。 获取behavior实例中的getDepends参数,例如: local depends = { "DestroyedBehavior", }在BuildingBehavior.lua文件中。 然后递归调用self:bindBehavior(dependBehaviorName) 创建self.behaviorDepends_变量,首次为空。创建 self.behaviorDepends_[dependBehaviorName] ={},首次为空,然后将这插入到表中。 table.insert(self.behaviorDepends_[dependBehaviorName],behaviorName) 。(将behaviorName依赖的behavior存到self.behaviorDepends_中。) 然后调用behavior:bind(self) 设置self.behaviorObjects_[behaviorName]= behavior,接着将behavior加入到变量behaviorObjects_中。 最后调用ObjectBase:resetAllBehaviors() (完) ObjectBase:unbindBehavior(behaviorName)ObjectBase:resetAllBehaviors()被函数ObjectBase:bindBehavior(behaviorName)调用。 解析变量self.behaviorObjects_中的behavior,复制给behaviors数组。 根据优先级进行排序。最后调用behavior:reset(self)。 ObjectBase:bindMethod(behavior,methodName,method,callOriginMethodLast)ObjectBase:unbindMethod(behavior,methodName)ObjectBase:vardump()ObjectBase:dump(label)Behaviors文件夹文件BehaviorBase.lua该类是其他各种Behavior的基类。 l Ctor (behaviorName,depends,priority,conflictions)self.name_ = behaviorName self.depends_ =checktable(depends) self.priority_ =checkint(priority) -- 行为集合初始化时的优先级,越大越先初始化 self.conflictions_ = checktable(conflictions) l BehaviorBase:getName()返回 self.priority_ l BehaviorBase:getDepends()返回self.depends_变量。 l BehaviorBase:getPriority()返回优先级 return self.priority_ l BehaviorBase:getConflictions()返回变量self.conflictions_ return self.conflictions_ l BehaviorBase:bind(object)父类中为实现,需要子类根据需要去实现。 l BehaviorBase:unbind(object)父类中为实现,需要子类根据需要去实现。 l BehaviorBase:reset(object)父类中为实现,需要子类根据需要去实现。 BehaviorFactory这个文件中定义了behaviorsClass表。定义了所有的behavior. local behaviorsClass = { CollisionBehavior = require("app.map.behaviors.CollisionBehavior"), CampBehavior = require("app.map.behaviors.CampBehavior"), DecorateBehavior = require("app.map.behaviors.DecorateBehavior"), BuildingBehavior = require("app.map.behaviors.BuildingBehavior"), FireBehavior = require("app.map.behaviors.FireBehavior"), MovableBehavior = require("app.map.behaviors.MovableBehavior"), DestroyedBehavior = require("app.map.behaviors.DestroyedBehavior"), TowerBehavior = require("app.map.behaviors.TowerBehavior"), NPCBehavior = require("app.map.behaviors.NPCBehavior"), PathEditorBehavior = require("app.map.behaviors.PathEditorBehavior"), RangeEditorBehavior = require("app.map.behaviors.RangeEditorBehavior"), StaticObjectEditorBehavior = require("app.map.behaviors.StaticObjectEditorBehavior"), } BehaviorFactory.createBehavior(behaviorName)在文件objectBase.lua的文件中被函数 local behavior = BehaviorFactory.createBehavior(behaviorName)调用。 通过参数获得class. local class = behaviorsClass[behaviorName] assert(class ~= nil,string.format("BehaviorFactory.createBehavior() - Invalid behavior name"%s"",tostring(behaviorName))) class.new() 返回相应的类实例。 BehaviorFactory.getAllStaticObjectBehaviorsName()获取所有静态物体的behaviors行为名字。. BehaviorFactory.isStaticObjectBehavior(behaviorName)获取静态行为是否开启。 BuildingBehavior创建BuildingBehavior,继承于BehaviorBase。 l ctor有局部变量depends local depends = { "DestroyedBehavior", } 调用父节点的ctor函数。 BuildingBehavior.super.ctor(self,"BuildingBehavior",100) 设置 self.name_ = behaviorName self.depends_ = checktable(depends) self.priority_ = checkint(priority) -- 行为集合初始化时的优先级,越大越先初始化 self.conflictions_ = checktable(conflictions) 最后返回一个类实例。 l BuildingBehavior:bind(object)获取对象的buildingId_ object.buildingId_ = object.state_.buildingId 包括对该变量的判断,如果不是字符串则赋值为空。 函数中定义了4个函数getBuildingId,setBuildingId,showDestroyedStatus,vardump 通过调用object:bindMethod函数都绑定到object上。 getBuildingId函数,调用return object.buildingId_。 setBuildingId函数,设置object.buildingId_,通过BuildingProperties获得object.buildingId_的定义,如果没有得到该值则判断object.campId_是否等于1,如果成立则object.buildingId_ = "BuildingP001",否则object.buildingId_ = "BuildingN001"。(这个主要两个方向,是否需要护甲) 最后设置define中的表,较索引都下一个下划线_。 showDestroyedStatus函数,视图不可见,显示装饰。 object:getView():setVisible(false) object:getDecoration(object.defineId_ .. "Destroyed"):getView():setVisible(true) vardump函数,如下。 state.buildingId = object.buildingId_ return state l BuildingBehavior:unbind(object)调用object:unbindMethod,移除 4个函数getBuildingId,setBuildingId,showDestroyedStatus,vardump l BuildingBehavior:reset(object)调用如下函数: object:setBuildingId(object:getBuildingId()) CampBehavior.lua创建CampBehavior,继承于BehaviorBase。 l CampBehavior:ctor()调用父类的构造函数。 l CampBehavior:bind(object)绑定2个函数,getCampId,vardump。 getCampId函数,返回object.campId_ vardump函数 state.campId = object.campId_ return state l CampBehavior:unbind(object)解除2个函数的绑定。 CollisionBehavior创建CollisionBehavior,继承于BehaviorBase。 l CollisionBehavior:ctor()调用父类的构造函数。 l CollisionBehavior:bind(object)绑定5个函数isCollisionEnabled,setCollisionEnabled,addCollisionLock。removeCollisionLock,vardump。 isCollisionEnabled函数 return object.collisionEnabled_ setCollisionEnabled函数 object.collisionEnabled_ = enabled addCollisionLock函数 object.collisionLock_ = object.collisionLock_+ 1 removeCollisionLock函数 object.collisionLock_ = object.collisionLock_ - 1 assert(object.collisionLock_ >= 0, "CollisionBehavior.removeCollisionLock()- object.collisionLock_ must >= 0") vardump函数,如下 state.collisionEnabled = object.collisionEnabled_ return state l CollisionBehavior:unbind(object)解除5个函数的绑定。 DecorateBehavior创建DecorateBehavior,继承于BehaviorBase l DecorateBehavior:ctor()调用父类。 l DecorateBehavior:bind(object)绑定8个函数给object. 起先设置 for i,k in ipairs(checktable(object.state_.decorations)) do object.decorations_[k] = false end 再设置: for i,k in ipairs(checktable(object.state_.decorationsMore)) do object.decorationsMore_[k] = false end isDecorationExists函数 return object.decorations_[decorationName]~= nil getDecoration函数 return object.decorations_[decorationName] updateView函数 其中定义了局部函数local function updateView_(source)。 该函数更新视图。 fastUpdateView函数 removeView函数 定义了一个局部函数local function removeView_(source) if not source then return end for decorationName,decoration in pairs(source) do if decoration then decoration:removeView() end source[decorationName] = false end end 再调用removeView_(object.decorations_) removeView_(object.decorationsMore_) setVisible函数 for decorationName,decoration in pairs(object.decorations_) do if decoration then local view = decoration:getView() view:setVisible(decoration.visible_ and visible) end end fadeTo函数 local function fadeTo(object,opacity,time) transition.fadeTo(object:getView(),{opacity = opacity,time = time}) for decorationName,decoration in pairs(object.decorations_) do if decoration then local view = decoration:getView() if view:isVisible() then transition.fadeTo(view,time = time}) end end end end vardump函数 l DecorateBehavior:unbind(object)解除绑定的8个函数。 DestroyedBehavior创建DestroyedBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 FireBehavior创建FireBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 MovableBehavior创建MovableBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 NPCBehavior创建NPCBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 PathEditorBehavior创建PathEditorBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 RangeEditorBehavior创建RangeEditorBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 StaticObjectEditorBehavior创建StaticObjectEditorBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 TowerBehavior创建TowerBehavior,继承于BehaviorBase 基本同其他behavior,存在细节差异。 Bullet文件夹文件ArrowBullet.lua继承与BulletBase类 l ArrowBullet:ctor(source,target,delay)设置参数params 调用父节点的构造函数。 l ArrowBullet:fireBegan()调用父节点的fireBegin(). l ArrowBullet:hit()击中目标后调用。 创建破坏的箭头精灵。设置旋转角度。 获取目标视图,获取飞行距离。 最后子弹精灵fadeout,删除自身。 BulletBase该类是其他3个子弹类的基类。其他类都基于此类。 l BulletBase:ctor(source,sprite,delay)构造函数中定义了基类的变量,如下,四个变量时来自构造函数的,需要注意的是self_delay_这个变量设置的时候需要checknumber操作。Self_damage_变量操作的时候,随机一个最小伤害到最大伤害的值(这个是游戏中常用的手段)。此外定义了起始的位置。 self.source_ = source self.target_ = target self.sprite_ = sprite self.delay_ = checknumber(delay) self.flag_ = 0 self.damage_ = math.random(source.minDamage_,source.maxDamage_) self.damageScale_ = 1 self.hit_ = math.random(100) <= source.hitrate_ self.critical_ = math.random(100) <= source.critical_ self.startX_ = source.x_ + source.radiusOffsetX_ + source.fireOffsetX_ self.startY_ = source.y_ + source.radiusOffsetY_ + source.fireOffsetY_ self.prevX_ = self.startX_ self.prevY_ = self.startY_ self.time_ = 0 self.over_ = false self.isBegan_ = false l BulletBase:setFlag(flag)设置变量 self.flag_= flag,为其他动作判断准备。 l BulletBase:getView()返回子弹图片如下: return self.sprite_ l BulletBase:removeView()移除子弹 self.sprite_:removeSelf() l BulletBase:tick(dt)判断子弹是否已经begin,那么设置时间self.time_ = self.time_ + dt,然后调用self:tickBullet(dt)。 如果没有发射,则判断self.delay_ <= 0,满足则调用firebegin(),否则让该值减掉时间片,实现延时发射的效果。 这个tick实现了子弹发射,保证了延时发送。 l BulletBase:fireBegan()判断是否已经摧毁,如果摧毁,则设置变量后返回 self.time_ = 0 self.over_= true self.isBegan_ = false return 如果没有摧毁,则设置位置,并设置self.isBegan_ = true l BulletBase:tickBullet(dt)子类可以覆盖之。 l BulletBase:checkHit()判断是否击中(通过一个随机值来产生数值判断是否击中在ctor中实现) 未击中直接调用miss()退出。 如果击中则判断目标是否存在,因为也可能击中了但是对象已经不存在,多个攻击时候很容易出现这种情况,而且子弹还需要飞行,那么也调用miss()退出。 否则调用计算目标和子弹的举例是否小于子弹直径,如果小于直径则调用hit()退出。 其他情况下调用miss() 退出。 l BulletBase:hit()子类可以覆盖之 l BulletBase:miss()l 子类可以覆盖之 l BulletBase:isOver()返回变量self.over_,用于其他判断。 CannonBullet继承与BulletBase类。 l CannonBullet:ctor(source,delay,spriteName,params)判断params参数是否存在,如果不存在则设置params的值如下: params = { flyTime = math.random(70,85) / 100, g = -1000, delay= delay or 0.2, } 如果没有输入spriteName,则使用CannonBall01.png图片。 最后调用父类的构造函数,见BulletBase的构造函数。 l CannonBullet:fireBegan()调用父节点的fireBegan(),然后设置子弹可见。 l CannonBullet:hit()击中对象后调用,该函数在父节点没有实现,通过子类覆盖。 获取帧图片,图片长度,播放间隔,然后创建动画。最后在子弹的父类中播放。 local parent = self.sprite_:getParent() parent:addChild(boom,self.sprite_:getLocalZOrder()) CurvedBulletBase继承与BulletBase类。 l CurvedBulletBase:ctor(source,params调用父节点的构造函数。 l CurvedBulletBase:fireBegan()调用父节点的firebegin(). 如果目标正在移动,那么目标的坐标需要变成子弹飞行时间后目标移动后的位置。 通过目标的直径计算导弹落到目标的随机位置偏移。然后根据飞行时间计算X和Y方向的距离除以时间。最后设置子弹位置。 l CurvedBulletBase:tickBullet(dt)覆盖父类,父类也没有实现该函数。 计算运行的事件,计算实时的X,Y坐标,并设置子弹位置。判断是否旋转,如果是则计算角度,然后设置子弹的角度。 最后判断运行时间是否结束,如果结束则返回self.over_=true,表示结束,用于其他判断调用。 Map文件夹该文件中定义的是2个地图的数据信息。 1.MapA0001Data.lua地图的长、宽,imagename,路径1和路径2的定义,范围,定义多个对象的特性, 最后返回这些数据信息。 2.MapA0001Events.lua继承于类MapEventHandler,该类在app.map.MapEventHandler文件中定义。 --重写父类preparePlay函数,time,objectEnterRange函数。 function MyMapEventHandler:preparePlay() MyMapEventHandler.super.preparePlay(self) self.createNextEnemyDelay_= 0.1 -- 等待多少时间创建下一个敌人 self.createNextEnemyInterval_ = 3.0 -- 创建下一个敌人前的间隔时间 self.createNextEnemyOnPathIndex_ = 2 -- 下一个敌人在哪一条路径 end 3.MapA0002Data.lua逻辑上同MapA0001Data.lua。 具体实现存在个体差异。 4.MapA0002Events.lua逻辑上同MapA0001Events.lua。 具体实现存在个体差异。 1.代码执行流程先从main函数中之下如下 display.replaceScene(require("editor.EditorScene").new()) 进入到场景editor .EditorScene 包含地图的整个视图,用于接收触摸事件,显示编辑的UI,创建地图对象。 创建工具栏,创建工具栏的视图,创建对象信息面板,创建地图名称文字标签,注册工具栏事件,创建运行地图时的工具栏,最后根据不同的平台调用editMap或者playMap。 2.相关函数2.1Pcall函数Calls function This means that any error inside Parameters ·f : functionto be call in protected mode. ·... : functionarguments. Return values 1.#boolean: true plusthe result of 2.#boolean,#string:false plus the error message in case of any error. 2.2UnpackReturns theelements from the given table. This function is equivalent to return list[i],list[i+1],...,list[j] except that the above code can bewritten only for a fixed number of elements. By default, Parameters ·#table list : a tableby index ·i : index offirst value. · j :index of last value. 2.3LUA string使用·--string.len(s) ·--string.rep(s,n) ·--string.lower(s) ·--string.upper(s) ·--string.sub(s,i,j) ·-string.char函数和string.byte函数用来将字符在字符和数字之间转换. ·--string.byte(s,i)将字符串s的第i个字符的转换成整数;第二个参数是可选的,缺省情况下i=1. ·--string.format()函数来生成具有特定格式的字符串, ·--string.gsub(s,pattern,reps[,limitNumber]) 将s中所有符合pattern的字串替换为reps,返回结果串+匹配数 ·--string.gfind(s,pattern) ·--string.match(s,d) --与string.find类似 但是返回匹配的子串 --s 源字符串 --d 目标字符串或者模式 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |