CocosLua3.10 塔防類(提供思路)

參考文章:https://www.cnblogs.com/hll2008/p/4235714.html
參考文章:https://blog.csdn.net/oShunz '王國保衛(wèi)戰(zhàn)'相關(guān)內(nèi)容

注:沒有ui,純用layout寫,比較劣質(zhì)虐秋。只提供思路和寫法川背。

思路:


Mind.png

#怪物
1.怪物沿著創(chuàng)建好的地圖路徑前進砂轻。

#塔
1.塔創(chuàng)建子彈猫十,并且檢測所有怪物蚓再,當遇到某個怪物在自己的檢測只损,攻擊范圍內(nèi)一姿,則執(zhí)行攻擊子彈操作。
2.當子彈創(chuàng)建完畢并發(fā)射的時候跃惫,執(zhí)行檢測子彈周邊叮叹。當遇到怪物的話,執(zhí)行怪物掉血等操作(這里就只做了掉血)爆存。
3.移除子彈

#道路
1.默認地圖創(chuàng)建蛉顽,建立起始點,然后根據(jù)上下左右(1像素)與偏移值進行添加道路先较。
2.建立可點擊的區(qū)塊携冤。并且當選擇要創(chuàng)建的塔時悼粮,廣播創(chuàng)建塔操作。

目前完善功能:

(塔):可攻擊曾棕,可點擊創(chuàng)建
(怪物):可移動扣猫,只可代碼內(nèi)創(chuàng)建
(地圖):只有一張地圖,直接就執(zhí)行翘地。地圖路徑在代碼里面寫入申尤。

概括:
[[由一個大層(控制層),去加載次類層衙耕。由控制層去轉(zhuǎn)發(fā)內(nèi)容等操作瀑凝。然后次類層在自己執(zhí)行自己需要的操作。]]
#1 控制層:用于轉(zhuǎn)發(fā)各層內(nèi)容臭杰,數(shù)據(jù)粤咪,加載各層內(nèi)容等。
#2 地圖層:道路的總集合渴杆。創(chuàng)建地圖寥枝,創(chuàng)建怪物行走路徑,創(chuàng)建可點擊的創(chuàng)建塔的區(qū)域磁奖。
#2 建筑層:塔的總集合囊拜。創(chuàng)建塔。
#2 怪物層: 怪物的總集合比搭。創(chuàng)建怪物冠跷。

代碼:(文件路徑我用的本地的,注意更改):

 -- 全局
-- Interval = 70  -- 間隔
-- Road_Size = cc.size(60, 60)  -- 區(qū)域大小

Event_Create_Protecter = 'Event_Create_Protecter'
-- 控制層
require('app.testFile.event.Key_3_Event_File.Global.GlobalData')
local MapRoadLayer = require('app.testFile.event.Key_3_Event_File.Layer.MapRoadLayer')  -- 地圖道路層
local MonsterLayer = require('app.testFile.event.Key_3_Event_File.Layer.MonsterLayer')
local ProtecterLayer = require('app.testFile.event.Key_3_Event_File.Layer.ProtecterLayer')

local event = class('event', cc.Node)

function event:ctor()
    self:initValue()
    self:initNode()
    self:bindEvent()
end

function event:initValue()
    -- 層
    self._Layer_MapRoad = nil  -- 地圖道路層
    self._Layer_Monster = nil  -- 怪物層
    self._Layer_Protecter = nil  -- 塔防層
end

function event:initNode()
    self:initLayer()
    self:initLayerRoad()
    self:initMonster()

    self:initProtecter()
end

