cocos2dx 3d開源項目 fantasyWarrior3D 從零走起 6完結 [AttackManager&GameMaster],cocos2dx開源遊戲

來源:互聯網
上載者:User

cocos2dx 3d開源項目 fantasyWarrior3D 從零走起 6完結 [AttackManager&GameMaster],cocos2dx開源遊戲
[AttackCommand]1. 聲明基本的碰撞體,作為角色釋放的攻擊單位

BasicCollider = class("BasicCollider", function()    local node = cc.Node:create()    node:setCascadeColorEnabled(true)    return nodeend)

function BasicCollider:ctor()    self.minRange = 0   --the min radius of the fan    self.maxRange = 150 --the max radius of the fan    self.angle    = 120 --arc of attack, in radians    self.knock    = 150 --default knock, knocks 150 units     self.mask     = 1   --1 is Heroes, 2 is enemy, 3 ??    self.damage   = 100    self.facing    = 0 --this is radians    self.duration = 0    self.curDuration = 0    self.speed = 0 --traveling speed}    self.criticalChance = 0end


每個角色的具體參數都在GlobalVariables.lua中配置
angle  攻擊角度,非常有用,關係到技能和攻擊的作用範圍
maxRange  攻擊的作用範圍

這兩個參數就可以決定了一個 "技能的作用地區",可以很方便得實現如"扇形"等攻擊地區
這樣攻擊技能的生效不一定需要BasicCollider和目標“碰撞”才觸發,只要敵人站在攻擊地區就可以算打到了。

speed   攻擊體移動的速度,對於戰士的攻擊或法師的“冰牆”則speed為0
duration 期間
DOTTimer 持續傷害的cd

還可以增加一個屬性maxTarget,來決定一個技能是單體吸收還是能夠穿透目標,
作用在多個目標上面。比如dota裡 大牛“衝擊波” 巫妖的“連環霜凍”等

2. AttackManager 所有被釋放的攻擊單位都放在 AttackManager 中
solveAttacks  攻擊單位的幀迴圈

主要幹了3件事:

[1]判斷是否“打到了”
onCollide  攻擊生效:條件是 距離 和角度滿足

_myPos 會不斷隨著遊戲進行更新
function Actor:baseUpdate(dt)
    self._myPos = getPosTable(self)
    ...
end


計算攻擊單位轉向目標需要的角度

local angle = radNormalize(cc.pToAngleSelf(cc.pSub(mpos,apos)))


計算攻擊單位的朝向
local afacing = radNormalize(attack.facing)


判斷是否在攻擊區

if(afacing + attack.angle/2)>angle and angle > (afacing- attack.angle/2) then
    attack:onCollide(monster)
end

[2]根據duration判斷逾時
onTimeOut  移除攻擊單位

[3]根據speed更新位置
onUpdate

3. 繼承基本的攻擊單位,來實現各種角色技能那麼來看一下法師的"冰牆"怎麼做的
Mage:specialAttack()
其中
local pos1 = getPosTable(self)local pos2 = getPosTable(self)local pos3 = getPosTable(self)pos1.x = pos1.x+130pos2.x = pos2.x+330pos3.x = pos3.x+530pos1 = cc.pRotateByAngle(pos1, self._myPos, self._curFacing)pos2 = cc.pRotateByAngle(pos2, self._myPos, self._curFacing)pos3 = cc.pRotateByAngle(pos3, self._myPos, self._curFacing)

pRotateByAngle 返回點以pos1 以self._myPos為旋轉軸點,按逆時針方向旋轉self._curFacing弧度,
這樣最終得到三個點,他們在 法師 和目標的連線上,與法師的距離分別為130 330 530。在這3個點建立了3個MageIceSpikes

MageIceSpikes.create

隨機由10個冰刺組成,並且添加粒子效果


屬性:
    _specialAttack   = {        minRange = 0,        maxRange = 140,        angle    = DEGREES_TO_RADIANS(360),        knock    = 75,        damage   = 250,        mask     = EnumRaceType.HERO,        duration = 4.5,        speed    = 0,        criticalChance = 0.05,        DOTTimer = 0.75, --it will be able to hurt every 0.5 seconds        curDOTTime = 0.75,        DOTApplied = false    }, 




[GameMaster]

GameMaster:init() 從中可以看到

統一把角色建立好,再分批放出來

self:AddHeros()
self:addMonsters()

logicUpdate  幀迴圈
主要負責控制英雄的前進和小怪的重新整理

local battleSiteX = {-2800,-1800,-800}
設定了觸發地點 和 重新整理地點

stage為 1~7 
隨機刷怪 or 向右跑

