码迷,mamicode.com
首页 > 其他好文 > 详细

quick-cocos2d-x 学习系列之十六 塔防完结

时间:2015-03-22 09:14:28      阅读:1607      评论:0      收藏:0      [点我收藏+]

标签:

quick-cocos2d-x 学习系列之十六 塔防完结

 

 

1.  math2d.lua文件

该文件实现了常用的数学函数。

Dist函数实现两点的距离。

radians4point求两点的夹角(弧度)

pointAtCircle求圆上一个点的位置

pointAtLineToPoint求线段上与指定点距离最近的点

degrees2radians角度转换为弧度

radians2degrees弧度转换为角度

 

2.  utils.lua文件

2.1         drawCircle

返回newCircle.

根据utils.useNVGDrawNode变量采用不同的方式。

如果utils.useNVGDrawNode为true,则返回NVGDrawNode.

 

 

 

2.2         drawRect

同drawCircle函数,返回矩形。

 

 

2.3         drawPolygon

同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, 255}

EditorConstants.SELECTED_LABEL_COLOR  = {0, 0, 255}

EditorConstants.UNSELECTED_COLOR      = {180, 180, 180, 180}

EditorConstants.UNSELECTED_LABEL_COLOR = {0, 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, 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, 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, 255, 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.3tick

 

1.4onTouch

 

1.5onEnter

 

 

 

1.6onExit

 

1.7showStatusCurve

 

1.8disableStatus

 

 

1.9addFPS

 

 

1.10        statusTimerBegin

 

 

1.11        statusTimerEnd

 

 

 

 

1.12        showResult

 

 

 

1.13        disabelResult

 

 

 

 

4.     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, true) -- 参数:地图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函数

--传入字符串和分隔符,返回分割后的tableclassId此处是range,path,static3种字符串。

    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.4removeObject

 

1.5getClassId

 

1.6getObjectsByClassId

 

2.     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.1getMargin

 

 

 

 

 

1.2setMargin

 

 

 

1.3getScale

地方

 

 

1.4setScale

 

1.5zoomTo

 

 

 

1.6getOffset

 

1.7setOffset

 

1.8moveOffset

 

 

1.9getOffsetLimit

 

1.10        resetOffsetLimit

 

1.11        convertToMapPosition

 

1.12        convertToWorldPosition

 

 

 

1.13        convertToCameraPosition

 

 

7.     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,state,map.

根据map是否是debug,设置变量debug.

根据classId的三个字符串static,path,range设置3条执行路径。

分别是

StaticObject.new(id, state, map)

Path.new(id, state, map)

Range.new(id, state, map)

注:StaticObject,Path,Range都是基于ObjectBase的 类,

最后返回得到一个object对象,然后调用object:init().

如果不是三个字符串static,path,range字符串中一个则退出。

此外还判断是否是isDebug,如果是调试则分别执行

object:bindBehavior("StaticObjectEditorBehavior")

object:bindBehavior("PathEditorBehavior")

object:bindBehavior("RangeEditorBehavior")

(完)

 

 

 

 

 

11.             Path

该文件创建了一个Path类,基于ObjectBase类。

1.1         Path:ctor

三个参数id,state,map.其中state是一个表结构object,里面有一个points={}的值。其索引必定是path:1之类的。

获取points表结构的x,y,赋值给state.x,state.y同时调用父类的ctor(self,id,state,map),参数和传给path:ctor 相比多了一个self参数。说明Path:ctor把自己这个对象传给了父类,可谓父子情深。最后返回包含变量points_给自己。

最后设置变量valid_ ,如果# self.points_ > 0 则就是true.

(完)

 

1.2         Path:getPoint(index)

 

 

 

 

1.3         Path:getPointsCount()

 

 

1.4         Path:appendPoint(x, y)

 

 

1.5         Path:insertPointAfterIndex

 

 

1.6         Path:movePoint(index, x, y)

 

 

1.7         Path:removePoint(index)

 

1.8         Path:checkPointAtPoint(x, y,checkDist)

 

 

 

 

1.9         Path:checkPointAtSegment(x, y,checkDist)

 

 

1.10    Path:vardump()

 

 

1.11    Path: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, state,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",

        "CollisionBehavior",

        "DecorateBehavior",

}在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",

        "CollisionBehavior",

        "DecorateBehavior",

    }

调用父节点的ctor函数。

BuildingBehavior.super.ctor(self,"BuildingBehavior", depends, 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, {opacity = opacity, 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, target, 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, target, 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, target, sprite, 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.1         Pcall函数

Calls function f with thegiven arguments in protected mode.

This means that any error inside f is notpropagated; instead, pcallcatches the error and returns a status code. Its first result is the statuscode (a boolean), which is true if the call succeeds without errors. In suchcase, pcallalso returns all results from the call, after this first result. In case of anyerror, pcallreturns false plus the error message.

Parameters

·        f : functionto be call in protected mode.

·        ... : functionarguments.

Return values

1.    #boolean: true plusthe result of ffunction if its call succeeds without errors.

2.    #boolean, #string:false plus the error message in case of any error.

2.2         Unpack

Returns 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, i is 1 and j is thelength of the list, as defined by the length operator.

Parameters

·        #table list : a tableby index

·        i : index offirst value.

·     j :index of last value.

 

 

 

2.3         LUA string使用  

·        --string.len(s)          
--返回字符串s的长度 

·        --string.rep(s, n)
--返回重复n次字符串s的串,你使用string.rep("a", 2^20)可以创建一个1M bytes的字符串(比如,为了测试需要);

·        --string.lower(s)
--将s中的大写字母转换成小写(string.upper将小写转换成大写).如果你想不关心大小写对一个数组进行排序的话,你可以这样:

·        --string.upper(s)
--将s中的小写字母转换成大写 

·        --string.sub(s,i,j)
--函数截取字符串s的从第i个字符到第j个字符之间的串.Lua中,字符串的第一个字符索引从1开始.你也可以使用负索引,负索引从字符串的结尾向前计数:-1指向最后一个字符,-2指向倒数第二个,以此类推.

·        -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 目标字符串或者模式

 

quick-cocos2d-x 学习系列之十六 塔防完结

标签:

原文地址:http://blog.csdn.net/notbaron/article/details/44522259

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!