-- 添加背景點擊區(qū)域
function event:initLayer()
    local layout = ccui.Layout:create()
    layout:setContentSize(cc.size(display.width,display.height))
    self:addChild(layout)

    local function onTouchBegan(touch, event)
        return true
    end

    local function onTouchEnded(touch, event)
        local pos = touch:getLocation()
        self:clickEvent(pos)
    end

    -- 注冊兩個回調(diào)監(jiān)聽方法
    local listener = cc.EventListenerTouchOneByOne:create()
    listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
    listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
    local eventDispatcher = cc.Director:getInstance():getEventDispatcher()
    -- 綁定觸摸事件到層當中
    eventDispatcher:addEventListenerWithSceneGraphPriority(listener, layout)
end

function event:initLayerRoad()
    self._Layer_MapRoad = MapRoadLayer:create(self)
    self:addChild(self._Layer_MapRoad)
    self._Layer_MapRoad:createRoads()
end

function event:initMonster()
    self._Layer_Monster = MonsterLayer:create(self)
    self:addChild(self._Layer_Monster)
    self._Layer_Monster:createMonsters()
end

function event:initProtecter()
    self._Layer_Protecter = ProtecterLayer:create(self)
    self:addChild(self._Layer_Protecter)
    self._Layer_Protecter:createProtecters()    
end

function event:clickEvent(pos)
    self._Layer_Protecter:resetAllProtecterScopeCircle()

    self._Layer_MapRoad:createClickNode(pos)
end

function event:getProtecter()
    return self._Layer_Protecter
end

function event:getMonster()
    return self._Layer_Monster
end

function event:getRoads()
    return self._Layer_MapRoad
end

function event:getAllProtecter()
    return self._Layer_Protecter:getAllProtecter()
end

function event:getAllMonster()
    return self._Layer_Monster:getAllMonster()
end

function event:getAllRoads()
    return self._Layer_MapRoad:getAllRoads()
end

function event:bindEvent()
    -- enter exit事件
    local function onNodeEvent(event)
        if event == "enter" then
            self:onEnter()
        elseif event == "exit" then
            self:onExit()
        end
    end
    self:registerScriptHandler(onNodeEvent)
end

function event:onEnter()

end

function event:onExit()
    
end

return event
-- 地圖層
--[[
    第一個方塊是0,0
]]

local Start_Pos = cc.p(100, 100)  --起始坐標
local _A = cc.p(-1, 0)
local _D = cc.p(1, 0)
local _W = cc.p(0, 1)
local _S = cc.p(0, -1)

-- 道路
local Map = {
    _D,_D,_D,_D,
    _W,_W,_W,
    _D,_D,
    _S,_S,
    _D,
    _S,
    _D,_D,
    _W,_W,_W,_W,_W,
    _A,_A,_A,_A,_A,_A,_A,
    _S,_S,
    _A,_A,
    _W,_W,_W,_W,
    _D,_D,_D,_D,_D,_D,_D,_D,_D,_D,_D,
}

local Interval = 70  -- 形塊間隔
local Road_Size = cc.size(60, 60)  -- 形塊大小

local Road = require('app.testFile.event.Key_3_Event_File.Node.Road')

local MapRoad = class('MapRoad', cc.Node)
function MapRoad:ctor(data, pos)
    self:initValue()
end

function MapRoad:initValue()
    self._roads = {}
    self._roadsTable = {}
    self._clickRoads = nil
end

function MapRoad:createRoads()
    if #Map > 0 then
        self:createRoadNode(0, 0)

        -- 先轉(zhuǎn)換一下
        local tempMap = {}
        local x, y = 0, 0
        for i, v in ipairs(Map) do
            x = x + v.x
            y = y + v.y
            tempMap[i] = cc.p(x, y)
        end

        for i, v in ipairs(tempMap) do
            self:createRoadNode(v.x, v.y)
        end
    end
end

-- 創(chuàng)建道路方塊
function MapRoad:createRoadNode(x, y)
    local data = {
        Color = cc.c3b(50, 50, 50),
        Pos = cc.p(x, y),
    }

    local node = Road:create(data)
    self:addChild(node)
    node:createRoadNode()
    table.insert(self._roads, node)
    self:setRoadTable(x, y)