stage == 7 清掉小怪
stage == 8 給予警告

警告結束後就顯示boss了 showBoss()
可以配置性不太強,所以這裡就不具體分析代碼了

[ParticleManager]plist包含兩部分內容:粒子系統屬性和粒子紋理

1. 粒子屬性載入和建立Quad粒子物件在啟動的時候調用AddPlistData 載入粒子的plist檔案,並且緩衝為map格式
從介面實現來看,如果直接從緩衝的map來建立粒子的話,就省去了讀檔案的時間,起到最佳化的作用
ParticleSystemQuad * ParticleSystemQuad::create(ValueMap &dictionary)
{
    ParticleSystemQuad *ret = new (std::nothrow) ParticleSystemQuad();
    if (ret && ret->initWithDictionary(dictionary))
    {
        ret->autorelease();
        return ret;
    }
    CC_SAFE_DELETE(ret);
    return ret;
}


2. 粒子紋理由FX.plist和FX.png 提供
給產生好的quad設定紋理
magic:setTextureWithRect(magicf:getTexture(), magicf:getRect())


3. 關於控制台的error在調試的時候,控制台一直在報bug,於是乎就去看了下源碼的時下,順便瞧瞧lua函數ParticleSystemQuad:create的重載是怎麼實現的
error:
     cc.ParticleSystemQuad:create argument #2 is 'table'; 'string' expected.

int lua_cocos2dx_ParticleSystemQuad_create(lua_State* tolua_S){    int argc = 0;    bool ok  = true;#if COCOS2D_DEBUG >= 1    tolua_Error tolua_err;#endif#if COCOS2D_DEBUG >= 1    if (!tolua_isusertable(tolua_S,1,"cc.ParticleSystemQuad",0,&tolua_err)) goto tolua_lerror;#endif    argc = lua_gettop(tolua_S)-1;    do     {        if (argc == 1)        {            std::string arg0;            ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.ParticleSystemQuad:create");            if (!ok) { break; }            cocos2d::ParticleSystemQuad* ret = cocos2d::ParticleSystemQuad::create(arg0);            object_to_luaval<cocos2d::ParticleSystemQuad>(tolua_S, "cc.ParticleSystemQuad",(cocos2d::ParticleSystemQuad*)ret);            return 1;        }    } while (0);    ok  = true;    do     {        if (argc == 0)        {            cocos2d::ParticleSystemQuad* ret = cocos2d::ParticleSystemQuad::create();            object_to_luaval<cocos2d::ParticleSystemQuad>(tolua_S, "cc.ParticleSystemQuad",(cocos2d::ParticleSystemQuad*)ret);            return 1;        }    } while (0);    ok  = true;    do     {        if (argc == 1)        {            cocos2d::ValueMap arg0;            ok &= luaval_to_ccvaluemap(tolua_S, 2, &arg0, "cc.ParticleSystemQuad:create");            if (!ok) { break; }            cocos2d::ParticleSystemQuad* ret = cocos2d::ParticleSystemQuad::create(arg0);            object_to_luaval<cocos2d::ParticleSystemQuad>(tolua_S, "cc.ParticleSystemQuad",(cocos2d::ParticleSystemQuad*)ret);            return 1;        }    } while (0);    ok  = true;


看了源碼重載的思路就比較清晰了:先判斷參數個數,再對通過函數luaval_to_std_string對L棧裡的參數分別進行嘗試性得取,直到某個類型正確取到值

ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.ParticleSystemQuad:create");

而error log就是在嘗試得過程中函數 luaval_to_native_err 報出來的

    if (!tolua_iscppstring(L,lo,0,&tolua_err))    {#if COCOS2D_DEBUG >=1        luaval_to_native_err(L,"#ferror:",&tolua_err,funcName);#endif        ok = false;    }

稍微想一下,其實這段代碼是可以最佳化的嘛,可以先把所有要嘗試分支都試試,如果都沒有正確再報錯。

[manager]
維護了所有的角色對象,主要負責處理碰撞事件

collisionDetect  幀迴圈 
collision(sprite)->solveCollision  
確保兩個角色之間的距離小於兩者"腰圍" _radius之合,並且根據兩者"體重" _mass 計算彈開的距離

isOutOfBound(sprite)    確保角色不會出螢幕
G =
{
    winSize = cc.Director:getInstance():getWinSize(),
    bloodPercentDropSpeed = 2,
    activearea = {left = -2800, right = 1000, bottom = 100, top = 700},
}

getFocusPointOfHeros 擷取英雄的“平均位置” 作為攝像機焦點


參考:


《粒子》

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.