123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722 |
- /****************************************************************************
- Copyright (c) 2008-2010 Ricardo Quesada
- Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
- http://www.cocos2d-x.org
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
- /**
- * Tint a texture using the "multiply" operation
- * @param {HTMLImageElement} image
- * @param {cc.Color} color
- * @param {cc.Rect} [rect]
- * @param {HTMLCanvasElement} renderCanvas
- * @returns {HTMLCanvasElement}
- */
- cc.generateTintImageWithMultiply = function(image, color, rect, renderCanvas){
- renderCanvas = renderCanvas || cc.newElement("canvas");
- rect = rect || cc.rect(0,0, image.width, image.height);
- var context = renderCanvas.getContext( "2d" );
- if(renderCanvas.width != rect.width || renderCanvas.height != rect.height){
- renderCanvas.width = rect.width;
- renderCanvas.height = rect.height;
- }else{
- context.globalCompositeOperation = "source-over";
- }
- context.fillStyle = "rgb(" + (0|color.r) + "," + (0|color.g) + "," + (0|color.b) + ")";
- context.fillRect(0, 0, rect.width, rect.height);
- context.globalCompositeOperation = "multiply";
- context.drawImage(image,
- rect.x,
- rect.y,
- rect.width,
- rect.height,
- 0,
- 0,
- rect.width,
- rect.height);
- context.globalCompositeOperation = "destination-atop";
- context.drawImage(image,
- rect.x,
- rect.y,
- rect.width,
- rect.height,
- 0,
- 0,
- rect.width,
- rect.height);
- return renderCanvas;
- };
- /**
- * Generate tinted texture with lighter.
- * lighter: The source and destination colors are added to each other, resulting in brighter colors,
- * moving towards color values of 1 (maximum brightness for that color).
- * @function
- * @param {HTMLImageElement} texture
- * @param {Array} tintedImgCache
- * @param {cc.Color} color
- * @param {cc.Rect} rect
- * @param {HTMLCanvasElement} [renderCanvas]
- * @return {HTMLCanvasElement}
- */
- cc.generateTintImage = function (texture, tintedImgCache, color, rect, renderCanvas) {
- if (!rect)
- rect = cc.rect(0, 0, texture.width, texture.height);
- var r = color.r / 255;
- var g = color.g / 255;
- var b = color.b / 255;
- var w = Math.min(rect.width, tintedImgCache[0].width);
- var h = Math.min(rect.height, tintedImgCache[0].height);
- var buff = renderCanvas;
- var ctx;
- // Create a new buffer if required
- if (!buff) {
- buff = cc.newElement("canvas");
- buff.width = w;
- buff.height = h;
- ctx = buff.getContext("2d");
- } else {
- ctx = buff.getContext("2d");
- ctx.clearRect(0, 0, w, h);
- }
- ctx.save();
- ctx.globalCompositeOperation = 'lighter';
- // Make sure to keep the renderCanvas alpha in mind in case of overdraw
- var a = ctx.globalAlpha;
- if (r > 0) {
- ctx.globalAlpha = r * a;
- ctx.drawImage(tintedImgCache[0], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- if (g > 0) {
- ctx.globalAlpha = g * a;
- ctx.drawImage(tintedImgCache[1], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- if (b > 0) {
- ctx.globalAlpha = b * a;
- ctx.drawImage(tintedImgCache[2], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- if (r + g + b < 1) {
- ctx.globalAlpha = a;
- ctx.drawImage(tintedImgCache[3], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- ctx.restore();
- return buff;
- };
- /**
- * Generates texture's cache for texture tint
- * @function
- * @param {HTMLImageElement} texture
- * @return {Array}
- */
- cc.generateTextureCacheForColor = function (texture) {
- if (texture.channelCache) {
- return texture.channelCache;
- }
- var textureCache = [
- cc.newElement("canvas"),
- cc.newElement("canvas"),
- cc.newElement("canvas"),
- cc.newElement("canvas")
- ];
- function renderToCache() {
- var ref = cc.generateTextureCacheForColor;
- var w = texture.width;
- var h = texture.height;
- textureCache[0].width = w;
- textureCache[0].height = h;
- textureCache[1].width = w;
- textureCache[1].height = h;
- textureCache[2].width = w;
- textureCache[2].height = h;
- textureCache[3].width = w;
- textureCache[3].height = h;
- ref.canvas.width = w;
- ref.canvas.height = h;
- var ctx = ref.canvas.getContext("2d");
- ctx.drawImage(texture, 0, 0);
- ref.tempCanvas.width = w;
- ref.tempCanvas.height = h;
- var pixels = ctx.getImageData(0, 0, w, h).data;
- for (var rgbI = 0; rgbI < 4; rgbI++) {
- var cacheCtx = textureCache[rgbI].getContext('2d');
- cacheCtx.getImageData(0, 0, w, h).data;
- ref.tempCtx.drawImage(texture, 0, 0);
- var to = ref.tempCtx.getImageData(0, 0, w, h);
- var toData = to.data;
- for (var i = 0; i < pixels.length; i += 4) {
- toData[i ] = (rgbI === 0) ? pixels[i ] : 0;
- toData[i + 1] = (rgbI === 1) ? pixels[i + 1] : 0;
- toData[i + 2] = (rgbI === 2) ? pixels[i + 2] : 0;
- toData[i + 3] = pixels[i + 3];
- }
- cacheCtx.putImageData(to, 0, 0);
- }
- texture.onload = null;
- }
- try {
- renderToCache();
- } catch (e) {
- texture.onload = renderToCache;
- }
- texture.channelCache = textureCache;
- return textureCache;
- };
- cc.generateTextureCacheForColor.canvas = cc.newElement('canvas');
- cc.generateTextureCacheForColor.tempCanvas = cc.newElement('canvas');
- cc.generateTextureCacheForColor.tempCtx = cc.generateTextureCacheForColor.tempCanvas.getContext('2d');
- cc.cutRotateImageToCanvas = function (texture, rect) {
- if (!texture)
- return null;
- if (!rect)
- return texture;
- var nCanvas = cc.newElement("canvas");
- nCanvas.width = rect.width;
- nCanvas.height = rect.height;
- var ctx = nCanvas.getContext("2d");
- ctx.translate(nCanvas.width / 2, nCanvas.height / 2);
- ctx.rotate(-1.5707963267948966);
- ctx.drawImage(texture, rect.x, rect.y, rect.height, rect.width, -rect.height / 2, -rect.width / 2, rect.height, rect.width);
- return nCanvas;
- };
- cc._getCompositeOperationByBlendFunc = function(blendFunc){
- if(!blendFunc)
- return "source";
- else{
- if(( blendFunc.src == cc.SRC_ALPHA && blendFunc.dst == cc.ONE) || (blendFunc.src == cc.ONE && blendFunc.dst == cc.ONE))
- return "lighter";
- else if(blendFunc.src == cc.ZERO && blendFunc.dst == cc.SRC_ALPHA)
- return "destination-in";
- else if(blendFunc.src == cc.ZERO && blendFunc.dst == cc.ONE_MINUS_SRC_ALPHA)
- return "destination-out";
- else
- return "source";
- }
- };
- /**
- * <p>cc.Sprite is a 2d image ( http://en.wikipedia.org/wiki/Sprite_(computer_graphics) ) <br/>
- *
- * cc.Sprite can be created with an image, or with a sub-rectangle of an image. <br/>
- *
- * If the parent or any of its ancestors is a cc.SpriteBatchNode then the following features/limitations are valid <br/>
- * - Features when the parent is a cc.BatchNode: <br/>
- * - MUCH faster rendering, specially if the cc.SpriteBatchNode has many children. All the children will be drawn in a single batch. <br/>
- *
- * - Limitations <br/>
- * - Camera is not supported yet (eg: CCOrbitCamera action doesn't work) <br/>
- * - GridBase actions are not supported (eg: CCLens, CCRipple, CCTwirl) <br/>
- * - The Alias/Antialias property belongs to CCSpriteBatchNode, so you can't individually set the aliased property. <br/>
- * - The Blending function property belongs to CCSpriteBatchNode, so you can't individually set the blending function property. <br/>
- * - Parallax scroller is not supported, but can be simulated with a "proxy" sprite. <br/>
- *
- * If the parent is an standard cc.Node, then cc.Sprite behaves like any other cc.Node: <br/>
- * - It supports blending functions <br/>
- * - It supports aliasing / antialiasing <br/>
- * - But the rendering will be slower: 1 draw per children. <br/>
- *
- * The default anchorPoint in cc.Sprite is (0.5, 0.5). </p>
- * @class
- * @extends cc.Node
- *
- * @param {String|cc.SpriteFrame|HTMLImageElement|cc.Texture2D} fileName The string which indicates a path to image file, e.g., "scene1/monster.png".
- * @param {cc.Rect} rect Only the contents inside rect of pszFileName's texture will be applied for this sprite.
- * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
- * @example
- *
- * 1.Create a sprite with image path and rect
- * var sprite1 = new cc.Sprite("res/HelloHTML5World.png");
- * var sprite2 = new cc.Sprite("res/HelloHTML5World.png",cc.rect(0,0,480,320));
- *
- * 2.Create a sprite with a sprite frame name. Must add "#" before frame name.
- * var sprite = new cc.Sprite('#grossini_dance_01.png');
- *
- * 3.Create a sprite with a sprite frame
- * var spriteFrame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png");
- * var sprite = new cc.Sprite(spriteFrame);
- *
- * 4.Create a sprite with an existing texture contained in a CCTexture2D object
- * After creation, the rect will be the size of the texture, and the offset will be (0,0).
- * var texture = cc.textureCache.addImage("HelloHTML5World.png");
- * var sprite1 = new cc.Sprite(texture);
- * var sprite2 = new cc.Sprite(texture, cc.rect(0,0,480,320));
- *
- * @property {Boolean} dirty - Indicates whether the sprite needs to be updated.
- * @property {Boolean} flippedX - Indicates whether or not the spirte is flipped on x axis.
- * @property {Boolean} flippedY - Indicates whether or not the spirte is flipped on y axis.
- * @property {Number} offsetX - <@readonly> The offset position on x axis of the sprite in texture. Calculated automatically by editors like Zwoptex.
- * @property {Number} offsetY - <@readonly> The offset position on x axis of the sprite in texture. Calculated automatically by editors like Zwoptex.
- * @property {Number} atlasIndex - The index used on the TextureAtlas.
- * @property {cc.Texture2D} texture - Texture used to render the sprite.
- * @property {Boolean} textureRectRotated - <@readonly> Indicate whether the texture rectangle is rotated.
- * @property {cc.TextureAtlas} textureAtlas - The weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode.
- * @property {cc.SpriteBatchNode} batchNode - The batch node object if this sprite is rendered by cc.SpriteBatchNode.
- * @property {cc.V3F_C4B_T2F_Quad} quad - <@readonly> The quad (tex coords, vertex coords and color) information.
- */
- cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
- dirty:false,
- atlasIndex:0,
- textureAtlas:null,
- _batchNode:null,
- _recursiveDirty:null, //Whether all of the sprite's children needs to be updated
- _hasChildren:null, //Whether the sprite contains children
- _shouldBeHidden:false, //should not be drawn because one of the ancestors is not visible
- _transformToBatch:null,
- //
- // Data used when the sprite is self-rendered
- //
- _blendFunc:null, //It's required for CCTextureProtocol inheritance
- _texture:null, //cc.Texture2D object that is used to render the sprite
- //
- // Shared data
- //
- // texture
- _rect:null, //Retangle of cc.Texture2D
- _rectRotated:false, //Whether the texture is rotated
- // Offset Position (used by Zwoptex)
- _offsetPosition:null, // absolute
- _unflippedOffsetPositionFromCenter:null,
- _opacityModifyRGB:false,
- // image is flipped
- _flippedX:false, //Whether the sprite is flipped horizontally or not.
- _flippedY:false, //Whether the sprite is flipped vertically or not.
- _textureLoaded:false,
- _loadedEventListeners: null,
- _newTextureWhenChangeColor: null, //hack property for LabelBMFont
- _className:"Sprite",
- //Only for texture update judgment
- _oldDisplayColor: cc.color.WHITE,
- /**
- * Returns whether the texture have been loaded
- * @returns {boolean}
- */
- textureLoaded:function(){
- return this._textureLoaded;
- },
- /**
- * Add a event listener for texture loaded event.
- * @param {Function} callback
- * @param {Object} target
- */
- addLoadedEventListener:function(callback, target){
- if(!this._loadedEventListeners)
- this._loadedEventListeners = [];
- this._loadedEventListeners.push({eventCallback:callback, eventTarget:target});
- },
- _callLoadedEventCallbacks:function(){
- if(!this._loadedEventListeners)
- return;
- var locListeners = this._loadedEventListeners;
- for(var i = 0, len = locListeners.length; i < len; i++){
- var selCallback = locListeners[i];
- selCallback.eventCallback.call(selCallback.eventTarget, this);
- }
- locListeners.length = 0;
- },
- /**
- * Returns whether or not the Sprite needs to be updated in the Atlas
- * @return {Boolean} True if the sprite needs to be updated in the Atlas, false otherwise.
- */
- isDirty:function () {
- return this.dirty;
- },
- /**
- * Makes the sprite to be updated in the Atlas.
- * @param {Boolean} bDirty
- */
- setDirty:function (bDirty) {
- this.dirty = bDirty;
- },
- /**
- * Returns whether or not the texture rectangle is rotated.
- * @return {Boolean}
- */
- isTextureRectRotated:function () {
- return this._rectRotated;
- },
- /**
- * Returns the index used on the TextureAtlas.
- * @return {Number}
- */
- getAtlasIndex:function () {
- return this.atlasIndex;
- },
- /**
- * Sets the index used on the TextureAtlas.
- * @warning Don't modify this value unless you know what you are doing
- * @param {Number} atlasIndex
- */
- setAtlasIndex:function (atlasIndex) {
- this.atlasIndex = atlasIndex;
- },
- /**
- * Returns the rect of the cc.Sprite in points
- * @return {cc.Rect}
- */
- getTextureRect:function () {
- return cc.rect(this._rect.x, this._rect.y, this._rect.width, this._rect.height);
- },
- /**
- * Returns the weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode
- * @return {cc.TextureAtlas}
- */
- getTextureAtlas:function () {
- return this.textureAtlas;
- },
- /**
- * Sets the weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode
- * @param {cc.TextureAtlas} textureAtlas
- */
- setTextureAtlas:function (textureAtlas) {
- this.textureAtlas = textureAtlas;
- },
- /**
- * Returns the offset position of the sprite. Calculated automatically by editors like Zwoptex.
- * @return {cc.Point}
- */
- getOffsetPosition:function () {
- return cc.p(this._offsetPosition);
- },
- _getOffsetX: function () {
- return this._offsetPosition.x;
- },
- _getOffsetY: function () {
- return this._offsetPosition.y;
- },
- /**
- * Returns the blend function
- * @return {cc.BlendFunc}
- */
- getBlendFunc:function () {
- return this._blendFunc;
- },
- /**
- * Initializes a sprite with an SpriteFrame. The texture and rect in SpriteFrame will be applied on this sprite.<br/>
- * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself,
- * @param {cc.SpriteFrame} spriteFrame A CCSpriteFrame object. It should includes a valid texture and a rect
- * @return {Boolean} true if the sprite is initialized properly, false otherwise.
- */
- initWithSpriteFrame:function (spriteFrame) {
- cc.assert(spriteFrame, cc._LogInfos.Sprite_initWithSpriteFrame);
- if(!spriteFrame.textureLoaded()){
- //add event listener
- this._textureLoaded = false;
- spriteFrame.addLoadedEventListener(this._spriteFrameLoadedCallback, this);
- }
- var rotated = cc._renderType === cc._RENDER_TYPE_CANVAS ? false : spriteFrame._rotated;
- var ret = this.initWithTexture(spriteFrame.getTexture(), spriteFrame.getRect(), rotated);
- this.setSpriteFrame(spriteFrame);
- return ret;
- },
- _spriteFrameLoadedCallback:null,
- /**
- * Initializes a sprite with a sprite frame name. <br/>
- * A cc.SpriteFrame will be fetched from the cc.SpriteFrameCache by name. <br/>
- * If the cc.SpriteFrame doesn't exist it will raise an exception. <br/>
- * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
- * @param {String} spriteFrameName A key string that can fected a volid cc.SpriteFrame from cc.SpriteFrameCache
- * @return {Boolean} true if the sprite is initialized properly, false otherwise.
- * @example
- * var sprite = new cc.Sprite();
- * sprite.initWithSpriteFrameName("grossini_dance_01.png");
- */
- initWithSpriteFrameName:function (spriteFrameName) {
- cc.assert(spriteFrameName, cc._LogInfos.Sprite_initWithSpriteFrameName);
- var frame = cc.spriteFrameCache.getSpriteFrame(spriteFrameName);
- cc.assert(frame, spriteFrameName + cc._LogInfos.Sprite_initWithSpriteFrameName1);
- return this.initWithSpriteFrame(frame);
- },
- /**
- * Tell the sprite to use batch node render.
- * @param {cc.SpriteBatchNode} batchNode
- */
- useBatchNode:function (batchNode) {
- this.textureAtlas = batchNode.textureAtlas; // weak ref
- this._batchNode = batchNode;
- },
- /**
- * <p>
- * set the vertex rect.<br/>
- * It will be called internally by setTextureRect. <br/>
- * Useful if you want to create 2x images from SD images in Retina Display. <br/>
- * Do not call it manually. Use setTextureRect instead. <br/>
- * (override this method to generate "double scale" sprites)
- * </p>
- * @param {cc.Rect} rect
- */
- setVertexRect:function (rect) {
- this._rect.x = rect.x;
- this._rect.y = rect.y;
- this._rect.width = rect.width;
- this._rect.height = rect.height;
- },
- /**
- * Sort all children of this sprite node.
- * @override
- */
- sortAllChildren:function () {
- if (this._reorderChildDirty) {
- var _children = this._children;
- // insertion sort
- var len = _children.length, i, j, tmp;
- for(i=1; i<len; i++){
- tmp = _children[i];
- j = i - 1;
- //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
- while(j >= 0){
- if(tmp._localZOrder < _children[j]._localZOrder){
- _children[j+1] = _children[j];
- }else if(tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder){
- _children[j+1] = _children[j];
- }else{
- break;
- }
- j--;
- }
- _children[j+1] = tmp;
- }
- if (this._batchNode) {
- this._arrayMakeObjectsPerformSelector(_children, cc.Node._StateCallbackType.sortAllChildren);
- }
- //don't need to check children recursively, that's done in visit of each child
- this._reorderChildDirty = false;
- }
- },
- /**
- * Reorders a child according to a new z value. (override cc.Node )
- * @param {cc.Node} child
- * @param {Number} zOrder
- * @override
- */
- reorderChild:function (child, zOrder) {
- cc.assert(child, cc._LogInfos.Sprite_reorderChild_2);
- if(this._children.indexOf(child) === -1){
- cc.log(cc._LogInfos.Sprite_reorderChild);
- return;
- }
- if (zOrder === child.zIndex)
- return;
- if (this._batchNode && !this._reorderChildDirty) {
- this._setReorderChildDirtyRecursively();
- this._batchNode.reorderBatch(true);
- }
- cc.Node.prototype.reorderChild.call(this, child, zOrder);
- },
- /**
- * Removes a child from the sprite.
- * @param child
- * @param cleanup whether or not cleanup all running actions
- * @override
- */
- removeChild:function (child, cleanup) {
- if (this._batchNode)
- this._batchNode.removeSpriteFromAtlas(child);
- cc.Node.prototype.removeChild.call(this, child, cleanup);
- },
- /**
- * Sets whether the sprite is visible or not.
- * @param {Boolean} visible
- * @override
- */
- setVisible:function (visible) {
- cc.Node.prototype.setVisible.call(this, visible);
- this.setDirtyRecursively(true);
- },
- /**
- * Removes all children from the container.
- * @param cleanup whether or not cleanup all running actions
- * @override
- */
- removeAllChildren:function (cleanup) {
- var locChildren = this._children, locBatchNode = this._batchNode;
- if (locBatchNode && locChildren != null) {
- for (var i = 0, len = locChildren.length; i < len; i++)
- locBatchNode.removeSpriteFromAtlas(locChildren[i]);
- }
- cc.Node.prototype.removeAllChildren.call(this, cleanup);
- this._hasChildren = false;
- },
- //
- // cc.Node property overloads
- //
- /**
- * Sets recursively the dirty flag.
- * Used only when parent is cc.SpriteBatchNode
- * @param {Boolean} value
- */
- setDirtyRecursively:function (value) {
- this._recursiveDirty = value;
- this.dirty = value;
- // recursively set dirty
- var locChildren = this._children, child, l = locChildren ? locChildren.length : 0;
- for (var i = 0; i < l; i++) {
- child = locChildren[i];
- (child instanceof cc.Sprite) && child.setDirtyRecursively(true);
- }
- },
- /**
- * Make the node dirty
- * @param {Boolean} norecursive When true children will not be set dirty recursively, by default, they will be.
- * @override
- */
- setNodeDirty: function(norecursive) {
- cc.Node.prototype.setNodeDirty.call(this);
- // Lazy set dirty
- if (!norecursive && this._batchNode && !this._recursiveDirty) {
- if (this._hasChildren)
- this.setDirtyRecursively(true);
- else {
- this._recursiveDirty = true;
- this.dirty = true;
- }
- }
- },
- /**
- * Sets whether ignore anchor point for positioning
- * @param {Boolean} relative
- * @override
- */
- ignoreAnchorPointForPosition:function (relative) {
- if(this._batchNode){
- cc.log(cc._LogInfos.Sprite_ignoreAnchorPointForPosition);
- return;
- }
- cc.Node.prototype.ignoreAnchorPointForPosition.call(this, relative);
- },
- /**
- * Sets whether the sprite should be flipped horizontally or not.
- * @param {Boolean} flippedX true if the sprite should be flipped horizontally, false otherwise.
- */
- setFlippedX:function (flippedX) {
- if (this._flippedX != flippedX) {
- this._flippedX = flippedX;
- this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
- this.setNodeDirty(true);
- }
- },
- /**
- * Sets whether the sprite should be flipped vertically or not.
- * @param {Boolean} flippedY true if the sprite should be flipped vertically, false otherwise.
- */
- setFlippedY:function (flippedY) {
- if (this._flippedY != flippedY) {
- this._flippedY = flippedY;
- this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
- this.setNodeDirty(true);
- }
- },
- /**
- * <p>
- * Returns the flag which indicates whether the sprite is flipped horizontally or not. <br/>
- * <br/>
- * It only flips the texture of the sprite, and not the texture of the sprite's children. <br/>
- * Also, flipping the texture doesn't alter the anchorPoint. <br/>
- * If you want to flip the anchorPoint too, and/or to flip the children too use: <br/>
- * sprite.setScaleX(sprite.getScaleX() * -1); <p/>
- * @return {Boolean} true if the sprite is flipped horizontally, false otherwise.
- */
- isFlippedX:function () {
- return this._flippedX;
- },
- /**
- * <p>
- * Return the flag which indicates whether the sprite is flipped vertically or not. <br/>
- * <br/>
- * It only flips the texture of the sprite, and not the texture of the sprite's children. <br/>
- * Also, flipping the texture doesn't alter the anchorPoint. <br/>
- * If you want to flip the anchorPoint too, and/or to flip the children too use: <br/>
- * sprite.setScaleY(sprite.getScaleY() * -1); <p/>
- * @return {Boolean} true if the sprite is flipped vertically, false otherwise.
- */
- isFlippedY:function () {
- return this._flippedY;
- },
- //
- // RGBA protocol
- //
- /**
- * Sets whether opacity modify color or not.
- * @function
- * @param {Boolean} modify
- */
- setOpacityModifyRGB:null,
- /**
- * Returns whether opacity modify color or not.
- * @return {Boolean}
- */
- isOpacityModifyRGB:function () {
- return this._opacityModifyRGB;
- },
- /**
- * Update the display opacity.
- * @function
- */
- updateDisplayedOpacity: null,
- // Animation
- /**
- * Changes the display frame with animation name and index.<br/>
- * The animation name will be get from the CCAnimationCache
- * @param {String} animationName
- * @param {Number} frameIndex
- */
- setDisplayFrameWithAnimationName:function (animationName, frameIndex) {
- cc.assert(animationName, cc._LogInfos.Sprite_setDisplayFrameWithAnimationName_3);
- var cache = cc.animationCache.getAnimation(animationName);
- if(!cache){
- cc.log(cc._LogInfos.Sprite_setDisplayFrameWithAnimationName);
- return;
- }
- var animFrame = cache.getFrames()[frameIndex];
- if(!animFrame){
- cc.log(cc._LogInfos.Sprite_setDisplayFrameWithAnimationName_2);
- return;
- }
- this.setSpriteFrame(animFrame.getSpriteFrame());
- },
- /**
- * Returns the batch node object if this sprite is rendered by cc.SpriteBatchNode
- * @returns {cc.SpriteBatchNode|null} The cc.SpriteBatchNode object if this sprite is rendered by cc.SpriteBatchNode, null if the sprite isn't used batch node.
- */
- getBatchNode:function () {
- return this._batchNode;
- },
- _setReorderChildDirtyRecursively:function () {
- //only set parents flag the first time
- if (!this._reorderChildDirty) {
- this._reorderChildDirty = true;
- var pNode = this._parent;
- while (pNode && pNode != this._batchNode) {
- pNode._setReorderChildDirtyRecursively();
- pNode = pNode.parent;
- }
- }
- },
- // CCTextureProtocol
- /**
- * Returns the texture of the sprite node
- * @returns {cc.Texture2D}
- */
- getTexture:function () {
- return this._texture;
- },
- _quad: null, // vertex coords, texture coords and color info
- _quadWebBuffer: null,
- _quadDirty: false,
- _colorized: false,
- _blendFuncStr: "source",
- _originalTexture: null,
- _textureRect_Canvas: null,
- _drawSize_Canvas: null,
- ctor: null,
- _softInit: function (fileName, rect, rotated) {
- if (fileName === undefined)
- cc.Sprite.prototype.init.call(this);
- else if (typeof(fileName) === "string") {
- if (fileName[0] === "#") {
- // Init with a sprite frame name
- var frameName = fileName.substr(1, fileName.length - 1);
- var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName);
- this.initWithSpriteFrame(spriteFrame);
- } else {
- // Init with filename and rect
- cc.Sprite.prototype.init.call(this, fileName, rect);
- }
- }
- else if (typeof(fileName) === "object") {
- if (fileName instanceof cc.Texture2D) {
- // Init with texture and rect
- this.initWithTexture(fileName, rect, rotated);
- } else if (fileName instanceof cc.SpriteFrame) {
- // Init with a sprite frame
- this.initWithSpriteFrame(fileName);
- } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
- // Init with a canvas or image element
- var texture2d = new cc.Texture2D();
- texture2d.initWithElement(fileName);
- texture2d.handleLoadedTexture();
- this.initWithTexture(texture2d);
- }
- }
- },
- /**
- * Returns the quad (tex coords, vertex coords and color) information.
- * @return {cc.V3F_C4B_T2F_Quad}
- */
- getQuad:function () {
- return this._quad;
- },
- /**
- * conforms to cc.TextureProtocol protocol
- * @function
- * @param {Number|cc.BlendFunc} src
- * @param {Number} dst
- */
- setBlendFunc: null,
- /**
- * Initializes an empty sprite with nothing init.<br/>
- * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
- * @function
- * @return {Boolean}
- */
- init:null,
- /**
- * <p>
- * Initializes a sprite with an image filename.<br/>
- *
- * This method will find pszFilename from local file system, load its content to CCTexture2D,<br/>
- * then use CCTexture2D to create a sprite.<br/>
- * After initialization, the rect used will be the size of the image. The offset will be (0,0).<br/>
- * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
- * </p>
- * @param {String} filename The path to an image file in local file system
- * @param {cc.Rect} rect The rectangle assigned the content area from texture.
- * @return {Boolean} true if the sprite is initialized properly, false otherwise.
- */
- initWithFile:function (filename, rect) {
- cc.assert(filename, cc._LogInfos.Sprite_initWithFile);
- var tex = cc.textureCache.getTextureForKey(filename);
- if (!tex) {
- tex = cc.textureCache.addImage(filename);
- return this.initWithTexture(tex, rect || cc.rect(0, 0, tex._contentSize.width, tex._contentSize.height));
- } else {
- if (!rect) {
- var size = tex.getContentSize();
- rect = cc.rect(0, 0, size.width, size.height);
- }
- return this.initWithTexture(tex, rect);
- }
- },
- /**
- * Initializes a sprite with a texture and a rect in points, optionally rotated. <br/>
- * After initialization, the rect used will be the size of the texture, and the offset will be (0,0).<br/>
- * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
- * @function
- * @param {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture A pointer to an existing CCTexture2D object. You can use a CCTexture2D object for many sprites.
- * @param {cc.Rect} rect Only the contents inside rect of this texture will be applied for this sprite.
- * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
- * @return {Boolean} true if the sprite is initialized properly, false otherwise.
- */
- initWithTexture: null,
- _textureLoadedCallback: null,
- /**
- * Updates the texture rect of the CCSprite in points.
- * @function
- * @param {cc.Rect} rect a rect of texture
- * @param {Boolean} [rotated] Whether or not the texture is rotated
- * @param {cc.Size} [untrimmedSize] The original pixels size of the texture
- */
- setTextureRect:null,
- // BatchNode methods
- /**
- * Updates the quad according the the rotation, position, scale values.
- * @function
- */
- updateTransform: null,
- /**
- * Add child to sprite (override cc.Node)
- * @function
- * @param {cc.Sprite} child
- * @param {Number} localZOrder child's zOrder
- * @param {String} tag child's tag
- * @override
- */
- addChild: null,
- /**
- * Update sprite's color
- */
- updateColor:function () {
- var locDisplayedColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity;
- var color4 = {r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: locDisplayedOpacity};
- // special opacity for premultiplied textures
- if (this._opacityModifyRGB) {
- color4.r *= locDisplayedOpacity / 255.0;
- color4.g *= locDisplayedOpacity / 255.0;
- color4.b *= locDisplayedOpacity / 255.0;
- }
- var locQuad = this._quad;
- locQuad.bl.colors = color4;
- locQuad.br.colors = color4;
- locQuad.tl.colors = color4;
- locQuad.tr.colors = color4;
- // renders using Sprite Manager
- if (this._batchNode) {
- if (this.atlasIndex != cc.Sprite.INDEX_NOT_INITIALIZED) {
- this.textureAtlas.updateQuad(locQuad, this.atlasIndex)
- } else {
- // no need to set it recursively
- // update dirty_, don't update recursiveDirty_
- this.dirty = true;
- }
- }
- // self render
- // do nothing
- this._quadDirty = true;
- },
- /**
- * Sets opacity of the sprite
- * @function
- * @param {Number} opacity
- */
- setOpacity:null,
- /**
- * Sets color of the sprite
- * @function
- * @param {cc.Color} color3
- */
- setColor: null,
- /**
- * Updates the display color
- * @function
- */
- updateDisplayedColor: null,
- // Frames
- /**
- * Sets a new sprite frame to the sprite.
- * @function
- * @param {cc.SpriteFrame|String} newFrame
- */
- setSpriteFrame: null,
- /**
- * Sets a new display frame to the sprite.
- * @param {cc.SpriteFrame|String} newFrame
- * @deprecated
- */
- setDisplayFrame: function(newFrame){
- cc.log(cc._LogInfos.Sprite_setDisplayFrame);
- this.setSpriteFrame(newFrame);
- },
- /**
- * Returns whether or not a cc.SpriteFrame is being displayed
- * @function
- * @param {cc.SpriteFrame} frame
- * @return {Boolean}
- */
- isFrameDisplayed: null,
- /**
- * Returns the current displayed frame.
- * @return {cc.SpriteFrame}
- */
- displayFrame: function () {
- return cc.SpriteFrame.create(this._texture,
- cc.rectPointsToPixels(this._rect),
- this._rectRotated,
- cc.pointPointsToPixels(this._unflippedOffsetPositionFromCenter),
- cc.sizePointsToPixels(this._contentSize));
- },
- /**
- * Sets the batch node to sprite
- * @function
- * @param {cc.SpriteBatchNode|null} spriteBatchNode
- * @example
- * var batch = cc.SpriteBatchNode.create("Images/grossini_dance_atlas.png", 15);
- * var sprite = cc.Sprite.create(batch.texture, cc.rect(0, 0, 57, 57));
- * batch.addChild(sprite);
- * layer.addChild(batch);
- */
- setBatchNode:null,
- // CCTextureProtocol
- /**
- * Sets the texture of sprite
- * @function
- * @param {cc.Texture2D|String} texture
- */
- setTexture: null,
- // Texture protocol
- _updateBlendFunc:function () {
- if(this._batchNode){
- cc.log(cc._LogInfos.Sprite__updateBlendFunc);
- return;
- }
- // it's possible to have an untextured sprite
- if (!this._texture || !this._texture.hasPremultipliedAlpha()) {
- this._blendFunc.src = cc.SRC_ALPHA;
- this._blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
- this.opacityModifyRGB = false;
- } else {
- this._blendFunc.src = cc.BLEND_SRC;
- this._blendFunc.dst = cc.BLEND_DST;
- this.opacityModifyRGB = true;
- }
- },
- _changeTextureColor: function () {
- var locElement, locTexture = this._texture, locRect = this._textureRect_Canvas; //this.getTextureRect();
- if (locTexture && locRect.validRect && this._originalTexture) {
- locElement = locTexture.getHtmlElementObj();
- if (!locElement)
- return;
- this._colorized = true;
- if (locElement instanceof HTMLCanvasElement && !this._rectRotated && !this._newTextureWhenChangeColor
- && this._originalTexture._htmlElementObj != locElement)
- cc.generateTintImageWithMultiply(this._originalTexture._htmlElementObj, this._displayedColor, locRect, locElement);
- else {
- locElement = cc.generateTintImageWithMultiply(this._originalTexture._htmlElementObj, this._displayedColor, locRect);
- locTexture = new cc.Texture2D();
- locTexture.initWithElement(locElement);
- locTexture.handleLoadedTexture();
- this.texture = locTexture;
- }
- }
- },
- _setTextureCoords:function (rect) {
- rect = cc.rectPointsToPixels(rect);
- var tex = this._batchNode ? this.textureAtlas.texture : this._texture;
- if (!tex)
- return;
- var atlasWidth = tex.pixelsWidth;
- var atlasHeight = tex.pixelsHeight;
- var left, right, top, bottom, tempSwap, locQuad = this._quad;
- if (this._rectRotated) {
- if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
- left = (2 * rect.x + 1) / (2 * atlasWidth);
- right = left + (rect.height * 2 - 2) / (2 * atlasWidth);
- top = (2 * rect.y + 1) / (2 * atlasHeight);
- bottom = top + (rect.width * 2 - 2) / (2 * atlasHeight);
- } else {
- left = rect.x / atlasWidth;
- right = (rect.x + rect.height) / atlasWidth;
- top = rect.y / atlasHeight;
- bottom = (rect.y + rect.width) / atlasHeight;
- }// CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
- if (this._flippedX) {
- tempSwap = top;
- top = bottom;
- bottom = tempSwap;
- }
- if (this._flippedY) {
- tempSwap = left;
- left = right;
- right = tempSwap;
- }
- locQuad.bl.texCoords.u = left;
- locQuad.bl.texCoords.v = top;
- locQuad.br.texCoords.u = left;
- locQuad.br.texCoords.v = bottom;
- locQuad.tl.texCoords.u = right;
- locQuad.tl.texCoords.v = top;
- locQuad.tr.texCoords.u = right;
- locQuad.tr.texCoords.v = bottom;
- } else {
- if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
- left = (2 * rect.x + 1) / (2 * atlasWidth);
- right = left + (rect.width * 2 - 2) / (2 * atlasWidth);
- top = (2 * rect.y + 1) / (2 * atlasHeight);
- bottom = top + (rect.height * 2 - 2) / (2 * atlasHeight);
- } else {
- left = rect.x / atlasWidth;
- right = (rect.x + rect.width) / atlasWidth;
- top = rect.y / atlasHeight;
- bottom = (rect.y + rect.height) / atlasHeight;
- } // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
- if (this._flippedX) {
- tempSwap = left;
- left = right;
- right = tempSwap;
- }
- if (this._flippedY) {
- tempSwap = top;
- top = bottom;
- bottom = tempSwap;
- }
- locQuad.bl.texCoords.u = left;
- locQuad.bl.texCoords.v = bottom;
- locQuad.br.texCoords.u = right;
- locQuad.br.texCoords.v = bottom;
- locQuad.tl.texCoords.u = left;
- locQuad.tl.texCoords.v = top;
- locQuad.tr.texCoords.u = right;
- locQuad.tr.texCoords.v = top;
- }
- this._quadDirty = true;
- },
- /**
- * draw sprite to canvas
- * @function
- */
- draw: null
- });
- /**
- * Create a sprite with image path or frame name or texture or spriteFrame.
- * @deprecated since v3.0, please use new construction instead
- * @see cc.Sprite
- * @param {String|cc.SpriteFrame|HTMLImageElement|cc.Texture2D} fileName The string which indicates a path to image file, e.g., "scene1/monster.png".
- * @param {cc.Rect} rect Only the contents inside rect of pszFileName's texture will be applied for this sprite.
- * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
- * @return {cc.Sprite} A valid sprite object
- */
- cc.Sprite.create = function (fileName, rect, rotated) {
- return new cc.Sprite(fileName, rect, rotated);
- };
- /**
- * @deprecated since v3.0, please use new construction instead
- * @see cc.Sprite
- * @function
- */
- cc.Sprite.createWithTexture = cc.Sprite.create;
- /**
- * @deprecated since v3.0, please use new construction instead
- * @see cc.Sprite
- * @function
- */
- cc.Sprite.createWithSpriteFrameName = cc.Sprite.create;
- /**
- * @deprecated since v3.0, please use new construction instead
- * @see cc.Sprite
- * @function
- */
- cc.Sprite.createWithSpriteFrame = cc.Sprite.create;
- /**
- * cc.Sprite invalid index on the cc.SpriteBatchNode
- * @constant
- * @type {Number}
- */
- cc.Sprite.INDEX_NOT_INITIALIZED = -1;
- if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
- var _p = cc.Sprite.prototype;
- _p._spriteFrameLoadedCallback = function(spriteFrame){
- var _t = this;
- _t.setNodeDirty(true);
- _t.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize());
- var curColor = _t.color;
- if (curColor.r !== 255 || curColor.g !== 255 || curColor.b !== 255)
- _t._changeTextureColor();
- _t._callLoadedEventCallbacks();
- };
- _p.setOpacityModifyRGB = function (modify) {
- if (this._opacityModifyRGB !== modify) {
- this._opacityModifyRGB = modify;
- this.setNodeDirty(true);
- }
- };
- _p.updateDisplayedOpacity = function (parentOpacity) {
- cc.Node.prototype.updateDisplayedOpacity.call(this, parentOpacity);
- this._setNodeDirtyForCache();
- };
- _p.ctor = function (fileName, rect, rotated) {
- var self = this;
- cc.Node.prototype.ctor.call(self);
- self._shouldBeHidden = false;
- self._offsetPosition = cc.p(0, 0);
- self._unflippedOffsetPositionFromCenter = cc.p(0, 0);
- self._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
- self._rect = cc.rect(0, 0, 0, 0);
- self._newTextureWhenChangeColor = false;
- self._textureLoaded = true;
- self._textureRect_Canvas = {x: 0, y: 0, width: 0, height:0, validRect: false};
- self._drawSize_Canvas = cc.size(0, 0);
- self._softInit(fileName, rect, rotated);
- };
- _p.setBlendFunc = function (src, dst) {
- var _t = this, locBlendFunc = this._blendFunc;
- if (dst === undefined) {
- locBlendFunc.src = src.src;
- locBlendFunc.dst = src.dst;
- } else {
- locBlendFunc.src = src;
- locBlendFunc.dst = dst;
- }
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
- _t._blendFuncStr = cc._getCompositeOperationByBlendFunc(locBlendFunc);
- };
- _p.init = function () {
- var _t = this;
- if (arguments.length > 0)
- return _t.initWithFile(arguments[0], arguments[1]);
- cc.Node.prototype.init.call(_t);
- _t.dirty = _t._recursiveDirty = false;
- _t._opacityModifyRGB = true;
- _t._blendFunc.src = cc.BLEND_SRC;
- _t._blendFunc.dst = cc.BLEND_DST;
- // update texture (calls _updateBlendFunc)
- _t.texture = null;
- _t._textureLoaded = true;
- _t._flippedX = _t._flippedY = false;
- // default transform anchor: center
- _t.anchorX = 0.5;
- _t.anchorY = 0.5;
- // zwoptex default values
- _t._offsetPosition.x = 0;
- _t._offsetPosition.y = 0;
- _t._hasChildren = false;
- // updated in "useSelfRender"
- // Atlas: TexCoords
- _t.setTextureRect(cc.rect(0, 0, 0, 0), false, cc.size(0, 0));
- return true;
- };
- _p.initWithTexture = function (texture, rect, rotated) {
- var _t = this;
- cc.assert(arguments.length != 0, cc._LogInfos.CCSpriteBatchNode_initWithTexture);
- rotated = rotated || false;
- if (rotated && texture.isLoaded()) {
- var tempElement = texture.getHtmlElementObj();
- tempElement = cc.cutRotateImageToCanvas(tempElement, rect);
- var tempTexture = new cc.Texture2D();
- tempTexture.initWithElement(tempElement);
- tempTexture.handleLoadedTexture();
- texture = tempTexture;
- _t._rect = cc.rect(0, 0, rect.width, rect.height);
- }
- if (!cc.Node.prototype.init.call(_t))
- return false;
- _t._batchNode = null;
- _t._recursiveDirty = false;
- _t.dirty = false;
- _t._opacityModifyRGB = true;
- _t._blendFunc.src = cc.BLEND_SRC;
- _t._blendFunc.dst = cc.BLEND_DST;
- _t._flippedX = _t._flippedY = false;
- // default transform anchor: center
- _t.anchorX = 0.5;
- _t.anchorY = 0.5;
- // zwoptex default values
- _t._offsetPosition.x = 0;
- _t._offsetPosition.y = 0;
- _t._hasChildren = false;
- var locTextureLoaded = texture.isLoaded();
- _t._textureLoaded = locTextureLoaded;
- if (!locTextureLoaded) {
- _t._rectRotated = rotated;
- if (rect) {
- _t._rect.x = rect.x;
- _t._rect.y = rect.y;
- _t._rect.width = rect.width;
- _t._rect.height = rect.height;
- }
- if(_t.texture)
- _t.texture.removeLoadedEventListener(_t);
- texture.addLoadedEventListener(_t._textureLoadedCallback, _t);
- _t.texture = texture;
- return true;
- }
- if (!rect) {
- rect = cc.rect(0, 0, texture.width, texture.height);
- }
- if(texture && texture.url) {
- var _x = rect.x + rect.width, _y = rect.y + rect.height;
- if(_x > texture.width){
- cc.error(cc._LogInfos.RectWidth, texture.url);
- }
- if(_y > texture.height){
- cc.error(cc._LogInfos.RectHeight, texture.url);
- }
- }
- _t._originalTexture = texture;
- _t.texture = texture;
- _t.setTextureRect(rect, rotated);
- // by default use "Self Render".
- // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
- _t.batchNode = null;
- return true;
- };
- _p._textureLoadedCallback = function (sender) {
- var _t = this;
- if(_t._textureLoaded)
- return;
- _t._textureLoaded = true;
- var locRect = _t._rect;
- if (!locRect) {
- locRect = cc.rect(0, 0, sender.width, sender.height);
- } else if (cc._rectEqualToZero(locRect)) {
- locRect.width = sender.width;
- locRect.height = sender.height;
- }
- _t._originalTexture = sender;
- _t.texture = sender;
- _t.setTextureRect(locRect, _t._rectRotated);
- //set the texture's color after the it loaded
- var locColor = this._displayedColor;
- if(locColor.r != 255 || locColor.g != 255 || locColor.b != 255)
- _t._changeTextureColor();
- // by default use "Self Render".
- // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
- _t.batchNode = _t._batchNode;
- _t._callLoadedEventCallbacks();
- };
- _p.setTextureRect = function (rect, rotated, untrimmedSize) {
- var _t = this;
- _t._rectRotated = rotated || false;
- _t.setContentSize(untrimmedSize || rect);
- _t.setVertexRect(rect);
- var locTextureRect = _t._textureRect_Canvas, scaleFactor = cc.contentScaleFactor();
- locTextureRect.x = 0 | (rect.x * scaleFactor);
- locTextureRect.y = 0 | (rect.y * scaleFactor);
- locTextureRect.width = 0 | (rect.width * scaleFactor);
- locTextureRect.height = 0 | (rect.height * scaleFactor);
- locTextureRect.validRect = !(locTextureRect.width === 0 || locTextureRect.height === 0 || locTextureRect.x < 0 || locTextureRect.y < 0);
- var relativeOffset = _t._unflippedOffsetPositionFromCenter;
- if (_t._flippedX)
- relativeOffset.x = -relativeOffset.x;
- if (_t._flippedY)
- relativeOffset.y = -relativeOffset.y;
- _t._offsetPosition.x = relativeOffset.x + (_t._contentSize.width - _t._rect.width) / 2;
- _t._offsetPosition.y = relativeOffset.y + (_t._contentSize.height - _t._rect.height) / 2;
- // rendering using batch node
- if (_t._batchNode) {
- // update dirty, don't update _recursiveDirty
- _t.dirty = true;
- }
- };
- _p.updateTransform = function () {
- var _t = this;
- //cc.assert(_t._batchNode, "updateTransform is only valid when cc.Sprite is being rendered using an cc.SpriteBatchNode");
- // recaculate matrix only if it is dirty
- if (_t.dirty) {
- // If it is not visible, or one of its ancestors is not visible, then do nothing:
- var locParent = _t._parent;
- if (!_t._visible || ( locParent && locParent != _t._batchNode && locParent._shouldBeHidden)) {
- _t._shouldBeHidden = true;
- } else {
- _t._shouldBeHidden = false;
- if (!locParent || locParent == _t._batchNode) {
- _t._transformToBatch = _t.nodeToParentTransform();
- } else {
- //cc.assert(_t._parent instanceof cc.Sprite, "Logic error in CCSprite. Parent must be a CCSprite");
- _t._transformToBatch = cc.affineTransformConcat(_t.nodeToParentTransform(), locParent._transformToBatch);
- }
- }
- _t._recursiveDirty = false;
- _t.dirty = false;
- }
- // recursively iterate over children
- if (_t._hasChildren)
- _t._arrayMakeObjectsPerformSelector(_t._children, cc.Node._StateCallbackType.updateTransform);
- };
- _p.addChild = function (child, localZOrder, tag) {
- cc.assert(child, cc._LogInfos.CCSpriteBatchNode_addChild_2);
- if (localZOrder == null)
- localZOrder = child._localZOrder;
- if (tag == null)
- tag = child.tag;
- //cc.Node already sets isReorderChildDirty_ so this needs to be after batchNode check
- cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
- this._hasChildren = true;
- };
- _p.setOpacity = function (opacity) {
- cc.Node.prototype.setOpacity.call(this, opacity);
- this._setNodeDirtyForCache();
- };
- _p.setColor = function (color3) {
- var _t = this;
- var curColor = _t.color;
- this._oldDisplayColor = curColor;
- if ((curColor.r === color3.r) && (curColor.g === color3.g) && (curColor.b === color3.b))
- return;
- cc.Node.prototype.setColor.call(_t, color3);
- };
- _p.updateDisplayedColor = function (parentColor) {
- var _t = this;
- cc.Node.prototype.updateDisplayedColor.call(_t, parentColor);
- var oColor = _t._oldDisplayColor;
- var nColor = _t._displayedColor;
- if (oColor.r === nColor.r && oColor.g === nColor.g && oColor.b === nColor.b)
- return;
- _t._changeTextureColor();
- _t._setNodeDirtyForCache();
- };
- _p.setSpriteFrame = function (newFrame) {
- var _t = this;
- if(typeof(newFrame) == "string"){
- newFrame = cc.spriteFrameCache.getSpriteFrame(newFrame);
- cc.assert(newFrame, cc._LogInfos.CCSpriteBatchNode_setSpriteFrame)
- }
- _t.setNodeDirty(true);
- var frameOffset = newFrame.getOffset();
- _t._unflippedOffsetPositionFromCenter.x = frameOffset.x;
- _t._unflippedOffsetPositionFromCenter.y = frameOffset.y;
- // update rect
- _t._rectRotated = newFrame.isRotated();
- var pNewTexture = newFrame.getTexture();
- var locTextureLoaded = newFrame.textureLoaded();
- if (!locTextureLoaded) {
- _t._textureLoaded = false;
- newFrame.addLoadedEventListener(function (sender) {
- _t._textureLoaded = true;
- var locNewTexture = sender.getTexture();
- if (locNewTexture != _t._texture)
- _t.texture = locNewTexture;
- _t.setTextureRect(sender.getRect(), sender.isRotated(), sender.getOriginalSize());
- _t._callLoadedEventCallbacks();
- }, _t);
- }
- // update texture before updating texture rect
- if (pNewTexture != _t._texture)
- _t.texture = pNewTexture;
- if (_t._rectRotated)
- _t._originalTexture = pNewTexture;
- _t.setTextureRect(newFrame.getRect(), _t._rectRotated, newFrame.getOriginalSize());
- _t._colorized = false;
- if (locTextureLoaded) {
- var curColor = _t.color;
- if (curColor.r !== 255 || curColor.g !== 255 || curColor.b !== 255)
- _t._changeTextureColor();
- }
- };
- _p.isFrameDisplayed = function (frame) {
- if (frame.getTexture() != this._texture)
- return false;
- return cc.rectEqualToRect(frame.getRect(), this._rect);
- };
- _p.setBatchNode = function (spriteBatchNode) {
- var _t = this;
- _t._batchNode = spriteBatchNode; // weak reference
- // self render
- if (!_t._batchNode) {
- _t.atlasIndex = cc.Sprite.INDEX_NOT_INITIALIZED;
- _t.textureAtlas = null;
- _t._recursiveDirty = false;
- _t.dirty = false;
- } else {
- // using batch
- _t._transformToBatch = cc.affineTransformIdentity();
- _t.textureAtlas = _t._batchNode.textureAtlas; // weak ref
- }
- };
- _p.setTexture = function (texture) {
- var _t = this;
- if(texture && (typeof(texture) === "string")){
- texture = cc.textureCache.addImage(texture);
- _t.setTexture(texture);
- //TODO
- var size = texture.getContentSize();
- _t.setTextureRect(cc.rect(0,0, size.width, size.height));
- return;
- }
- // CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteSheet
- cc.assert(!texture || texture instanceof cc.Texture2D, cc._LogInfos.CCSpriteBatchNode_setTexture);
- if (_t._texture != texture) {
- if (texture && texture.getHtmlElementObj() instanceof HTMLImageElement) {
- _t._originalTexture = texture;
- }
- _t._texture = texture;
- }
- };
- _p.draw = function (ctx) {
- var _t = this;
- if (!_t._textureLoaded)
- return;
- var context = ctx || cc._renderContext;
- if (_t._blendFuncStr != "source")
- context.globalCompositeOperation = _t._blendFuncStr;
- var locEGL_ScaleX = cc.view.getScaleX(), locEGL_ScaleY = cc.view.getScaleY();
- context.globalAlpha = _t._displayedOpacity / 255;
- var locRect = _t._rect, locContentSize = _t._contentSize, locOffsetPosition = _t._offsetPosition, locDrawSizeCanvas = _t._drawSize_Canvas;
- var flipXOffset = 0 | (locOffsetPosition.x), flipYOffset = -locOffsetPosition.y - locRect.height, locTextureCoord = _t._textureRect_Canvas;
- locDrawSizeCanvas.width = locRect.width * locEGL_ScaleX;
- locDrawSizeCanvas.height = locRect.height * locEGL_ScaleY;
- if (_t._flippedX || _t._flippedY) {
- context.save();
- if (_t._flippedX) {
- flipXOffset = -locOffsetPosition.x - locRect.width;
- context.scale(-1, 1);
- }
- if (_t._flippedY) {
- flipYOffset = locOffsetPosition.y;
- context.scale(1, -1);
- }
- }
- flipXOffset *= locEGL_ScaleX;
- flipYOffset *= locEGL_ScaleY;
- if (_t._texture && locTextureCoord.validRect) {
- var image = _t._texture.getHtmlElementObj();
- if (_t._colorized) {
- context.drawImage(image,
- 0, 0, locTextureCoord.width, locTextureCoord.height,
- flipXOffset, flipYOffset, locDrawSizeCanvas.width, locDrawSizeCanvas.height);
- } else {
- context.drawImage(image,
- locTextureCoord.x, locTextureCoord.y, locTextureCoord.width, locTextureCoord.height,
- flipXOffset, flipYOffset, locDrawSizeCanvas.width , locDrawSizeCanvas.height);
- }
- } else if (!_t._texture && locTextureCoord.validRect) {
- var curColor = _t.color;
- context.fillStyle = "rgba(" + curColor.r + "," + curColor.g + "," + curColor.b + ",1)";
- context.fillRect(flipXOffset, flipYOffset, locContentSize.width * locEGL_ScaleX, locContentSize.height * locEGL_ScaleY);
- }
- if (cc.SPRITE_DEBUG_DRAW === 1 || _t._showNode) {
- // draw bounding box
- context.strokeStyle = "rgba(0,255,0,1)";
- flipXOffset /= locEGL_ScaleX;
- flipYOffset /= locEGL_ScaleY;
- flipYOffset = -flipYOffset;
- var vertices1 = [cc.p(flipXOffset, flipYOffset),
- cc.p(flipXOffset + locRect.width, flipYOffset),
- cc.p(flipXOffset + locRect.width, flipYOffset - locRect.height),
- cc.p(flipXOffset, flipYOffset - locRect.height)];
- cc._drawingUtil.drawPoly(vertices1, 4, true);
- } else if (cc.SPRITE_DEBUG_DRAW === 2) {
- // draw texture box
- context.strokeStyle = "rgba(0,255,0,1)";
- var drawRect = _t._rect;
- flipYOffset = -flipYOffset;
- var vertices2 = [cc.p(flipXOffset, flipYOffset), cc.p(flipXOffset + drawRect.width, flipYOffset),
- cc.p(flipXOffset + drawRect.width, flipYOffset - drawRect.height), cc.p(flipXOffset, flipYOffset - drawRect.height)];
- cc._drawingUtil.drawPoly(vertices2, 4, true);
- }
- if (_t._flippedX || _t._flippedY)
- context.restore();
- cc.g_NumberOfDraws++;
- };
- if(!cc.sys._supportCanvasNewBlendModes)
- _p._changeTextureColor = function () {
- var locElement, locTexture = this._texture, locRect = this._textureRect_Canvas; //this.getTextureRect();
- if (locTexture && locRect.validRect && this._originalTexture) {
- locElement = locTexture.getHtmlElementObj();
- if (!locElement)
- return;
- var cacheTextureForColor = cc.textureCache.getTextureColors(this._originalTexture.getHtmlElementObj());
- if (cacheTextureForColor) {
- this._colorized = true;
- //generate color texture cache
- if (locElement instanceof HTMLCanvasElement && !this._rectRotated && !this._newTextureWhenChangeColor)
- cc.generateTintImage(locElement, cacheTextureForColor, this._displayedColor, locRect, locElement);
- else {
- locElement = cc.generateTintImage(locElement, cacheTextureForColor, this._displayedColor, locRect);
- locTexture = new cc.Texture2D();
- locTexture.initWithElement(locElement);
- locTexture.handleLoadedTexture();
- this.texture = locTexture;
- }
- }
- }
- };
- delete _p;
- } else {
- cc.assert(typeof cc._tmp.WebGLSprite === "function", cc._LogInfos.MissingFile, "SpritesWebGL.js");
- cc._tmp.WebGLSprite();
- delete cc._tmp.WebGLSprite;
- }
- cc.assert(typeof cc._tmp.PrototypeSprite === "function", cc._LogInfos.MissingFile, "SpritesPropertyDefine.js");
- cc._tmp.PrototypeSprite();
- delete cc._tmp.PrototypeSprite;
|