#Cocos2d-JS v3.0中的屬性風格API
##1. 新的API風格
我們直接來看看你可以如何使用Cocos2d-JS v3.0:
以前的API | 新的API |
---|---|
node.setPosition(x, y); |
node.x = x; node.y = y; |
node.setRotation(r); | node.rotation = r; |
如表格中可以看到的,設置position屬性的函數調用在3.0版中會被替換爲直接的對象屬性存取。不僅僅是示例中的x
,y
和rotation
,幾乎所有節點類型中關於屬性存取的函數都會被替換爲直接的對象屬性訪問。具體的屬性列表在文檔最後。
得益於JavaScript的getter/setter,我們可以爲對象的某一個屬性名分別設置其getter/setter函數。這就是Cocos2d-JS如何做到從函數到屬性的轉換。比如說,node.x
= x;
實際上調用了setPositionX
函數並傳入x作爲參數,所以在使用屬性風格API的時候請不要因爲它的簡單而感到擔心,在很多情況下這等同於以前的函數調用。
你也可以給自己的對象屬性定義getter/setter函數,只需要使用下面這行代碼:
cc.defineGetterSetter(object, "propertyName", getterFunc, setterFunc);
這樣的話,var a = object.propertyName;
會通過getterFunc
獲取propertyName
的當前值,object.propertyName
= newvalue;
則會通過setterFunc
來給propertyName
賦新值。
至於屬性的命名,我們儘可能提供了類似css風格的屬性名,除此之外的屬性都盡力維持與v2.2.2中一致。選擇類似css的屬性名是爲了給JavaScript開發者以最自然的開發體驗。
##2. cc.Node的attr
函數
新API使得Cocos2d-JS代碼更加簡潔,但這還不夠,我們爲cc.Node添加了更爲簡單易用的attr
函數。與jQuery的attr
函數相同,這個函數允許開發者批量設置多個屬性。示例如下:
node.attr({
x: 20,
y: 20,
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 300,
scale: 2
});
值得一提的是,這個函數不僅僅支持文末列表中的屬性,也支持開發者的自定義屬性。
##3. 改變的初衷
爲什麼Cocos2d-JS要對已穩定的API做出如此大的改變呢?我想最顯而易見的答案已經體現在前面的示例中了:那就是更簡單。
但是我們真正想改變的目標,並不僅僅是更簡單而已,或者說簡單並不是目標,而是結果。長期以來,Cocos2d-JS一直被WEB開發者詬病其複雜程度導致難於學習和使用。在與其他html5遊戲引擎比較之後,我們發現我們引擎最大的問題是,它並不是爲JavaScript開發者設計的。事實上確實如此,到目前爲止,Cocos2d-JS引擎的實現目標一直是盡力與Cocos2d-x的API保持一致,而Cocos2d-x是爲C++開發者設計的,與此同時,Cocos2d家族的起源Cocos2d-iPhone也在引擎中留下了非常多objective-C風格的API設計。很顯然,正是由於這些API被直接移植到h5引擎中,JavaScript開發者纔會覺得引擎非常複雜難用。
所以引擎3.0版本的主要目標就是提供給開發者一套全新的JavaScript風格API,開發團隊決定冒着很大的風險推動這次重構。
回到屬性風格API,cc.Node以及所有繼承自cc.Node的類都使用屬性風格重構。以往的大多數getXXX()
和setXXX(value)
都被直接屬性存取取代了。同時也有也有少數其他適合屬性風格的類使用這種方式重構,它們都可以在文末的列表中找到。
##4. 關於Closure Compiler
由於attr
函數使用鍵值對來配置節點,當我們使用Closure Compiler的高級模式來混淆時,這可能會引起一些意想不到的錯誤。
簡單來說,鍵值對中的鍵實質上是String類型,混淆過程中它並不會被壓縮,而與之相對應的屬性名卻會被壓縮,這導致了兩者命名的不匹配。所幸,在引擎中我們保障了常用的屬性不會被壓縮,至於其他的屬性和用戶自定義屬性,可以使用Closure Compiler的expose
聲明來避免出現問題。需要注意的是這個問題只有在開發者嘗試使用attr
函數來配置屬性的時候纔會出現,如果沒有使用attr
函數就不需要做任何額外的處理。
/** @expose */
node.shaderProgram;
/** @expose */
node.customProperty;
node.attr({
shaderProgram: program,
customProperty: 0
});
##5. 通過繼承來重載屬性
另一個重要的問題是在繼承過程中,如何重載父類中的屬性。好消息是我們已經將這一機制在Cocos2d-JS的cc.Class中實現了。只要你重載了父類中的getter/setter函數,那麼不需要重新定義,新的getter/setter會自動被綁定到屬性上。下面是一個重載Sprite類中的x
屬性的例子:
var MySprite = cc.Sprite.extend({
ctor: function() {
this._super();
this.init();
},
getPositionX: function() {
// Your own implementation
},
setPositionX: function(x) {
// Your own implementation
}
});
var mySprite = new MySprite();
mySprite.x = x;
會調用MySprite
類的setPositionX
函數而不是Sprite
類的,getter函數也是同理。用戶代碼中唯一需要保證的是重載的getter/setter函數名必須和父類中定義的屬性的getter/setter函數同名。否則你將需要通過cc.defineGetterSetter
重新定義屬性。
##6. 屬性列表
cc.Node
Property | Type | Accessibility | Getter/Setter function | Advanced Compress Ready |
---|---|---|---|---|
x | Number | R&W | getPositionX, setPositionX | YES |
y | Number | R&W | getPositionY, setPositionY | YES |
width | Number | R&W | _getWidth, _setWidth | YES |
height | Number | R&W | _getHeight, _setHeight | YES |
anchorX | Number | R&W | _getAnchorX, _setAnchorX | YES |
anchorY | Number | R&W | _getAnchorY, _setAnchorY | YES |
skewX | Number | R&W | getSkewX, setSkewX | YES |
skewY | Number | R&W | getSkewY, setSkewY | YES |
zIndex | Number | R&W | getLocalZOrder, setLocalZOrder | YES |
vertexZ | Number | R&W | getVertexZ, setVertexZ | YES |
rotation | Number | R&W | getRotation, setRotation | YES |
rotationX | Number | R&W | getRotationX, setRotationX | YES |
rotationY | Number | R&W | getRotationY, setRotationY | YES |
scale | Number | R&W | getScale, setScale | YES |
scaleX | Number | R&W | getScaleX, setScaleX | YES |
scaleY | Number | R&W | getScaleY, setScaleY | YES |
opacity | Number | R&W | getOpacity, setOpacity | YES |
opacityModifyRGB | Boolean | R&W | isOpacityModifyRGB, setOpacityModifyRGB | YES |
cascadeOpacity | Boolean | R&W | isCascadeOpacityEnabled, setCascadeOpacityEnabled | YES |
color | cc.Color | R&W | getColor, setColor | YES |
cascadeColor | Boolean | R&W | isCascadeColorEnabled, setCascadeColorEnabled | YES |
children | Array | readonly | getChildren | YES |
childrenCount | Number | readonly | getChildrenCount | YES |
parent | cc.Node | R&W | getParent, setParent | YES |
visible | Boolean | R&W | isVisible, setVisible | YES |
running | Boolean | readonly | isRunning | YES |
ignoreAnchor | Boolean | R&W | isIgnoreAnchorPointForPosition, ignoreAnchorPointForPosition | YES |
tag | Number | R&W | None | YES |
userData | Object | R&W | None | YES |
userObject | Object | R&W | None | YES |
arrivalOrder | Number | R&W | None | YES |
actionManager | cc.ActionManager | R&W | getActionManager, setActionManager | YES |
scheduler | cc.Scheduler | R&W | getScheduler, setScheduler | YES |
grid | cc.GridBase | R&W | None | NO |
shaderProgram | cc.GLProgram | R&W | getShaderProgram, setShaderProgram | YES |
cc.Texture2D
Property | Type | Accessibility | Getter/Setter function | Advanced Compress Ready |
---|---|---|---|---|
name | WebGLTexture | readonly | getName | NO |
pixelFormat | Number | readonly | getPixelFormat | NO |
pixelsWidth | Number | readonly | getPixelsWide | NO |
pixelsHeight | Number | readonly | getPixelsHigh | NO |
width | Number | R&W | _getWidth, _setWidth | NO |
height | Number | R&W | _getHeight, _setHeight | NO |
shaderProgram | cc.GLProgram | R&W | None | NO |
maxS | Number | R&W | None | NO |
maxT | Number | R&W | None | NO |
cc.Sprite
Extend from cc.NodeRGBA
Property | Type | Accessibility | Getter/Setter function | Advanced Compress Ready |
---|---|---|---|---|
dirty | Boolean | R&W | None | YES |
flippedX | Boolean | R&W | isFlippedX, setFlippedX | YES |
flippedY | Boolean | R&W | isFlippedY, setFlippedY | YES |
offsetX | Number | readonly | _getOffsetX | YES |
offsetY | Number | readonly | _getOffsetY | YES |
atlasIndex | Number | R&W | None | YES |
texture | cc.Texture2D | R&W | getTexture, setTexture | YES |
textureRectRotated | Boolean | readonly | isTextureRectRotated | YES |
textureAtlas | cc.TextureAtlas | R&W | None | YES |
batchNode | cc.SpriteBatchNode | R&W | getBatchNode, setBatchNode | YES |
quad | cc.V3F_C4B_T2F_Quad | readonly | getQuad | YES |
cc.LabelTTF
Extend from cc.Sprite
Property | Type | Accessibility | Getter/Setter function | Advanced Compress Ready |
---|---|---|---|---|
string | String | R&W | getString, setString | YES |
textAlign | Number | R&W | getHorizontalAlignment, setHorizontalAlignment | YES |
verticalAlign | Number | R&W | getVerticalAlignment, setVerticalAlignment | YES |
fontSize | Number | R&W | getFontSize, setFontSize | YES |
fontName | String | R&W | getFontName, setFontName | YES |
font | String | R&W | _getFont, _setFont | YES |
boundingWidth | Number | R&W | _getBoundingWidth, _setBoundingWidth | YES |
boundingHeight | Number | R&W | _getBoundingHeight, _setBoundingHeight | YES |
fillStyle | cc.Color | R&W | _getFillStyle, setFontFillColor | YES |
strokeStyle | cc.Color | R&W | _getStrokeStyle, _setStrokeStyle | YES |
lineWidth | Number | R&W | _getLineWidth, _setLineWidth | YES |
shadowOffsetX | Number | R&W | _getShadowOffsetX, _setShadowOffsetX | YES |
shadowOffsetY | Number | R&W | _getShadowOffsetY, _setShadowOffsetY | YES |
shadowOpacity | Number | R&W | _getShadowOpacity, _setShadowOpacity | YES |
shadowBlur | Number | R&W | _getShadowBlur, _setShadowBlur | YES |