<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          教你一招:四兩拔千斤

          共 3508字,需瀏覽 8分鐘

           ·

          2020-10-13 01:47

          在游戲中實(shí)現(xiàn)節(jié)點(diǎn)的可拖動(dòng)是一個(gè)比較常見情況,比如:可以給小朋友做一個(gè)將果皮投進(jìn)垃圾箱的教學(xué)練習(xí)、角色換裝、物品包裹界面等。

          在Cocos Creator中實(shí)現(xiàn)一個(gè)可拖動(dòng)組件,只需對(duì)目標(biāo)節(jié)點(diǎn)拖拽配置就能讓節(jié)點(diǎn)任意移動(dòng),這對(duì)策劃、美術(shù)人員來(lái)說(shuō)是不是很有殺傷力!

          1. 創(chuàng)建測(cè)試場(chǎng)景

          在實(shí)現(xiàn)一個(gè)組件代碼之前最好新建一個(gè)測(cè)試場(chǎng)景,組件代碼在測(cè)試場(chǎng)景中通過(guò)了基本測(cè)試之后再放入正式環(huán)境使用。

          而且在組件完成后,測(cè)試場(chǎng)景最好也不要丟棄了,等我們以后為組件升級(jí)或修改BUG時(shí),可用于快速檢驗(yàn)修改是否正確。

          初始化工程

          2. 實(shí)現(xiàn)可拖拽組件

          我們來(lái)看下組件代碼非常簡(jiǎn)單,就算你不會(huì)編程,根著注釋相信也能明白個(gè)大概

          const?{ccclass,?property}?=?cc._decorator;

          @ccclass
          export?default?class?Dragable?extends?cc.Component?{
          ????onLoad()?{
          ????????//注冊(cè)TOUCH_MOVE事件
          ????????this.node.on(cc.Node.EventType.TOUCH_MOVE,?this.onTouchMove,?this);
          ????}
          ????onTouchMove(touchEvent:?cc.Event.EventTouch)?{
          ????????//獲取觸摸位移增量
          ????????let?dt?=?touchEvent.getDelta();
          ????????//設(shè)置節(jié)點(diǎn)位置
          ????????this.node.x?+=?dt.x;
          ????????this.node.y?+=?dt.y;
          ????}
          }

          代碼主要是設(shè)置節(jié)點(diǎn)的觸摸監(jiān)聽,在監(jiān)聽事件中修改節(jié)點(diǎn)的位置。將組件代碼掛載到節(jié)點(diǎn)上,其它什么都不用做,運(yùn)行起來(lái)看看效果:



          3. 設(shè)置移動(dòng)目標(biāo)

          有了這個(gè)組件,可以控制節(jié)點(diǎn)任意移動(dòng)了,但是很多情況下,需要將節(jié)點(diǎn)移動(dòng)到指定位置,比如將果皮投進(jìn)垃圾箱,我們?cè)鰪?qiáng)一下組件代碼:


          const?{ccclass,?property}?=?cc._decorator;

          @ccclass
          export?default?class?DragToTarget?extends?cc.Component?{
          ????@property(cc.Node)
          ????target:?cc.Node?=?null;

          ????_oldPosition:?cc.Vec3?=?null;
          ????_oldParent:?cc.Node?=?null;
          ????onLoad()?{
          ????????//保存原始父節(jié)點(diǎn)
          ????????this._oldPosition?=?this.node.position;
          ????????this._oldParent?=?this.node.parent;
          ????????
          ????????//注冊(cè)觸摸開始
          ????????this.node.on(cc.Node.EventType.TOUCH_START,?this.onTouchStart,?this);
          ????????//注冊(cè)觸摸移動(dòng)
          ????????this.node.on(cc.Node.EventType.TOUCH_MOVE,?this.onTouchMove,?this);
          ????????//注冊(cè)觸摸結(jié)束
          ????????this.node.on(cc.Node.EventType.TOUCH_END,?this.onTouchEnd,?this);
          ????}

          ????private?onTouchStart(touchEvent:?cc.Event.EventTouch)?{
          ????????let?location?=?touchEvent.getLocation();
          ????????let?offset?=?this.node.convertToNodeSpaceAR(location);
          ????????if?(this.node.parent?===?this._oldParent)?{
          ????????????return;
          ????????}
          ????????//保存原始位置
          ????????this.node.parent?=?this._oldParent;
          ????????let?point?=?this._oldParent.convertToNodeSpaceAR(location);
          ????????this.node.position?=?cc.v3(point.x?-?offset.x,?point.y?-?offset.y,?0);
          ????}

          ????private?onTouchMove(touchEvent:?cc.Event.EventTouch)?{
          ????????//移動(dòng)節(jié)點(diǎn)
          ????????let?dt?=?touchEvent.getDelta();
          ????????this.node.x?+=?dt.x;
          ????????this.node.y?+=?dt.y;
          ????}

          ????private?onTouchEnd(touchEvent:?cc.Event.EventTouch)?{
          ????????if?(!this.target)?{
          ????????????return;
          ????????}
          ????????//獲取target節(jié)點(diǎn)在父容器的包圍盒,返回一個(gè)矩形對(duì)象
          ????????let?rect?=?this.target.getBoundingBox();
          ????????//使用target容器轉(zhuǎn)換觸摸坐標(biāo)
          ????????let?location?=?touchEvent.getLocation();
          ????????let?point?=?this.target.parent.convertToNodeSpaceAR(location);
          ????????if?(rect.contains(point))?{
          ????????????//在目標(biāo)矩形內(nèi),修改節(jié)點(diǎn)坐標(biāo)??
          ????????????point?=?this.target.convertToNodeSpaceAR(location);?
          ????????????this.node.position?=?cc.v3(point);
          ????????????//修改父節(jié)點(diǎn)
          ????????????this.node.parent?=?this.target;
          ????????????return;
          ????????}
          ????????//不在矩形中,還原節(jié)點(diǎn)位置????
          ????????this.node.position?=?this._oldPosition;
          ????}
          }

          代碼變復(fù)雜了,簡(jiǎn)單說(shuō)明一下:

          1. 是增加了一個(gè)target節(jié)點(diǎn)屬性,他是節(jié)點(diǎn)要移動(dòng)到的目標(biāo)
          2. 增加TOUCH_END事件,當(dāng)手指抬起時(shí),檢查當(dāng)前節(jié)點(diǎn)是否在目標(biāo)節(jié)點(diǎn)之中
          3. 在目標(biāo)范圍,修改節(jié)點(diǎn)父子關(guān)系
          4. 不在目標(biāo)范圍,還原節(jié)點(diǎn)位置(提前緩存節(jié)點(diǎn)原始坐標(biāo))

          組件有了鎖定目標(biāo)的功能,現(xiàn)在就可以實(shí)現(xiàn)將果皮投進(jìn)垃圾箱了,當(dāng)然也可以用來(lái)實(shí)現(xiàn)給角色換裝、物品包裹之類的操作,請(qǐng)看下面的演示:


          我給目標(biāo)節(jié)點(diǎn)掛載了一個(gè)Layout組件,設(shè)置成GRID模式,實(shí)現(xiàn)自動(dòng)網(wǎng)格排列,很像游戲中的物品包裹功能,這個(gè)組件真的是物超所值哦!

          4. 小結(jié)

          這次主要運(yùn)用了節(jié)點(diǎn)的觸摸事件監(jiān)聽,在觸摸事件的touchEvent參數(shù)中獲取當(dāng)前觸摸坐標(biāo)點(diǎn)。

          同時(shí)還需要對(duì)坐標(biāo)點(diǎn)在不同節(jié)點(diǎn)坐標(biāo)系下進(jìn)行轉(zhuǎn)換,需要理解的是拖動(dòng)節(jié)點(diǎn)的本質(zhì)是:修改節(jié)點(diǎn)在父節(jié)點(diǎn)上的位置,需要使用this.node.parent.convertToNodeSpaceAR進(jìn)行轉(zhuǎn)換。

          同時(shí)還有使用了最簡(jiǎn)單的碰撞檢測(cè)函數(shù)rect.contains,檢查一個(gè)坐標(biāo)點(diǎn)是否在矩形內(nèi)。

          好了這次的代碼有點(diǎn)多非程序員同學(xué)要好好消化下,發(fā)揮你的想像,可以使用這個(gè)組件做出更有趣的東西。


          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费一级黄片 | 丁香五月天堂 | 一本道无码在线观看 | 在线观看中文字幕一区 | 免费插逼 |