end

-- 創(chuàng)建可點擊方塊
function MapRoad:createClickNode(pos)
    local x = math.floor(pos.x / Interval) - 1
    local y = math.floor(pos.y / Interval) - 1

    if self:getIsUseInRoadTable(x, y) then
        if self._clickRoads then
            self._clickRoads:setVisible(false)
            self:removeInRoadTable(x, y)
        end

        return
    end

    if not self._clickRoads then
        local data = {
            Color = cc.c3b(255, 255, 255),
            Pos = cc.p(x, y),
        }

        self._clickRoads = Road:create(data)
        self:addChild(self._clickRoads)
        self._clickRoads:createClickNode()
        self._clickRoads:setVisible(false)
    end

    self._clickRoads:setVisible(true)
    self._clickRoads:resetPosition(x, y)
    self._clickRoads:doShowChoose()
    self:setRoadTable(x, y)
end

-- 將當前xy保存到表內(nèi)(標記這里已被占用)
function MapRoad:setRoadTable(x, y)
    local str = string.format('%s_%s', x, y)
    self._roadsTable[str] = true
end

function MapRoad:getIsUseInRoadTable(x, y)
    local str = string.format('%s_%s', x, y)
    return self._roadsTable[str] or false
end

function MapRoad:removeInRoadTable(x, y)
    local str = string.format('%s_%s', x, y)
    self._roadsTable[str] = nil
end

function MapRoad:getAllRoads()
    return self._roads
end

function MapRoad:getStartPos()
    return Start_Pos
end

return MapRoad
-- 怪物層
--[[
    data = {Blood = (血量), Speed = (移動速度), CircleRadius = (偏移值身诺,半徑圓蜜托,怪物的寬高一半)}
]]

local MonsterNode = require('app.testFile.event.Key_3_Event_File.Node.Monster')
local Start_Pos = cc.p(100, 100)

local MonsterTable = {
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},
    {Blood = 200, Speed = 1, CircleRadius = 20},    
    {Blood = 200, Speed = 1, CircleRadius = 40},            
}

local Free_Time = 0
local Monster_Create_Interval = 1  -- 間隔幾秒創(chuàng)建小怪獸

local Monster = class('Monster', cc.Node)

function Monster:ctor(_Main)
    self._Main = _Main
    self:initValue()
end

function Monster:initValue()
    self._monster = {}
    self._createMonsterSchedule = nil
end

function Monster:createMonsters()
    local idx = 0

    local function callfunc()
        idx = idx + 1
        if MonsterTable[idx] then
            local monster = MonsterNode:create(MonsterTable[idx])
            self:addChild(monster)
            table.insert(self._monster, monster)
            monster:resetPosition(Start_Pos)
            monster:runMove()
        else
            if self._createMonsterSchedule then
                self:stopAction(self._createMonsterSchedule)
                self._createMonsterSchedule = nil
            end
        end
    end

    local delayFree_Time = cc.DelayTime:create(Free_Time)
    local function afterFree_Time()
        self._createMonsterSchedule = schedule(self, callfunc, Monster_Create_Interval)
    end

    local seq = cc.Sequence:create(delayFree_Time, cc.CallFunc:create(afterFree_Time))
    self:runAction(seq)
end

function Monster:getAllMonster()
    return self._monster
end

function Monster:getDelegate()
    return self._Main
end

function Monster:getMonsterStartPos()
    return Start_Pos
end

return Monster
-- 塔(保衛(wèi)層)
local Interval = 70

local Time_Check_Monster = 0.2
local Start_Pos = cc.p(100, 100)

local testProtecter1 = {Blood = 1, Speed = 1, CircleRadius = 30, Scope = 3}
local testProtecter2 = {Blood = 1, Speed = 1, CircleRadius = 30, Scope = 3}
local testProtecter3 = {Blood = 1, Speed = 1, CircleRadius = 30, Scope = 3}

