2012-09-10

LimeJS 的 setAnchorPoint() 與 setPosition()

錨定點與位置,官方文件寫的很簡單,燒掉好一些腦細胞才搞懂。



錨定點(setAnchorPoint)可以設定 0 到 1 之間的值,一般常用 0、0.5 與 1,分別表示 X 軸的左、中與右,或者 Y 軸的上、中與下,例如 [0, 0] 表示左上,[1, 1] 表示右下,[0.5, 0.5] 表示正中。


位置(setPosition)乍看很簡單,事實上指的是「外層 Node 的錨定點與本身錨定點間的距離」。

看 code 先。
ag.testScene = function() {
  var scene = new lime.Scene();
  
  // Left-Top -> red
  var ltLayer = new lime.Layer().setAnchorPoint(0,0).setPosition(0,0);
  var ltSprite = new lime.Sprite().setFill('#c00').setAnchorPoint(0,0).setPosition(0,0).setSize(100,100);
  ltLayer.appendChild(ltSprite);
  scene.appendChild(ltLayer);
  
  // Right-Top -> green
  var rtLayer = new lime.Layer().setAnchorPoint(1,0).setPosition(ag.gameW,0);
  var rtSprite = new lime.Sprite().setFill('#0c0').setAnchorPoint(0,0).setPosition(0,0).setSize(100,100);
  rtLayer.appendChild(rtSprite);
  scene.appendChild(rtLayer);
  
  // Center-Top -> blue
  var ctLayer = new lime.Layer().setAnchorPoint(0.5,0).setPosition(ag.gameW/2,0);
  var ctSprite = new lime.Sprite().setFill('#00c').setAnchorPoint(0,0).setPosition(0,0).setSize(100,100);
  ctLayer.appendChild(ctSprite);
  scene.appendChild(ctLayer);

  ag.director.replaceScene(scene);
};
得到以下的結果:
ltLayer、rtLayer 與 ctLayer 的錨定點分別為左上、右上與中上,這時,不是下層 Node 的 position 很重要, ltLayer、rtLayer 與 ctLayer 這一層的 position 才是重點,ltLayer 的 position 沒有問題,特別的是 rtLayer 與 ctLayer 的 position,錨定點為右上的 rtLayer 的 position 必須是 [scene 的寬度, 0],也就是說 rtLayer 的外層,也就是 scene 的錨定點為左上,所以兩個錨定點間的距離就是 scene 的寬度;所以錨定點為中上的 ctLayer 的 position 就是 [scene 寬度的一半, 0]。

用 ltSprite、rtSprite 與 ctSprite 三個矩形來驗證,三個矩形錨定點一律為左上,position 為 [0, 0],position 為 0 表示說三個矩形的錨定點跟它的外層的錨定點是在一起的,所以都是左上對齊。

再看另一組 code。
ag.testScene2 = function() {
  var scene = new lime.Scene();
  
  // Left-Top -> red
  var ltLayer = new lime.Layer().setAnchorPoint(0,0).setPosition(0,0);
  var ltSprite = new lime.Sprite().setFill('#0c0').setAnchorPoint(0.5,0).setPosition(0,0).setSize(100,100);
  ltLayer.appendChild(ltSprite);
  scene.appendChild(ltLayer);
  
  // Right-Top -> green
  var rtLayer = new lime.Layer().setAnchorPoint(1,0).setPosition(ag.gameW,0);
  var rtSprite = new lime.Sprite().setFill('#00c').setAnchorPoint(0.5,0).setPosition(0,0).setSize(100,100);
  rtLayer.appendChild(rtSprite);
  scene.appendChild(rtLayer);
  
  // Center-Top -> blue
  var ctLayer = new lime.Layer().setAnchorPoint(0.5,0).setPosition(ag.gameW/2,0);
  var ctSprite = new lime.Sprite().setFill('#c00').setAnchorPoint(0.5,0).setPosition(0,0).setSize(100,100);
  ctLayer.appendChild(ctSprite);
  scene.appendChild(ctLayer);

  ag.director.replaceScene(scene);
};
得到以下的結果:
跟第一組範例的差別在於,三個矩形錨定點從左上改為中上。

最後一組 code。
ag.testScene3 = function() {
  var scene = new lime.Scene();
  
  // Left-Top -> red
  var ltLayer = new lime.Layer().setAnchorPoint(0,0).setPosition(0,0);
  var ltSprite = new lime.Sprite().setFill('#0c0').setAnchorPoint(0.5,0).setPosition(0,50).setSize(100,100);
  ltLayer.appendChild(ltSprite);
  scene.appendChild(ltLayer);
  
  // Right-Top -> green
  var rtLayer = new lime.Layer().setAnchorPoint(1,0).setPosition(ag.gameW,0);
  var rtSprite = new lime.Sprite().setFill('#00c').setAnchorPoint(0.5,0).setPosition(0,50).setSize(100,100);
  rtLayer.appendChild(rtSprite);
  scene.appendChild(rtLayer);
  
  // Center-Top -> blue
  var ctLayer = new lime.Layer().setAnchorPoint(0.5,0).setPosition(ag.gameW/2,0);
  var ctSprite = new lime.Sprite().setFill('#c00').setAnchorPoint(0.5,0).setPosition(0,50).setSize(100,100);
  ctLayer.appendChild(ctSprite);
  scene.appendChild(ctLayer);

  ag.director.replaceScene(scene);
}; 
得到以下的結果:
跟第二組範例的差別在於,三個矩形的 position 從 [0,0] 改為 [0,50],也就是說矩形的錨定點距離外層的錨定點往下移 50px。

結論:「Position 指的是外層錨定點與本身錨定點間的距離」,以及「scene 的錨定點為左上」。

2012/10/2 補充

除了 lime.Director 與 lime.Scene 的錨定點預設在左上角,以及少數例外,其餘的錨定點預設都在正中間,也就是[0.5,0.5],設定在 lime.Node 裡。

錨定點除了用來 setPosition 外,還用來作為旋轉的中心點,一般習慣將錨定點設為左上角,所以有旋轉需求時,錨定點還是得設在正中間。
---
---
---

沒有留言:

張貼留言