local ProtecterNode = require('app.testFile.event.Key_3_Event_File.Node.Protecter')
local Bullet = require('app.testFile.event.Key_3_Event_File.Node.Bullet')

local Protecter = class('Protecter', cc.Node)

--[[
    data = {Blood = (血量), Speed = (射擊速度), CircleRadius = (偏移值,半徑圓霉赡,塔的寬高一半), Scope = 1(以自己為中心橄务,半徑為Scopr畫圓)}
]]
function Protecter:ctor(_Main, data)
    self._Main = _Main
    self._ProtecterData = data
    self:initValue()
    self:bindEvent()
end

function Protecter:initValue()
    self._protecter = {}
end

function Protecter:createProtecters()
    self:createProtecterNode(testProtecter1, 6, 0)
    self:createProtecterNode(testProtecter2, 4, 6)
    self:createProtecterNode(testProtecter3, 8, 4)
end

function Protecter:createProtecterNode(data, x, y)
    local protecter = ProtecterNode:create(data)
    self:addChild(protecter)
    protecter:resetPosition(x, y)
    table.insert(self._protecter, protecter)
    protecter:startCheckMonster(self:getDelegate():getAllMonster())
end

function Protecter:resetAllProtecterScopeCircle()
    if not self._protecter or #self._protecter <= 0 then
        return
    end

    for i, v in ipairs(self._protecter) do
        if v.setScopeCircle then
            v:setScopeCircle(true)
        end
    end
end

function Protecter:getDelegate()
    return self._Main
end

function Protecter:getAllProtecter()
    return self._protecter
end

function Protecter:bindEvent()
    self:bindCreateProtecter()
end

function Protecter:bindCreateProtecter()
    local function fun(event)
        if not event or not event.data then
            return
        end

        self:createProtecterNode(event.data, event.data.Pos.x, event.data.Pos.y)
    end

    local listener = cc.EventListenerCustom:create(Event_Create_Protecter, fun)
    cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(listener, 1)
end

function Protecter:getProtecterStartPos()
    return Start_Pos
end

return Protecter
-- 單個道路
--[[
    data:
        Color = (顏色),
        Pos = (位置),
]]

local Interval = 70  -- 形塊間隔
local Road_Size = cc.size(60, 60)  -- 形塊大小
local Road_Size_Mid = cc.size(54, 54)

local Road = class('Road', cc.Node)
function Road:ctor(data)
    self._data = data
    self:initValue()
end

function Road:initValue()
    self._Color = self._data.Color or cc.c3b(250, 250, 250)
    self._Pos = self._data.Pos or cc.p(1, 1)

    self._clickTable = {}
end

-- 創(chuàng)建道路Node
function Road:createRoadNode()
    self:createNode()
end

-- 創(chuàng)建可點擊Node(可選擇建筑的)
function Road:createClickNode()
    self:createNode()
    self:createNode(true)
    self:showClickEvent()
end

function Road:createNode(isMid)
    local x, y = self._Pos.x, self._Pos.y
    local layout = ccui.Layout:create()
    layout:setAnchorPoint(cc.p(0.5, 0.5))
    layout:setContentSize(isMid and Road_Size_Mid or Road_Size)
    layout:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) --設(shè)置顏色
    layout:setBackGroundColor(isMid and cc.c3b(0, 0, 0) or self._Color)
    self:addChild(layout)
    self:resetPosition(x, y)
end

function Road:resetPosition(x, y)
    self._Pos = cc.p(x, y)
    local startPos = self:getStartPos()
    self:setPositionX(Interval * self._Pos.x + startPos.x)
    self:setPositionY(Interval * self._Pos.y + startPos.y)
end

function Road:showClickEvent()
    local temp = {
        {Color = cc.c3b(255, 0, 0)},
        {Color = cc.c3b(0, 255, 0)},
        {Color = cc.c3b(0, 0, 255)},
    }

    for i, v in ipairs(temp) do
        local layout = ccui.Layout:create()
        layout:setAnchorPoint(cc.p(0.5, 0))
        layout:setContentSize(cc.size(20, 20))
        layout:setPosition(cc.p((i - (#temp+1)/2) * Road_Size.width/2, Road_Size.height/2 + 5))
        layout:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) --設(shè)置顏色
        layout:setBackGroundColor(v.Color)
        layout:setTouchEnabled(true)
        layout:setScale(0)
        self:addChild(layout)
        table.insert(self._clickTable, layout)

        local function clickEvent(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                local data = {Color = layout:getBackGroundColor(), }
                self:dispatchCreateProtecter(data)
            end
        end
        
        layout:addTouchEventListener(clickEvent)  
    end

    self:doShowChoose()
end

function Road:doShowChoose()
    for i, v in ipairs(self._clickTable) do
        v:setScale(0)
        local scale1 = cc.ScaleTo:create(0.1, 1.2)
        local scale2 = cc.ScaleTo:create(0.05, 1)
        local seq = cc.Sequence:create(scale1, scale2)
        v:runAction(seq)
    end
end

function Road:getStartPos()
    return self:getParent():getStartPos()
end

function Road:dispatchCreateProtecter(_data)
    local event = cc.EventCustom:new(Event_Create_Protecter)
    local data = {Blood = 1, Speed = 1, CircleRadius = 30, Scope = 3, Pos = self._Pos, Color = _data.Color, }
    event.data = data

    cc.Director:getInstance():getEventDispatcher():dispatchEvent(event)
    self:setVisible(false)
end

return Road
-- 單個怪物
--[[
    data = {Blood = (血量), Speed = (移動速度), CircleRadius = (偏移值,半徑圓穴亏,怪物的寬高一半)}
]]

local Monster = class('Monster', cc.Node)

function Monster:ctor(data)
    self._MonsterData = data
    self:initValue()
    self:createMonster()
    self:createBlood()
end

function Monster:initValue()
    self._monsterNode = nil
    self._bloodBg = nil
    self._Blood = self._MonsterData.Blood or 1  -- 總血量
    self._Speed = self._MonsterData.Speed or 1
    self._CircleRadius = self._MonsterData.CircleRadius or 20
    self._currentBlood = self._MonsterData.Blood or 1  -- 當前血量
end

function Monster:createMonster()
    local color = cc.c3b(math.random(1, 255), math.random(1, 255), math.random(1, 255))
    self._monsterNode = ccui.Layout:create()
    self._monsterNode:setAnchorPoint(cc.p(0.5, 0.5))
    self._monsterNode:setContentSize(cc.size(self._CircleRadius * 2, self._CircleRadius * 2))
    self._monsterNode:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) --設(shè)置顏色
    self._monsterNode:setBackGroundColor(color)
    self:addChild(self._monsterNode)
end

function Monster:createBlood()
    self._bloodBg = ccui.Layout:create()
    self._bloodBg:setAnchorPoint(cc.p(0.5, 0))
    self._bloodBg:setContentSize(cc.size(self._CircleRadius * 2, 8))
    self._bloodBg:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) --設(shè)置顏色
    self._bloodBg:setBackGroundColor(cc.c3b(255, 255, 255))
    self._bloodBg:setBackGroundColorOpacity(150)
    self._bloodBg:setPosition(cc.p(0, self._monsterNode:getContentSize().height / 2 + 5))
    self:addChild(self._bloodBg)

    self._bloodNode = ccui.Layout:create()
    self._bloodNode:setAnchorPoint(cc.p(0, 0.5))
    self._bloodNode:setContentSize(cc.size(self._CircleRadius * 2, 8))
    self._bloodNode:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) --設(shè)置顏色
    self._bloodNode:setBackGroundColor(cc.c3b(255, 0, 0))
    self._bloodNode:setPosition(cc.p(0, self._bloodBg:getContentSize().height / 2))
    self._bloodBg:addChild(self._bloodNode)
end

function Monster:runMove()
    local roadTable = self:getParent():getDelegate():getAllRoads()
    local idx = 1

    local function run()
        idx = idx + 1

        local roadPos = cc.p(roadTable[idx]:getPositionX(), roadTable[idx]:getPositionY())
        local move = cc.MoveTo:create(self:getMoveSpeed(), roadPos)
        local callfunc = cc.CallFunc:create(function()
            if idx == #roadTable then
                self:showEnd()
            else
                run()
            end
        end)

        local seq = cc.Sequence:create(move, callfunc)
        self:runAction(seq)
    end

    if #roadTable > 0 then
        run()
    end
end

function Monster:showEnd()
    print('end...')
end

function Monster:getSpeed()
    return self._Speed
end

function Monster:getMoveSpeed()
    return 1 - self._Speed * 0.1
end

function Monster:dropBlood(_damage)
    self._currentBlood = self._currentBlood - _damage
    if self._currentBlood <= 0 then
        self:removeFromParent()
    else
        self:setBlood()     
    end
end

-- 偏移值
function Monster:getCircleRadius()
    return self._CircleRadius
end

function Monster:setBlood()
    self._bloodNode:setContentSize(cc.size((self._CircleRadius * 2) * (self._currentBlood / self._Blood), 8))
end

function Monster:resetPosition()
    self:setPosition(self:getParent():getMonsterStartPos())
end

return Monster
-- 單個塔
local Interval = 70

local ZOrder_Protexter = 5
local ZOrder_Circle = 1
local Zorder_Bullet = 6

local Time_Check_Monster = 0.2

local Protecter = class('Protecter', cc.Node)
local Bullet = require('app.testFile.event.Key_3_Event_File.Node.Bullet')

--[[
    data = {Blood = (血量), 
    Speed = (射擊速度), 
    CircleRadius = (偏移值蜂挪,半徑圓,塔的寬高一半), 
    Scope = 1(以自己為中心嗓化,半徑為Scopr畫圓), 
    Pos = (位置)棠涮,可不傳,暫時沒用,
    Color = (顏色刺覆,不傳則為默認顏色(隨機色))
]]

function Protecter:ctor(data, pos)
    self._ProtecterData = data
    self:initValue()
    self:createProtecter()
    self:createScopeCircle()
    self:bindEvent()

    -- 測試严肪,打開檢測區(qū)域
    -- self:setScopeCircle()
end

function Protecter:initValue()
    self.ui = nil
    self._scopeCircle = nil
    self._isShowScopeCircle = false

    self._Blood = self._ProtecterData.Blood or 1
    self._Speed = self._ProtecterData.Speed or 1
    self._CircleRadius = self._ProtecterData.CircleRadius or 30
    self._Scope = self._ProtecterData.Scope or 1
    self._Pos = self._ProtecterData.Pos
    self._Color = self._ProtecterData.Color
end

function Protecter:createProtecter()
    local color = self._Color or cc.c3b(math.random(1, 255), math.random(1, 255), math.random(1, 255))
    local layout = ccui.Layout:create()
    layout:setAnchorPoint(cc.p(0.5, 0.5))
    layout:setContentSize(cc.size(self._CircleRadius * 2, self._CircleRadius * 2))
    layout:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) --設(shè)置顏色
    layout:setBackGroundColor(color)
    layout:setTouchEnabled(true)
    layout:setLocalZOrder(ZOrder_Protexter)
    self:addChild(layout)

    self.ui = layout
end

function Protecter:createScopeCircle()
    self._scopeCircle = cc.DrawNode:create()
    self._scopeCircle:drawDot(cc.p(0, 0), self:getScope() * Interval, cc.c4b(150, 150, 150, 0.5))
    self._scopeCircle:setLocalZOrder(ZOrder_Circle)
    self:addChild( self._scopeCircle)
    self._scopeCircle:setScale(0)
    self._scopeCircle:setOpacity(0)
    -- self._scopeCircle:setVisible(false)
end

-- 如果沒傳isHide,則由當前的self._isShowScopeCircle來做決定
function Protecter:setScopeCircle(isHide)
    local fade = cc.FadeTo:create(0.15, (isHide or self._isShowScopeCircle) and 0 or 1)
    local scale = cc.ScaleTo:create(0.15, (isHide or self._isShowScopeCircle) and 0 or 1)
    local spawn = cc.Spawn:create(fade, scale)
    self._scopeCircle:runAction(scale)

    if isHide then
        self._isShowScopeCircle = false
    else
        self._isShowScopeCircle = not self._isShowScopeCircle
    end
end

function Protecter:bindEvent()
    local function clickEvent(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if self._scopeCircle then
                self:setScopeCircle()
            end
        end
    end
        
    self.ui:addTouchEventListener(clickEvent)   
end

function Protecter:getNode()
    return self.ui
end

function Protecter:getScopeCircle()
    return self._scopeCircle
end

function Protecter:getScope()
    return self._Scope
end

function Protecter:startCheckMonster(_monsterData)
    local function callback()
        local isShould, monster = self:checkMonster(_monsterData)
        if isShould then
            self:shoot(monster, _monsterData)
        end
    end

    schedule(self, callback, Time_Check_Monster)
end

function Protecter:checkMonster(_monsterData)
    for i, v in ipairs(_monsterData) do
        if v and not tolua.isnull(v) then
            local monsterWorldPos = v:convertToWorldSpace(cc.p(0, 0))
            local protecterWorldPos = self:convertToWorldSpace(cc.p(0, 0))
            local distance = cc.pGetDistance(protecterWorldPos, monsterWorldPos) - v:getCircleRadius()
            if distance <= self._Scope * Interval then
                return true, v
            end
        end
    end
end

function Protecter:shoot(_monster, _targetTable)
    if not _monster then
        return
    end

    if tolua.isnull(_monster) then
        return
    end

    local monsterWorldPos = _monster:convertToWorldSpace(cc.p(0, 0))
    local protecterWorldPos = self:getWorldPos()
    local distance = cc.pGetDistance(protecterWorldPos, monsterWorldPos)

    local bulletData = {
        Speed = self._Speed, 
        Damage = 1, 
        StartPos = protecterWorldPos, 
        EndPos = monsterWorldPos, 
        Distance = distance,
    }

    local bullet = Bullet:create(bulletData)
    bullet:setLocalZOrder(Zorder_Bullet)
    self:addChild(bullet)
    bullet:startShoot(_targetTable)
end

function Protecter:getWorldPos()
    return self:convertToWorldSpace(cc.p(0, 0))
end

-- 偏移值
function Protecter:getCircleRadius()
    return self._CircleRadius
end

function Protecter:resetPosition(x, y)
    self:setPosition(self:getParent():getProtecterStartPos().x + x * Interval, self:getParent():getProtecterStartPos().y + y * Interval)
end

return Protecter
-- 單個子彈
--[[
    Speed(速度)
    Damage(傷害)
    StartPos(起始位置,世界坐標)
    EndPos(終點位置诬垂,世界坐標,這個只用于得到角度和移動方向)
    Distance(距離)
]]

local Bullet_Radius = 10
local Bullet_Color = cc.c4b(1, 0, 0, 1)
local Time_Check_Is_Hit_The_Target = 1 / 60

local Bullet = class('Bullet', cc.Node)

function Bullet:ctor(data)
    self._data = data
    self:initValue()
    self:initNode()
end

function Bullet:initValue()
    self._bullet = nil
    self._Speed = self._data.Speed or 1
    self._Damage = self._data.Damage or 1
    self._StartPos = self._data.StartPos or cc.p(0, 0)
    self._EndPos = self._data.EndPos or cc.p(0, 0)
    self._Distance = self._data.Distance or 1
end

function Bullet:initNode()
    self._bullet = cc.DrawNode:create()
    self._bullet:drawDot(cc.p(0, 0), Bullet_Radius, Bullet_Color)
    self:addChild(self._bullet)
end

function Bullet:getMoveSpeed()
    return 1 - self._Speed * 0.1
end

function Bullet:startShoot(_targetTable)
    local localPos = self:convertToNodeSpace(cc.p(self._EndPos.x, self._EndPos.y))
    -- localPos = cc.p(localPos.x * 3, localPos.y * 3)  -- 沿線繼續(xù)做處理

    local move = cc.MoveTo:create(self:getMoveSpeed() * self._Distance * 0.002, localPos)
    local callfunc = cc.CallFunc:create(function()
        self:removeFromParent()
    end)

    local seq = cc.Sequence:create(move, callfunc)
    self:runAction(seq)

    self:startCheckIsHitTheTarget(_targetTable)
end

function Bullet:startCheckIsHitTheTarget(_targetTable)
    local function callback()
        local targetTable = _targetTable or {}
        for i, v in ipairs(targetTable) do
            if v and not tolua.isnull(v) then
                local targetWorldPos = v:convertToWorldSpace(cc.p(0, 0))

                -- 檢測目標與子彈碰撞伦仍,決定使用圓與圓(考慮之后可能改為小怪物结窘,避免是長方形)
                local flag = true
                if v.getCircleRadius then
                    local targetRadius = v:getCircleRadius()
                    local bulletRadius = Bullet_Radius
                    local distance = cc.pGetDistance(self:getWorldPos(), targetWorldPos)
                    if distance <= targetRadius + bulletRadius then
                        v:dropBlood(self._Damage)
                        self:removeFromParent()
                    end
                else
                    print('當前子彈檢測的目標,沒有配置getCircleRadius方法喔!!請注意')
                end

                -- 在判斷點到框的位置
            end
        end
    end

    schedule(self, callback, Time_Check_Is_Hit_The_Target)
end

function Bullet:getWorldPos()
    return self:convertToWorldSpace(cc.p(0, 0))
end

return Bullet
塔防類.png

ε≡?(?>?<)? 請大家多多評論一起討論討論

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末充蓝,一起剝皮案震驚了整個濱河市隧枫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谓苟,老刑警劉巖官脓,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涝焙,居然都是意外死亡卑笨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門仑撞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赤兴,“玉大人,你說我怎么就攤上這事隧哮⊥傲迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵沮翔,是天一觀的道長陨帆。 經(jīng)常有香客問我,道長采蚀,這世上最難降的妖魔是什么疲牵? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮榆鼠,結(jié)果婚禮上瑰步,老公的妹妹穿的比我還像新娘。我一直安慰自己璧眠,他們只是感情好缩焦,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著责静,像睡著了一般袁滥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上灾螃,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天题翻,我揣著相機與錄音,去河邊找鬼。 笑死嵌赠,一個胖子當著我的面吹牛塑荒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姜挺,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼齿税,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炊豪?” 一聲冷哼從身側(cè)響起凌箕,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎词渤,沒想到半個月后牵舱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡缺虐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年芜壁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片高氮。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡沿盅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纫溃,到底是詐尸還是另有隱情腰涧,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布紊浩,位于F島的核電站窖铡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坊谁。R本人自食惡果不足惜费彼,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望口芍。 院中可真熱鬧箍铲,春花似錦、人聲如沸鬓椭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽小染。三九已至翘瓮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間裤翩,已是汗流浹背资盅。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呵扛。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓每庆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親今穿。 傳聞我的和親對象是個殘疾皇子缤灵,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355