CCSprite.js 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323
  1. /****************************************************************************
  2. Copyright (c) 2010-2012 cocos2d-x.org
  3. Copyright (c) 2008-2010 Ricardo Quesada
  4. Copyright (c) 2011 Zynga Inc.
  5. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. /**
  23. * cc.Sprite invalid index on the cc.SpriteBatchNode
  24. * @constant
  25. * @type Number
  26. */
  27. cc.SPRITE_INDEX_NOT_INITIALIZED = -1;
  28. /**
  29. * generate texture's cache for texture tint
  30. * @function
  31. * @param {HTMLImageElement} texture
  32. * @return {Array}
  33. */
  34. cc.generateTextureCacheForColor = function (texture) {
  35. if (texture.channelCache) {
  36. return texture.channelCache;
  37. }
  38. var textureCache = [
  39. document.createElement("canvas"),
  40. document.createElement("canvas"),
  41. document.createElement("canvas"),
  42. document.createElement("canvas")
  43. ];
  44. function renderToCache() {
  45. var ref = cc.generateTextureCacheForColor;
  46. var w = texture.width;
  47. var h = texture.height;
  48. textureCache[0].width = w;
  49. textureCache[0].height = h;
  50. textureCache[1].width = w;
  51. textureCache[1].height = h;
  52. textureCache[2].width = w;
  53. textureCache[2].height = h;
  54. textureCache[3].width = w;
  55. textureCache[3].height = h;
  56. ref.canvas.width = w;
  57. ref.canvas.height = h;
  58. var ctx = ref.canvas.getContext("2d");
  59. ctx.drawImage(texture, 0, 0);
  60. ref.tempCanvas.width = w;
  61. ref.tempCanvas.height = h;
  62. var pixels = ctx.getImageData(0, 0, w, h).data;
  63. for (var rgbI = 0; rgbI < 4; rgbI++) {
  64. var cacheCtx = textureCache[rgbI].getContext('2d');
  65. cacheCtx.getImageData(0, 0, w, h).data;
  66. ref.tempCtx.drawImage(texture, 0, 0);
  67. var to = ref.tempCtx.getImageData(0, 0, w, h);
  68. var toData = to.data;
  69. for (var i = 0; i < pixels.length; i += 4) {
  70. toData[i ] = (rgbI === 0) ? pixels[i ] : 0;
  71. toData[i + 1] = (rgbI === 1) ? pixels[i + 1] : 0;
  72. toData[i + 2] = (rgbI === 2) ? pixels[i + 2] : 0;
  73. toData[i + 3] = pixels[i + 3];
  74. }
  75. cacheCtx.putImageData(to, 0, 0);
  76. }
  77. texture.onload = null;
  78. }
  79. try {
  80. renderToCache();
  81. } catch (e) {
  82. texture.onload = renderToCache;
  83. }
  84. texture.channelCache = textureCache;
  85. return textureCache;
  86. };
  87. cc.generateTextureCacheForColor.canvas = document.createElement('canvas');
  88. cc.generateTextureCacheForColor.tempCanvas = document.createElement('canvas');
  89. cc.generateTextureCacheForColor.tempCtx = cc.generateTextureCacheForColor.tempCanvas.getContext('2d');
  90. /**
  91. * generate tinted texture
  92. * source-in: Where source and destination overlaps and both are opaque, the source is displayed.
  93. * Everywhere else transparency is displayed.
  94. * @function
  95. * @param {HTMLImageElement} texture
  96. * @param {cc.Color3B|cc.Color4F} color
  97. * @param {cc.Rect} rect
  98. * @return {HTMLCanvasElement}
  99. */
  100. cc.generateTintImage2 = function (texture, color, rect) {
  101. if (!rect) {
  102. rect = cc.rect(0, 0, texture.width, texture.height);
  103. rect = cc.RECT_PIXELS_TO_POINTS(rect);
  104. }
  105. var selColor;
  106. if (color instanceof cc.Color4F) {
  107. selColor = cc.c4b(color.r * 255, color.g * 255, color.b * 255, color.a * 255);
  108. } else {
  109. selColor = cc.c4b(color.r, color.g, color.b, 50);//color;
  110. }
  111. var buff = document.createElement("canvas");
  112. var ctx = buff.getContext("2d");
  113. if (buff.width != rect.width) buff.width = rect.width;
  114. if (buff.height != rect.height) buff.height = rect.height;
  115. ctx.save();
  116. ctx.drawImage(texture, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height);
  117. ctx.globalCompositeOperation = "source-in";
  118. ctx.globalAlpha = selColor.a / 255.0;
  119. ctx.fillStyle = "rgb(" + selColor.r + "," + selColor.g + "," + selColor.b + ")";
  120. ctx.fillRect(0, 0, rect.width, rect.height);
  121. ctx.restore();
  122. return buff;
  123. };
  124. /**
  125. * generate tinted texture
  126. * lighter: The source and destination colors are added to each other, resulting in brighter colors,
  127. * moving towards color values of 1 (maximum brightness for that color).
  128. * @function
  129. * @param {HTMLImageElement} texture
  130. * @param {Array} tintedImgCache
  131. * @param {cc.Color3B|cc.Color4F} color
  132. * @param {cc.Rect} rect
  133. * @param {HTMLCanvasElement} [renderCanvas]
  134. * @return {HTMLCanvasElement}
  135. */
  136. cc.generateTintImage = function (texture, tintedImgCache, color, rect, renderCanvas) {
  137. if (!rect)
  138. rect = cc.rect(0, 0, texture.width, texture.height);
  139. var selColor;
  140. if (color.a == null) {
  141. // Optimization for the particle system which mainly uses c4f colors
  142. selColor = cc.c4f(color.r / 255.0, color.g / 255.0, color.b / 255, 1);
  143. } else {
  144. selColor = color;
  145. }
  146. var w = Math.min(rect.width, tintedImgCache[0].width);
  147. var h = Math.min(rect.height, tintedImgCache[0].height);
  148. var buff = renderCanvas;
  149. var ctx;
  150. // Create a new buffer if required
  151. if (!buff) {
  152. buff = document.createElement("canvas");
  153. buff.width = w;
  154. buff.height = h;
  155. ctx = buff.getContext("2d");
  156. } else {
  157. ctx = buff.getContext("2d");
  158. ctx.clearRect(0, 0, w, h);
  159. }
  160. ctx.save();
  161. ctx.globalCompositeOperation = 'lighter';
  162. // Make sure to keep the renderCanvas alpha in mind in case of overdraw
  163. var a = ctx.globalAlpha;
  164. if (selColor.r > 0) {
  165. ctx.globalAlpha = selColor.r * a;
  166. ctx.drawImage(tintedImgCache[0], rect.x, rect.y, w, h, 0, 0, w, h);
  167. }
  168. if (selColor.g > 0) {
  169. ctx.globalAlpha = selColor.g * a;
  170. ctx.drawImage(tintedImgCache[1], rect.x, rect.y, w, h, 0, 0, w, h);
  171. }
  172. if (selColor.b > 0) {
  173. ctx.globalAlpha = selColor.b * a;
  174. ctx.drawImage(tintedImgCache[2], rect.x, rect.y, w, h, 0, 0, w, h);
  175. }
  176. if (selColor.r + selColor.g + selColor.b < 1) {
  177. ctx.globalAlpha = a;
  178. ctx.drawImage(tintedImgCache[3], rect.x, rect.y, w, h, 0, 0, w, h);
  179. }
  180. ctx.restore();
  181. return buff;
  182. };
  183. cc.cutRotateImageToCanvas = function (texture, rect) {
  184. if (!texture)
  185. return null;
  186. if (!rect)
  187. return texture;
  188. var nCanvas = document.createElement("canvas");
  189. nCanvas.width = rect.width;
  190. nCanvas.height = rect.height;
  191. var ctx = nCanvas.getContext("2d");
  192. ctx.translate(nCanvas.width / 2, nCanvas.height / 2);
  193. ctx.rotate(-1.5707963267948966);
  194. ctx.drawImage(texture, rect.x, rect.y, rect.height, rect.width, -rect.height / 2, -rect.width / 2, rect.height, rect.width);
  195. return nCanvas;
  196. };
  197. /**
  198. * a Values object for transform
  199. * @Class
  200. * @Construct
  201. * @param {cc.Point} pos position x and y
  202. * @param {cc.Point} scale scale x and y
  203. * @param {Number} rotation
  204. * @param {cc.Point} skew skew x and y
  205. * @param {cc.Point} ap anchor point in pixels
  206. * @param {Boolean} visible
  207. */
  208. cc.TransformValues = function (pos, scale, rotation, skew, ap, visible) {
  209. this.pos = pos; // position x and y
  210. this.scale = scale; // scale x and y
  211. this.rotation = rotation;
  212. this.skew = skew; // skew x and y
  213. this.ap = ap; // anchor point in pixels
  214. this.visible = visible;
  215. };
  216. cc.RENDER_IN_SUBPIXEL = function (A) {
  217. return (0 | A);
  218. };
  219. if (cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) {
  220. cc.RENDER_IN_SUBPIXEL = function (A) {
  221. return A;
  222. };
  223. }
  224. /**
  225. * <p>cc.Sprite is a 2d image ( http://en.wikipedia.org/wiki/Sprite_(computer_graphics) ) <br/>
  226. *
  227. * cc.Sprite can be created with an image, or with a sub-rectangle of an image. <br/>
  228. *
  229. * If the parent or any of its ancestors is a cc.SpriteBatchNode then the following features/limitations are valid <br/>
  230. * - Features when the parent is a cc.BatchNode: <br/>
  231. * - MUCH faster rendering, specially if the cc.SpriteBatchNode has many children. All the children will be drawn in a single batch. <br/>
  232. *
  233. * - Limitations <br/>
  234. * - Camera is not supported yet (eg: CCOrbitCamera action doesn't work) <br/>
  235. * - GridBase actions are not supported (eg: CCLens, CCRipple, CCTwirl) <br/>
  236. * - The Alias/Antialias property belongs to CCSpriteBatchNode, so you can't individually set the aliased property. <br/>
  237. * - The Blending function property belongs to CCSpriteBatchNode, so you can't individually set the blending function property. <br/>
  238. * - Parallax scroller is not supported, but can be simulated with a "proxy" sprite. <br/>
  239. *
  240. * If the parent is an standard cc.Node, then cc.Sprite behaves like any other cc.Node: <br/>
  241. * - It supports blending functions <br/>
  242. * - It supports aliasing / antialiasing <br/>
  243. * - But the rendering will be slower: 1 draw per children. <br/>
  244. *
  245. * The default anchorPoint in cc.Sprite is (0.5, 0.5). </p>
  246. * @class
  247. * @extends cc.NodeRGBA
  248. *
  249. * @example
  250. * var aSprite = new cc.Sprite();
  251. * aSprite.initWithFile("HelloHTML5World.png",cc.rect(0,0,480,320));
  252. */
  253. cc.Sprite = cc.NodeRGBA.extend(/** @lends cc.Sprite# */{
  254. RGBAProtocol:true,
  255. //
  256. // Data used when the sprite is rendered using a CCSpriteSheet
  257. //
  258. _textureAtlas:null, //cc.SpriteBatchNode texture atlas
  259. _atlasIndex:0,
  260. _batchNode:null,
  261. _dirty:false, //Whether the sprite needs to be updated
  262. _recursiveDirty:null, //Whether all of the sprite's children needs to be updated
  263. _hasChildren:null, //Whether the sprite contains children
  264. _shouldBeHidden:false, //should not be drawn because one of the ancestors is not visible
  265. _transformToBatch:null,
  266. //
  267. // Data used when the sprite is self-rendered
  268. //
  269. _blendFunc:null, //It's required for CCTextureProtocol inheritance
  270. _texture:null, //cc.Texture2D object that is used to render the sprite
  271. //
  272. // Shared data
  273. //
  274. // texture
  275. _rect:null, //Retangle of cc.Texture2D
  276. _rectRotated:false, //Whether the texture is rotated
  277. // Offset Position (used by Zwoptex)
  278. _offsetPosition:null, // absolute
  279. _unflippedOffsetPositionFromCenter:null,
  280. _opacityModifyRGB:false,
  281. // image is flipped
  282. _flippedX:false, //Whether the sprite is flipped horizontally or not.
  283. _flippedY:false, //Whether the sprite is flipped vertically or not.
  284. _textureLoaded:false,
  285. _loadedEventListeners: null,
  286. _newTextureWhenChangeColor: null, //hack property for LabelBMFont
  287. textureLoaded:function(){
  288. return this._textureLoaded;
  289. },
  290. addLoadedEventListener:function(callback, target){
  291. if(!this._loadedEventListeners)
  292. this._loadedEventListeners = [];
  293. this._loadedEventListeners.push({eventCallback:callback, eventTarget:target});
  294. },
  295. _callLoadedEventCallbacks:function(){
  296. if(!this._loadedEventListeners)
  297. return;
  298. var locListeners = this._loadedEventListeners;
  299. for(var i = 0, len = locListeners.length; i < len; i++){
  300. var selCallback = locListeners[i];
  301. cc.doCallback(selCallback.eventCallback, selCallback.eventTarget, this);
  302. }
  303. locListeners.length = 0;
  304. },
  305. /**
  306. * Whether or not the Sprite needs to be updated in the Atlas
  307. * @return {Boolean} true if the sprite needs to be updated in the Atlas, false otherwise.
  308. */
  309. isDirty:function () {
  310. return this._dirty;
  311. },
  312. /**
  313. * Makes the Sprite to be updated in the Atlas.
  314. * @param {Boolean} bDirty
  315. */
  316. setDirty:function (bDirty) {
  317. this._dirty = bDirty;
  318. },
  319. /**
  320. * Returns whether or not the texture rectangle is rotated.
  321. * @return {Boolean}
  322. */
  323. isTextureRectRotated:function () {
  324. return this._rectRotated;
  325. },
  326. /**
  327. * Returns the index used on the TextureAtlas.
  328. * @return {Number}
  329. */
  330. getAtlasIndex:function () {
  331. return this._atlasIndex;
  332. },
  333. /**
  334. * Set the index used on the TextureAtlas.
  335. * @warning Don't modify this value unless you know what you are doing
  336. * @param {Number} atlasIndex
  337. */
  338. setAtlasIndex:function (atlasIndex) {
  339. this._atlasIndex = atlasIndex;
  340. },
  341. /**
  342. * returns the rect of the cc.Sprite in points
  343. * @return {cc.Rect}
  344. */
  345. getTextureRect:function () {
  346. return cc.rect(this._rect.x, this._rect.y, this._rect.width, this._rect.height);
  347. },
  348. /**
  349. * Gets the weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode
  350. * @return {cc.TextureAtlas}
  351. */
  352. getTextureAtlas:function () {
  353. return this._textureAtlas;
  354. },
  355. /**
  356. * Sets the weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode
  357. * @param {cc.TextureAtlas} textureAtlas
  358. */
  359. setTextureAtlas:function (textureAtlas) {
  360. this._textureAtlas = textureAtlas;
  361. },
  362. /**
  363. * return the SpriteBatchNode of the cc.Sprite
  364. * @return {cc.SpriteBatchNode}
  365. */
  366. getSpriteBatchNode:function () {
  367. return this._batchNode;
  368. },
  369. /**
  370. * set the SpriteBatchNode of the cc.Sprite
  371. * @param {cc.SpriteBatchNode} spriteBatchNode
  372. */
  373. setSpriteBatchNode:function (spriteBatchNode) {
  374. this._batchNode = spriteBatchNode;
  375. },
  376. /**
  377. * Gets the offset position of the sprite. Calculated automatically by editors like Zwoptex.
  378. * @return {cc.Point}
  379. */
  380. getOffsetPosition:function () {
  381. return cc.p(this._offsetPosition);
  382. },
  383. /**
  384. * conforms to cc.TextureProtocol protocol
  385. * @return {cc.BlendFunc}
  386. */
  387. getBlendFunc:function () {
  388. return this._blendFunc;
  389. },
  390. /**
  391. * Initializes a sprite with an SpriteFrame. The texture and rect in SpriteFrame will be applied on this sprite
  392. * @param {cc.SpriteFrame} spriteFrame A CCSpriteFrame object. It should includes a valid texture and a rect
  393. * @return {Boolean} true if the sprite is initialized properly, false otherwise.
  394. * @example
  395. * var spriteFrame = cc.SpriteFrameCache.getInstance().getSpriteFrame("grossini_dance_01.png");
  396. * var sprite = new cc.Sprite();
  397. * sprite.initWithSpriteFrame(spriteFrame);
  398. */
  399. initWithSpriteFrame:function (spriteFrame) {
  400. if(!spriteFrame)
  401. throw "cc.Sprite.initWithSpriteFrame(): spriteFrame should be non-null";
  402. if(!spriteFrame.textureLoaded()){
  403. //add event listener
  404. this._textureLoaded = false;
  405. spriteFrame.addLoadedEventListener(this._spriteFrameLoadedCallback, this);
  406. }
  407. var ret = this.initWithTexture(spriteFrame.getTexture(), spriteFrame.getRect());
  408. this.setDisplayFrame(spriteFrame);
  409. return ret;
  410. },
  411. _spriteFrameLoadedCallback:null,
  412. _spriteFrameLoadedCallbackForWebGL:function(spriteFrame){
  413. this.setNodeDirty();
  414. this.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize());
  415. this._callLoadedEventCallbacks();
  416. },
  417. _spriteFrameLoadedCallbackForCanvas:function(spriteFrame){
  418. this.setNodeDirty();
  419. this.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize());
  420. var curColor = this.getColor();
  421. if (curColor.r !== 255 || curColor.g !== 255 || curColor.b !== 255)
  422. this._changeTextureColor();
  423. this._callLoadedEventCallbacks();
  424. },
  425. /**
  426. * Initializes a sprite with a sprite frame name. <br/>
  427. * A cc.SpriteFrame will be fetched from the cc.SpriteFrameCache by name. <br/>
  428. * If the cc.SpriteFrame doesn't exist it will raise an exception. <br/>
  429. * @param {String} spriteFrameName A key string that can fected a volid cc.SpriteFrame from cc.SpriteFrameCache
  430. * @return {Boolean} true if the sprite is initialized properly, false otherwise.
  431. * @example
  432. * var sprite = new cc.Sprite();
  433. * sprite.initWithSpriteFrameName("grossini_dance_01.png");
  434. */
  435. initWithSpriteFrameName:function (spriteFrameName) {
  436. if(!spriteFrameName)
  437. throw "cc.Sprite.initWithSpriteFrameName(): spriteFrameName should be non-null";
  438. var frame = cc.SpriteFrameCache.getInstance().getSpriteFrame(spriteFrameName);
  439. if(!frame)
  440. throw spriteFrameName + " is null, please check.";
  441. return this.initWithSpriteFrame(frame);
  442. },
  443. /**
  444. * tell the sprite to use batch node render.
  445. * @param {cc.SpriteBatchNode} batchNode
  446. */
  447. useBatchNode:function (batchNode) {
  448. this._textureAtlas = batchNode.getTextureAtlas(); // weak ref
  449. this._batchNode = batchNode;
  450. },
  451. /**
  452. * <p>
  453. * set the vertex rect.<br/>
  454. * It will be called internally by setTextureRect. <br/>
  455. * Useful if you want to create 2x images from SD images in Retina Display. <br/>
  456. * Do not call it manually. Use setTextureRect instead. <br/>
  457. * (override this method to generate "double scale" sprites)
  458. * </p>
  459. * @param {cc.Rect} rect
  460. */
  461. setVertexRect:function (rect) {
  462. this._rect.x = rect.x;
  463. this._rect.y = rect.y;
  464. this._rect.width = rect.width;
  465. this._rect.height = rect.height;
  466. },
  467. sortAllChildren:function () {
  468. if (this._reorderChildDirty) {
  469. var j, tempItem, locChildren = this._children, tempChild;
  470. for (var i = 1; i < locChildren.length; i++) {
  471. tempItem = locChildren[i];
  472. j = i - 1;
  473. tempChild = locChildren[j];
  474. //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
  475. while (j >= 0 && ( tempItem._zOrder < tempChild._zOrder ||
  476. ( tempItem._zOrder == tempChild._zOrder && tempItem._orderOfArrival < tempChild._orderOfArrival ))) {
  477. locChildren[j + 1] = tempChild;
  478. j = j - 1;
  479. tempChild = locChildren[j];
  480. }
  481. locChildren[j + 1] = tempItem;
  482. }
  483. if (this._batchNode) {
  484. this._arrayMakeObjectsPerformSelector(locChildren, cc.Node.StateCallbackType.sortAllChildren);
  485. }
  486. this._reorderChildDirty = false;
  487. }
  488. },
  489. /**
  490. * Reorders a child according to a new z value. (override cc.Node )
  491. * @param {cc.Node} child
  492. * @param {Number} zOrder
  493. * @override
  494. */
  495. reorderChild:function (child, zOrder) {
  496. if(!child)
  497. throw "cc.Sprite.reorderChild(): child should be non-null";
  498. if(this._children.indexOf(child) === -1){
  499. cc.log("cc.Sprite.reorderChild(): this child is not in children list");
  500. return;
  501. }
  502. if (zOrder === child.getZOrder())
  503. return;
  504. if (this._batchNode && !this._reorderChildDirty) {
  505. this._setReorderChildDirtyRecursively();
  506. this._batchNode.reorderBatch(true);
  507. }
  508. cc.Node.prototype.reorderChild.call(this, child, zOrder);
  509. },
  510. /**
  511. * Removes a child from the sprite. (override cc.Node )
  512. * @param child
  513. * @param cleanup whether or not cleanup all running actions
  514. * @override
  515. */
  516. removeChild:function (child, cleanup) {
  517. if (this._batchNode)
  518. this._batchNode.removeSpriteFromAtlas(child);
  519. cc.Node.prototype.removeChild.call(this, child, cleanup);
  520. },
  521. /**
  522. * Removes all children from the container (override cc.Node )
  523. * @param cleanup whether or not cleanup all running actions
  524. * @override
  525. */
  526. removeAllChildren:function (cleanup) {
  527. var locChildren = this._children, locBatchNode = this._batchNode;
  528. if (locBatchNode && locChildren != null) {
  529. for (var i = 0, len = locChildren.length; i < len; i++)
  530. locBatchNode.removeSpriteFromAtlas(locChildren[i]);
  531. }
  532. cc.Node.prototype.removeAllChildren.call(this, cleanup);
  533. this._hasChildren = false;
  534. },
  535. //
  536. // cc.Node property overloads
  537. //
  538. /**
  539. * set Recursively is or isn't Dirty
  540. * used only when parent is cc.SpriteBatchNode
  541. * @param {Boolean} value
  542. */
  543. setDirtyRecursively:function (value) {
  544. this._recursiveDirty = value;
  545. this.setDirty(value);
  546. // recursively set dirty
  547. var locChildren = this._children;
  548. if (locChildren != null) {
  549. for (var i = 0; i < locChildren.length; i++) {
  550. if (locChildren[i] instanceof cc.Sprite)
  551. locChildren[i].setDirtyRecursively(true);
  552. }
  553. }
  554. },
  555. /**
  556. * HACK: optimization
  557. */
  558. SET_DIRTY_RECURSIVELY:function () {
  559. if (this._batchNode && !this._recursiveDirty) {
  560. this._recursiveDirty = true;
  561. this._dirty = true;
  562. if (this._hasChildren)
  563. this.setDirtyRecursively(true);
  564. }
  565. },
  566. /**
  567. * position setter (override cc.Node )
  568. * @param {cc.Point|Number} pos position or x value of position
  569. * @param {Number} [yValue] y value of position
  570. * @override
  571. */
  572. setPosition:function (pos, yValue) {
  573. if (arguments.length >= 2)
  574. cc.Node.prototype.setPosition.call(this, pos, arguments[1]);
  575. else
  576. cc.Node.prototype.setPosition.call(this, pos);
  577. this.SET_DIRTY_RECURSIVELY();
  578. },
  579. /**
  580. * Rotation setter (override cc.Node )
  581. * @param {Number} rotation
  582. * @override
  583. */
  584. setRotation:function (rotation) {
  585. cc.Node.prototype.setRotation.call(this, rotation);
  586. this.SET_DIRTY_RECURSIVELY();
  587. },
  588. setRotationX:function (rotationX) {
  589. cc.Node.prototype.setRotationX.call(this, rotationX);
  590. this.SET_DIRTY_RECURSIVELY();
  591. },
  592. setRotationY:function (rotationY) {
  593. cc.Node.prototype.setRotationY.call(this, rotationY);
  594. this.SET_DIRTY_RECURSIVELY();
  595. },
  596. /**
  597. * SkewX setter (override cc.Node )
  598. * @param {Number} sx SkewX value
  599. * @override
  600. */
  601. setSkewX:function (sx) {
  602. cc.Node.prototype.setSkewX.call(this, sx);
  603. this.SET_DIRTY_RECURSIVELY();
  604. },
  605. /**
  606. * SkewY setter (override cc.Node )
  607. * @param {Number} sy SkewY value
  608. * @override
  609. */
  610. setSkewY:function (sy) {
  611. cc.Node.prototype.setSkewY.call(this, sy);
  612. this.SET_DIRTY_RECURSIVELY();
  613. },
  614. /**
  615. * ScaleX setter (override cc.Node )
  616. * @param {Number} scaleX
  617. * @override
  618. */
  619. setScaleX:function (scaleX) {
  620. cc.Node.prototype.setScaleX.call(this, scaleX);
  621. this.SET_DIRTY_RECURSIVELY();
  622. },
  623. /**
  624. * ScaleY setter (override cc.Node )
  625. * @param {Number} scaleY
  626. * @override
  627. */
  628. setScaleY:function (scaleY) {
  629. cc.Node.prototype.setScaleY.call(this, scaleY);
  630. this.SET_DIRTY_RECURSIVELY();
  631. },
  632. /**
  633. * <p>The scale factor of the node. 1.0 is the default scale factor. <br/>
  634. * It modifies the X and Y scale at the same time. (override cc.Node ) <p/>
  635. * @param {Number} scale
  636. * @param {Number|null} [scaleY=]
  637. * @override
  638. */
  639. setScale:function (scale, scaleY) {
  640. cc.Node.prototype.setScale.call(this, scale, scaleY);
  641. this.SET_DIRTY_RECURSIVELY();
  642. },
  643. /**
  644. * VertexZ setter (override cc.Node )
  645. * @param {Number} vertexZ
  646. * @override
  647. */
  648. setVertexZ:function (vertexZ) {
  649. cc.Node.prototype.setVertexZ.call(this, vertexZ);
  650. this.SET_DIRTY_RECURSIVELY();
  651. },
  652. /**
  653. * Sets the anchor point in percent. (override cc.Node )
  654. * @param {cc.Point|Number} anchor The anchor Sprite of Sprite or The anchor point.x of Sprite.
  655. * @param {Number} [y] The anchor point.y of Sprite.
  656. * @override
  657. */
  658. setAnchorPoint:function (anchor, y) {
  659. cc.Node.prototype.setAnchorPoint.call(this, anchor, y);
  660. this.SET_DIRTY_RECURSIVELY();
  661. },
  662. /**
  663. * visible setter (override cc.Node )
  664. * @param {Boolean} visible
  665. * @override
  666. */
  667. setVisible:function (visible) {
  668. cc.Node.prototype.setVisible.call(this, visible);
  669. this.SET_DIRTY_RECURSIVELY();
  670. },
  671. /**
  672. * IsRelativeAnchorPoint setter (override cc.Node )
  673. * @param {Boolean} relative
  674. * @override
  675. */
  676. ignoreAnchorPointForPosition:function (relative) {
  677. if(this._batchNode){
  678. cc.log("cc.Sprite.ignoreAnchorPointForPosition(): it is invalid in cc.Sprite when using SpriteBatchNode");
  679. return;
  680. }
  681. cc.Node.prototype.ignoreAnchorPointForPosition.call(this, relative);
  682. },
  683. /**
  684. * Sets whether the sprite should be flipped horizontally or not.
  685. * @param {Boolean} flippedX true if the sprite should be flipped horizontally, false otherwise.
  686. */
  687. setFlippedX:function (flippedX) {
  688. if (this._flippedX != flippedX) {
  689. this._flippedX = flippedX;
  690. this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
  691. this.setNodeDirty();
  692. }
  693. },
  694. /**
  695. * Sets whether the sprite should be flipped vertically or not.
  696. * @param {Boolean} flippedY true if the sprite should be flipped vertically, false otherwise.
  697. */
  698. setFlippedY:function (flippedY) {
  699. if (this._flippedY != flippedY) {
  700. this._flippedY = flippedY;
  701. this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
  702. this.setNodeDirty();
  703. }
  704. },
  705. /**
  706. * <p>
  707. * Returns the flag which indicates whether the sprite is flipped horizontally or not. <br/>
  708. * <br/>
  709. * It only flips the texture of the sprite, and not the texture of the sprite's children. <br/>
  710. * Also, flipping the texture doesn't alter the anchorPoint. <br/>
  711. * If you want to flip the anchorPoint too, and/or to flip the children too use: <br/>
  712. * sprite->setScaleX(sprite->getScaleX() * -1); <p/>
  713. * @return {Boolean} true if the sprite is flipped horizaontally, false otherwise.
  714. */
  715. isFlippedX:function () {
  716. return this._flippedX;
  717. },
  718. /**
  719. * <p>
  720. * Return the flag which indicates whether the sprite is flipped vertically or not. <br/>
  721. * <br/>
  722. * It only flips the texture of the sprite, and not the texture of the sprite's children. <br/>
  723. * Also, flipping the texture doesn't alter the anchorPoint. <br/>
  724. * If you want to flip the anchorPoint too, and/or to flip the children too use: <br/>
  725. * sprite->setScaleY(sprite->getScaleY() * -1); <p/>
  726. * @return {Boolean} true if the sprite is flipped vertically, flase otherwise.
  727. */
  728. isFlippedY:function () {
  729. return this._flippedY;
  730. },
  731. //
  732. // RGBA protocol
  733. //
  734. /**
  735. * opacity: conforms to CCRGBAProtocol protocol
  736. * @param {Boolean} modify
  737. */
  738. setOpacityModifyRGB:null,
  739. _setOpacityModifyRGBForWebGL: function (modify) {
  740. if (this._opacityModifyRGB !== modify) {
  741. this._opacityModifyRGB = modify;
  742. this.updateColor();
  743. }
  744. },
  745. _setOpacityModifyRGBForCanvas: function (modify) {
  746. if (this._opacityModifyRGB !== modify) {
  747. this._opacityModifyRGB = modify;
  748. this.setNodeDirty();
  749. }
  750. },
  751. /**
  752. * return IsOpacityModifyRGB value
  753. * @return {Boolean}
  754. */
  755. isOpacityModifyRGB:function () {
  756. return this._opacityModifyRGB;
  757. },
  758. updateDisplayedOpacity: null,
  759. _updateDisplayedOpacityForWebGL:function (parentOpacity) {
  760. cc.NodeRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity);
  761. this.updateColor();
  762. },
  763. _updateDisplayedOpacityForCanvas:function (parentOpacity) {
  764. cc.NodeRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity);
  765. this._setNodeDirtyForCache();
  766. },
  767. // Animation
  768. /**
  769. * changes the display frame with animation name and index.<br/>
  770. * The animation name will be get from the CCAnimationCache
  771. * @param animationName
  772. * @param frameIndex
  773. */
  774. setDisplayFrameWithAnimationName:function (animationName, frameIndex) {
  775. if(!animationName)
  776. throw "cc.Sprite.setDisplayFrameWithAnimationName(): animationName must be non-null";
  777. var cache = cc.AnimationCache.getInstance().getAnimation(animationName);
  778. if(!cache){
  779. cc.log("cc.Sprite.setDisplayFrameWithAnimationName(): Frame not found");
  780. return;
  781. }
  782. var animFrame = cache.getFrames()[frameIndex];
  783. if(!animFrame){
  784. cc.log("cc.Sprite.setDisplayFrameWithAnimationName(): Invalid frame index");
  785. return;
  786. }
  787. this.setDisplayFrame(animFrame.getSpriteFrame());
  788. },
  789. /**
  790. * Returns the batch node object if this sprite is rendered by cc.SpriteBatchNode
  791. * @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.
  792. */
  793. getBatchNode:function () {
  794. return this._batchNode;
  795. },
  796. _setReorderChildDirtyRecursively:function () {
  797. //only set parents flag the first time
  798. if (!this._reorderChildDirty) {
  799. this._reorderChildDirty = true;
  800. var pNode = this._parent;
  801. while (pNode && pNode != this._batchNode) {
  802. pNode._setReorderChildDirtyRecursively();
  803. pNode = pNode.getParent();
  804. }
  805. }
  806. },
  807. // CCTextureProtocol
  808. getTexture:function () {
  809. return this._texture;
  810. },
  811. _quad:null, // vertex coords, texture coords and color info
  812. _quadWebBuffer:null,
  813. _quadDirty:false,
  814. _colorized:false,
  815. _isLighterMode:false,
  816. _originalTexture:null,
  817. _textureRect_Canvas:null,
  818. _drawSize_Canvas:null,
  819. /**
  820. * Constructor
  821. * @param {String|cc.SpriteFrame|cc.SpriteBatchNode|HTMLImageElement|cc.Texture2D} fileName sprite construct parameter
  822. */
  823. ctor: null,
  824. _ctorForWebGL: function (fileName) {
  825. cc.NodeRGBA.prototype.ctor.call(this);
  826. this._shouldBeHidden = false;
  827. this._offsetPosition = cc.p(0, 0);
  828. this._unflippedOffsetPositionFromCenter = cc.p(0, 0);
  829. this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
  830. this._rect = cc.rect(0,0,0,0);
  831. this._quad = new cc.V3F_C4B_T2F_Quad();
  832. this._quadWebBuffer = cc.renderContext.createBuffer();
  833. this._quadDirty = true;
  834. this._textureLoaded = true;
  835. if (fileName) {
  836. if (typeof(fileName) === "string") {
  837. var frame = cc.SpriteFrameCache.getInstance().getSpriteFrame(fileName);
  838. this.initWithSpriteFrame(frame);
  839. } else if (typeof(fileName) === "object") {
  840. if (fileName instanceof cc.SpriteFrame) {
  841. this.initWithSpriteFrame(fileName);
  842. } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
  843. var texture2d = new cc.Texture2D();
  844. texture2d.initWithElement(fileName);
  845. texture2d.handleLoadedTexture();
  846. this.initWithTexture(texture2d);
  847. } else if (fileName instanceof cc.Texture2D) {
  848. this.initWithTexture(fileName);
  849. }
  850. }
  851. }
  852. },
  853. _ctorForCanvas: function (fileName) {
  854. cc.NodeRGBA.prototype.ctor.call(this);
  855. this._shouldBeHidden = false;
  856. this._offsetPosition = cc.p(0, 0);
  857. this._unflippedOffsetPositionFromCenter = cc.p(0, 0);
  858. this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
  859. this._rect = cc.rect(0, 0, 0, 0);
  860. this._newTextureWhenChangeColor = false;
  861. this._textureLoaded = true;
  862. this._textureRect_Canvas = {x: 0, y: 0, width: 0, height:0, validRect: false};
  863. this._drawSize_Canvas = cc.size(0, 0);
  864. if (fileName) {
  865. if (typeof(fileName) === "string") {
  866. var frame = cc.SpriteFrameCache.getInstance().getSpriteFrame(fileName);
  867. this.initWithSpriteFrame(frame);
  868. } else if (typeof(fileName) === "object") {
  869. if (fileName instanceof cc.SpriteFrame) {
  870. this.initWithSpriteFrame(fileName);
  871. } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
  872. var texture2d = new cc.Texture2D();
  873. texture2d.initWithElement(fileName);
  874. texture2d.handleLoadedTexture();
  875. this.initWithTexture(texture2d);
  876. } else if (fileName instanceof cc.Texture2D) {
  877. this.initWithTexture(fileName);
  878. }
  879. }
  880. }
  881. },
  882. /**
  883. * Returns the quad (tex coords, vertex coords and color) information.
  884. * @return {cc.V3F_C4B_T2F_Quad}
  885. */
  886. getQuad:function () {
  887. return this._quad;
  888. },
  889. /**
  890. * conforms to cc.TextureProtocol protocol
  891. * @param {Number|cc.BlendFunc} src
  892. * @param {Number} dst
  893. */
  894. setBlendFunc: null,
  895. _setBlendFuncForWebGL: function (src, dst) {
  896. var locBlendFunc = this._blendFunc;
  897. if (dst === undefined) {
  898. locBlendFunc.src = src.src;
  899. locBlendFunc.dst = src.dst;
  900. } else {
  901. locBlendFunc.src = src;
  902. locBlendFunc.dst = dst;
  903. }
  904. },
  905. _setBlendFuncForCanvas: function (src, dst) {
  906. var locBlendFunc = this._blendFunc;
  907. if (dst === undefined) {
  908. locBlendFunc.src = src.src;
  909. locBlendFunc.dst = src.dst;
  910. } else {
  911. locBlendFunc.src = src;
  912. locBlendFunc.dst = dst;
  913. }
  914. this._isLighterMode = (locBlendFunc &&
  915. (( locBlendFunc.src == gl.SRC_ALPHA && locBlendFunc.dst == gl.ONE) || (locBlendFunc.src == gl.ONE && locBlendFunc.dst == gl.ONE)));
  916. },
  917. /**
  918. * Initializes an empty sprite with nothing init.
  919. * @return {Boolean}
  920. */
  921. init:null,
  922. _initForWebGL: function () {
  923. if (arguments.length > 0)
  924. return this.initWithFile(arguments[0], arguments[1]);
  925. cc.NodeRGBA.prototype.init.call(this);
  926. this._dirty = this._recursiveDirty = false;
  927. this._opacityModifyRGB = true;
  928. this._blendFunc.src = cc.BLEND_SRC;
  929. this._blendFunc.dst = cc.BLEND_DST;
  930. // update texture (calls _updateBlendFunc)
  931. this.setTexture(null);
  932. this._textureLoaded = true;
  933. this._flippedX = this._flippedY = false;
  934. // default transform anchor: center
  935. this.setAnchorPoint(0.5, 0.5);
  936. // zwoptex default values
  937. this._offsetPosition.x = 0;
  938. this._offsetPosition.y = 0;
  939. this._hasChildren = false;
  940. // Atlas: Color
  941. var tempColor = {r: 255, g: 255, b: 255, a: 255};
  942. this._quad.bl.colors = tempColor;
  943. this._quad.br.colors = tempColor;
  944. this._quad.tl.colors = tempColor;
  945. this._quad.tr.colors = tempColor;
  946. this._quadDirty = true;
  947. // updated in "useSelfRender"
  948. // Atlas: TexCoords
  949. this.setTextureRect(cc.RectZero(), false, cc.SizeZero());
  950. return true;
  951. },
  952. _initForCanvas: function () {
  953. if (arguments.length > 0)
  954. return this.initWithFile(arguments[0], arguments[1]);
  955. cc.NodeRGBA.prototype.init.call(this);
  956. this._dirty = this._recursiveDirty = false;
  957. this._opacityModifyRGB = true;
  958. this._blendFunc.src = cc.BLEND_SRC;
  959. this._blendFunc.dst = cc.BLEND_DST;
  960. // update texture (calls _updateBlendFunc)
  961. this.setTexture(null);
  962. this._textureLoaded = true;
  963. this._flippedX = this._flippedY = false;
  964. // default transform anchor: center
  965. this.setAnchorPoint(0.5, 0.5);
  966. // zwoptex default values
  967. this._offsetPosition.x = 0;
  968. this._offsetPosition.y = 0;
  969. this._hasChildren = false;
  970. // updated in "useSelfRender"
  971. // Atlas: TexCoords
  972. this.setTextureRect(cc.RectZero(), false, cc.SizeZero());
  973. return true;
  974. },
  975. /**
  976. * <p>
  977. * Initializes a sprite with an image filename.
  978. *
  979. * This method will find pszFilename from local file system, load its content to CCTexture2D,
  980. * then use CCTexture2D to create a sprite.
  981. * After initialization, the rect used will be the size of the image. The offset will be (0,0).
  982. * </p>
  983. * @param {String} filename The path to an image file in local file system
  984. * @param {cc.Rect} rect The rectangle assigned the content area from texture.
  985. * @return {Boolean} true if the sprite is initialized properly, false otherwise.
  986. * @example
  987. * var mySprite = new cc.Sprite();
  988. * mySprite.initWithFile("HelloHTML5World.png",cc.rect(0,0,480,320));
  989. */
  990. initWithFile:function (filename, rect) {
  991. if(!filename)
  992. throw "cc.Sprite.initWithFile(): filename should be non-null";
  993. var texture = cc.TextureCache.getInstance().textureForKey(filename);
  994. if (!texture) {
  995. texture = cc.TextureCache.getInstance().addImage(filename);
  996. return this.initWithTexture(texture, rect);
  997. } else {
  998. if (!rect) {
  999. var size = texture.getContentSize();
  1000. rect = cc.rect(0, 0, size.width, size.height);
  1001. }
  1002. return this.initWithTexture(texture, rect);
  1003. }
  1004. },
  1005. /**
  1006. * Initializes a sprite with a texture and a rect in points, optionally rotated. <br/>
  1007. * After initialization, the rect used will be the size of the texture, and the offset will be (0,0).
  1008. * @param {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture A pointer to an existing CCTexture2D object. You can use a CCTexture2D object for many sprites.
  1009. * @param {cc.Rect} rect Only the contents inside rect of this texture will be applied for this sprite.
  1010. * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
  1011. * @return {Boolean} true if the sprite is initialized properly, false otherwise.
  1012. * @example
  1013. * var img =cc.TextureCache.getInstance().addImage("HelloHTML5World.png");
  1014. * var mySprite = new cc.Sprite();
  1015. * mySprite.initWithTexture(img,cc.rect(0,0,480,320));
  1016. */
  1017. initWithTexture: null,
  1018. _initWithTextureForWebGL: function (texture, rect, rotated) {
  1019. var argnum = arguments.length;
  1020. if (argnum == 0)
  1021. throw "Sprite.initWithTexture(): Argument must be non-nil ";
  1022. rotated = rotated || false;
  1023. if (!cc.NodeRGBA.prototype.init.call(this))
  1024. return false;
  1025. this._batchNode = null;
  1026. this._recursiveDirty = false;
  1027. this._dirty = false;
  1028. this._opacityModifyRGB = true;
  1029. this._blendFunc.src = cc.BLEND_SRC;
  1030. this._blendFunc.dst = cc.BLEND_DST;
  1031. this._flippedX = this._flippedY = false;
  1032. // default transform anchor: center
  1033. this.setAnchorPoint(0.5, 0.5);
  1034. // zwoptex default values
  1035. this._offsetPosition.x = 0;
  1036. this._offsetPosition.y = 0;
  1037. this._hasChildren = false;
  1038. // Atlas: Color
  1039. var tmpColor = new cc.Color4B(255, 255, 255, 255);
  1040. var locQuad = this._quad;
  1041. locQuad.bl.colors = tmpColor;
  1042. locQuad.br.colors = tmpColor;
  1043. locQuad.tl.colors = tmpColor;
  1044. locQuad.tr.colors = tmpColor;
  1045. var locTextureLoaded = texture.isLoaded();
  1046. this._textureLoaded = locTextureLoaded;
  1047. if (!locTextureLoaded) {
  1048. this._rectRotated = rotated || false;
  1049. if (rect) {
  1050. var locRect = this._rect;
  1051. locRect.x = rect.x;
  1052. locRect.y = rect.y;
  1053. locRect.width = rect.width;
  1054. locRect.height = rect.height;
  1055. }
  1056. texture.addLoadedEventListener(this._textureLoadedCallback, this);
  1057. return true;
  1058. }
  1059. if (!rect) {
  1060. var locSize1 = texture.getContentSize();
  1061. rect = cc.rect(0, 0, locSize1.width, locSize1.height);
  1062. }
  1063. this.setTexture(texture);
  1064. this.setTextureRect(rect, rotated, rect._size);
  1065. // by default use "Self Render".
  1066. // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
  1067. this.setBatchNode(null);
  1068. this._quadDirty = true;
  1069. return true;
  1070. },
  1071. _initWithTextureForCanvas: function (texture, rect, rotated) {
  1072. var argnum = arguments.length;
  1073. if (argnum == 0)
  1074. throw "Sprite.initWithTexture(): Argument must be non-nil ";
  1075. rotated = rotated || false;
  1076. if (!cc.NodeRGBA.prototype.init.call(this))
  1077. return false;
  1078. this._batchNode = null;
  1079. this._recursiveDirty = false;
  1080. this._dirty = false;
  1081. this._opacityModifyRGB = true;
  1082. this._blendFunc.src = cc.BLEND_SRC;
  1083. this._blendFunc.dst = cc.BLEND_DST;
  1084. this._flippedX = this._flippedY = false;
  1085. // default transform anchor: center
  1086. this.setAnchorPoint(0.5, 0.5);
  1087. // zwoptex default values
  1088. this._offsetPosition.x = 0;
  1089. this._offsetPosition.y = 0;
  1090. this._hasChildren = false;
  1091. var locTextureLoaded = texture.isLoaded();
  1092. this._textureLoaded = locTextureLoaded;
  1093. if (!locTextureLoaded) {
  1094. this._rectRotated = rotated || false;
  1095. if (rect) {
  1096. this._rect.x = rect.x;
  1097. this._rect.y = rect.y;
  1098. this._rect.width = rect.width;
  1099. this._rect.height = rect.height;
  1100. }
  1101. texture.addLoadedEventListener(this._textureLoadedCallback, this);
  1102. return true;
  1103. }
  1104. if (!rect) {
  1105. var locSize1 = texture.getContentSize();
  1106. rect = cc.rect(0, 0, locSize1.width, locSize1.height);
  1107. }
  1108. this._originalTexture = texture;
  1109. this.setTexture(texture);
  1110. this.setTextureRect(rect, rotated, rect._size);
  1111. // by default use "Self Render".
  1112. // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
  1113. this.setBatchNode(null);
  1114. return true;
  1115. },
  1116. _textureLoadedCallback: null,
  1117. _textureLoadedCallbackForWebGL: function (sender) {
  1118. if(this._textureLoaded)
  1119. return;
  1120. this._textureLoaded = true;
  1121. var locRect = this._rect;
  1122. if (!locRect) {
  1123. var locSize1 = sender.getContentSize();
  1124. locRect = cc.rect(0, 0, locSize1.width, locSize1.height);
  1125. } else if (cc._rectEqualToZero(locRect)) {
  1126. var locSize2 = sender.getContentSize();
  1127. locRect.width = locSize2.width;
  1128. locRect.height = locSize2.height;
  1129. }
  1130. this.setTexture(sender);
  1131. this.setTextureRect(locRect, this._rectRotated, locRect._size);
  1132. // by default use "Self Render".
  1133. // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
  1134. this.setBatchNode(this._batchNode);
  1135. this._quadDirty = true;
  1136. this._callLoadedEventCallbacks();
  1137. },
  1138. _textureLoadedCallbackForCanvas: function (sender) {
  1139. if(this._textureLoaded)
  1140. return;
  1141. this._textureLoaded = true;
  1142. var locRect = this._rect;
  1143. if (!locRect) {
  1144. var locSize1 = sender.getContentSize();
  1145. locRect = cc.rect(0, 0, locSize1.width, locSize1.height);
  1146. } else if (cc._rectEqualToZero(locRect)) {
  1147. var locSize2 = sender.getContentSize();
  1148. locRect.width = locSize2.width;
  1149. locRect.height = locSize2.height;
  1150. }
  1151. this._originalTexture = sender;
  1152. this.setTexture(sender);
  1153. this.setTextureRect(locRect, this._rectRotated, locRect._size);
  1154. // by default use "Self Render".
  1155. // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
  1156. this.setBatchNode(this._batchNode);
  1157. this._callLoadedEventCallbacks();
  1158. },
  1159. /**
  1160. * updates the texture rect of the CCSprite in points.
  1161. * @param {cc.Rect} rect a rect of texture
  1162. * @param {Boolean} rotated
  1163. * @param {cc.Size} untrimmedSize
  1164. */
  1165. setTextureRect:null,
  1166. _setTextureRectForWebGL:function (rect, rotated, untrimmedSize) {
  1167. this._rectRotated = rotated || false;
  1168. untrimmedSize = untrimmedSize || rect._size;
  1169. this.setContentSize(untrimmedSize);
  1170. this.setVertexRect(rect);
  1171. this._setTextureCoords(rect);
  1172. var relativeOffset = this._unflippedOffsetPositionFromCenter;
  1173. if (this._flippedX)
  1174. relativeOffset.x = -relativeOffset.x;
  1175. if (this._flippedY)
  1176. relativeOffset.y = -relativeOffset.y;
  1177. var locRect = this._rect;
  1178. this._offsetPosition.x = relativeOffset.x + (this._contentSize.width - locRect.width) / 2;
  1179. this._offsetPosition.y = relativeOffset.y + (this._contentSize.height - locRect.height) / 2;
  1180. // rendering using batch node
  1181. if (this._batchNode) {
  1182. // update dirty_, don't update recursiveDirty_
  1183. //this.setDirty(true);
  1184. this._dirty = true;
  1185. } else {
  1186. // self rendering
  1187. // Atlas: Vertex
  1188. var x1 = 0 + this._offsetPosition.x;
  1189. var y1 = 0 + this._offsetPosition.y;
  1190. var x2 = x1 + locRect.width;
  1191. var y2 = y1 + locRect.height;
  1192. // Don't update Z.
  1193. var locQuad = this._quad;
  1194. locQuad.bl.vertices = {x:x1, y:y1, z:0};
  1195. locQuad.br.vertices = {x:x2, y:y1, z:0};
  1196. locQuad.tl.vertices = {x:x1, y:y2, z:0};
  1197. locQuad.tr.vertices = {x:x2, y:y2, z:0};
  1198. this._quadDirty = true;
  1199. }
  1200. },
  1201. _setTextureRectForCanvas: function (rect, rotated, untrimmedSize) {
  1202. this._rectRotated = rotated || false;
  1203. untrimmedSize = untrimmedSize || rect._size;
  1204. this.setContentSize(untrimmedSize);
  1205. this.setVertexRect(rect);
  1206. var locTextureRect = this._textureRect_Canvas, scaleFactor = cc.CONTENT_SCALE_FACTOR();
  1207. locTextureRect.x = 0 | (rect.x * scaleFactor);
  1208. locTextureRect.y = 0 | (rect.y * scaleFactor);
  1209. locTextureRect.width = 0 | (rect.width * scaleFactor);
  1210. locTextureRect.height = 0 | (rect.height * scaleFactor);
  1211. locTextureRect.validRect = !(locTextureRect.width === 0 || locTextureRect.height === 0 || locTextureRect.x < 0 || locTextureRect.y < 0);
  1212. var relativeOffset = this._unflippedOffsetPositionFromCenter;
  1213. if (this._flippedX)
  1214. relativeOffset.x = -relativeOffset.x;
  1215. if (this._flippedY)
  1216. relativeOffset.y = -relativeOffset.y;
  1217. this._offsetPosition.x = relativeOffset.x + (this._contentSize.width - this._rect.width) / 2;
  1218. this._offsetPosition.y = relativeOffset.y + (this._contentSize.height - this._rect.height) / 2;
  1219. // rendering using batch node
  1220. if (this._batchNode) {
  1221. // update dirty_, don't update recursiveDirty_
  1222. //this.setDirty(true);
  1223. this._dirty = true;
  1224. }
  1225. },
  1226. // BatchNode methods
  1227. /**
  1228. * updates the quad according the the rotation, position, scale values.
  1229. */
  1230. updateTransform: null,
  1231. _updateTransformForWebGL: function () {
  1232. //cc.Assert(this._batchNode, "updateTransform is only valid when cc.Sprite is being rendered using an cc.SpriteBatchNode");
  1233. // recaculate matrix only if it is dirty
  1234. if (this.isDirty()) {
  1235. var locQuad = this._quad, locParent = this._parent;
  1236. // If it is not visible, or one of its ancestors is not visible, then do nothing:
  1237. if (!this._visible || ( locParent && locParent != this._batchNode && locParent._shouldBeHidden)) {
  1238. locQuad.br.vertices = {x: 0, y: 0, z: 0};
  1239. locQuad.tl.vertices = {x: 0, y: 0, z: 0};
  1240. locQuad.tr.vertices = {x: 0, y: 0, z: 0};
  1241. locQuad.bl.vertices = {x: 0, y: 0, z: 0};
  1242. this._shouldBeHidden = true;
  1243. } else {
  1244. this._shouldBeHidden = false;
  1245. if (!locParent || locParent == this._batchNode) {
  1246. this._transformToBatch = this.nodeToParentTransform();
  1247. } else {
  1248. //cc.Assert(this._parent instanceof cc.Sprite, "Logic error in CCSprite. Parent must be a CCSprite");
  1249. this._transformToBatch = cc.AffineTransformConcat(this.nodeToParentTransform(), locParent._transformToBatch);
  1250. }
  1251. //
  1252. // calculate the Quad based on the Affine Matrix
  1253. //
  1254. var locTransformToBatch = this._transformToBatch;
  1255. var size = this._rect._size;
  1256. var x1 = this._offsetPosition.x;
  1257. var y1 = this._offsetPosition.y;
  1258. var x2 = x1 + size.width;
  1259. var y2 = y1 + size.height;
  1260. var x = locTransformToBatch.tx;
  1261. var y = locTransformToBatch.ty;
  1262. var cr = locTransformToBatch.a;
  1263. var sr = locTransformToBatch.b;
  1264. var cr2 = locTransformToBatch.d;
  1265. var sr2 = -locTransformToBatch.c;
  1266. var ax = x1 * cr - y1 * sr2 + x;
  1267. var ay = x1 * sr + y1 * cr2 + y;
  1268. var bx = x2 * cr - y1 * sr2 + x;
  1269. var by = x2 * sr + y1 * cr2 + y;
  1270. var cx = x2 * cr - y2 * sr2 + x;
  1271. var cy = x2 * sr + y2 * cr2 + y;
  1272. var dx = x1 * cr - y2 * sr2 + x;
  1273. var dy = x1 * sr + y2 * cr2 + y;
  1274. var locVertexZ = this._vertexZ;
  1275. locQuad.bl.vertices = {x: cc.RENDER_IN_SUBPIXEL(ax), y: cc.RENDER_IN_SUBPIXEL(ay), z: locVertexZ};
  1276. locQuad.br.vertices = {x: cc.RENDER_IN_SUBPIXEL(bx), y: cc.RENDER_IN_SUBPIXEL(by), z: locVertexZ};
  1277. locQuad.tl.vertices = {x: cc.RENDER_IN_SUBPIXEL(dx), y: cc.RENDER_IN_SUBPIXEL(dy), z: locVertexZ};
  1278. locQuad.tr.vertices = {x: cc.RENDER_IN_SUBPIXEL(cx), y: cc.RENDER_IN_SUBPIXEL(cy), z: locVertexZ};
  1279. }
  1280. this._textureAtlas.updateQuad(locQuad, this._atlasIndex);
  1281. this._recursiveDirty = false;
  1282. this.setDirty(false);
  1283. }
  1284. // recursively iterate over children
  1285. if (this._hasChildren)
  1286. this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.updateTransform);
  1287. if (cc.SPRITE_DEBUG_DRAW) {
  1288. // draw bounding box
  1289. var vertices = [
  1290. cc.p(this._quad.bl.vertices.x, this._quad.bl.vertices.y),
  1291. cc.p(this._quad.br.vertices.x, this._quad.br.vertices.y),
  1292. cc.p(this._quad.tr.vertices.x, this._quad.tr.vertices.y),
  1293. cc.p(this._quad.tl.vertices.x, this._quad.tl.vertices.y)
  1294. ];
  1295. cc.drawingUtil.drawPoly(vertices, 4, true);
  1296. }
  1297. },
  1298. _updateTransformForCanvas: function () {
  1299. //cc.Assert(this._batchNode, "updateTransform is only valid when cc.Sprite is being rendered using an cc.SpriteBatchNode");
  1300. // recaculate matrix only if it is dirty
  1301. if (this._dirty) {
  1302. // If it is not visible, or one of its ancestors is not visible, then do nothing:
  1303. var locParent = this._parent;
  1304. if (!this._visible || ( locParent && locParent != this._batchNode && locParent._shouldBeHidden)) {
  1305. this._shouldBeHidden = true;
  1306. } else {
  1307. this._shouldBeHidden = false;
  1308. if (!locParent || locParent == this._batchNode) {
  1309. this._transformToBatch = this.nodeToParentTransform();
  1310. } else {
  1311. //cc.Assert(this._parent instanceof cc.Sprite, "Logic error in CCSprite. Parent must be a CCSprite");
  1312. this._transformToBatch = cc.AffineTransformConcat(this.nodeToParentTransform(), locParent._transformToBatch);
  1313. }
  1314. }
  1315. this._recursiveDirty = false;
  1316. this._dirty = false;
  1317. }
  1318. // recursively iterate over children
  1319. if (this._hasChildren)
  1320. this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.updateTransform);
  1321. },
  1322. /**
  1323. * Add child to sprite (override cc.Node )
  1324. * @param {cc.Sprite} child
  1325. * @param {Number} zOrder child's zOrder
  1326. * @param {String} tag child's tag
  1327. * @override
  1328. */
  1329. addChild: null,
  1330. _addChildForWebGL:function (child, zOrder, tag) {
  1331. if(!child)
  1332. throw "cc.Sprite.addChild(): child should be non-null";
  1333. if (zOrder == null)
  1334. zOrder = child._zOrder;
  1335. if (tag == null)
  1336. tag = child._tag;
  1337. if (this._batchNode) {
  1338. if(!(child instanceof cc.Sprite)){
  1339. cc.log("cc.Sprite.addChild(): cc.Sprite only supports cc.Sprites as children when using cc.SpriteBatchNode");
  1340. return;
  1341. }
  1342. if(child.getTexture()._webTextureObj !== this._textureAtlas.getTexture()._webTextureObj)
  1343. cc.log("cc.Sprite.addChild(): cc.Sprite only supports a sprite using same texture as children when using cc.SpriteBatchNode");
  1344. //put it in descendants array of batch node
  1345. this._batchNode.appendChild(child);
  1346. if (!this._reorderChildDirty)
  1347. this._setReorderChildDirtyRecursively();
  1348. }
  1349. //cc.Node already sets isReorderChildDirty_ so this needs to be after batchNode check
  1350. cc.NodeRGBA.prototype.addChild.call(this, child, zOrder, tag);
  1351. this._hasChildren = true;
  1352. },
  1353. _addChildForCanvas: function (child, zOrder, tag) {
  1354. if(!child)
  1355. throw "cc.Sprite.addChild(): child should be non-null";
  1356. if (zOrder == null)
  1357. zOrder = child._zOrder;
  1358. if (tag == null)
  1359. tag = child._tag;
  1360. //cc.Node already sets isReorderChildDirty_ so this needs to be after batchNode check
  1361. cc.NodeRGBA.prototype.addChild.call(this, child, zOrder, tag);
  1362. this._hasChildren = true;
  1363. },
  1364. /**
  1365. * Update sprite's color
  1366. */
  1367. updateColor:function () {
  1368. var locDisplayedColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity;
  1369. var color4 = {r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: locDisplayedOpacity};
  1370. // special opacity for premultiplied textures
  1371. if (this._opacityModifyRGB) {
  1372. color4.r *= locDisplayedOpacity / 255.0;
  1373. color4.g *= locDisplayedOpacity / 255.0;
  1374. color4.b *= locDisplayedOpacity / 255.0;
  1375. }
  1376. var locQuad = this._quad;
  1377. locQuad.bl.colors = color4;
  1378. locQuad.br.colors = color4;
  1379. locQuad.tl.colors = color4;
  1380. locQuad.tr.colors = color4;
  1381. // renders using Sprite Manager
  1382. if (this._batchNode) {
  1383. if (this._atlasIndex != cc.SPRITE_INDEX_NOT_INITIALIZED) {
  1384. this._textureAtlas.updateQuad(locQuad, this._atlasIndex)
  1385. } else {
  1386. // no need to set it recursively
  1387. // update dirty_, don't update recursiveDirty_
  1388. //this.setDirty(true);
  1389. this._dirty = true;
  1390. }
  1391. }
  1392. // self render
  1393. // do nothing
  1394. this._quadDirty = true;
  1395. },
  1396. /**
  1397. * opacity setter
  1398. * @param {Number} opacity
  1399. */
  1400. setOpacity:null,
  1401. _setOpacityForWebGL: function (opacity) {
  1402. cc.NodeRGBA.prototype.setOpacity.call(this, opacity);
  1403. this.updateColor();
  1404. },
  1405. _setOpacityForCanvas: function (opacity) {
  1406. cc.NodeRGBA.prototype.setOpacity.call(this, opacity);
  1407. this._setNodeDirtyForCache();
  1408. },
  1409. /**
  1410. * color setter
  1411. * @param {cc.Color3B} color3
  1412. */
  1413. setColor: null,
  1414. _setColorForWebGL: function (color3) {
  1415. cc.NodeRGBA.prototype.setColor.call(this, color3);
  1416. this.updateColor();
  1417. },
  1418. _setColorForCanvas: function (color3) {
  1419. var curColor = this.getColor();
  1420. if ((curColor.r === color3.r) && (curColor.g === color3.g) && (curColor.b === color3.b))
  1421. return;
  1422. cc.NodeRGBA.prototype.setColor.call(this, color3);
  1423. this._changeTextureColor();
  1424. this._setNodeDirtyForCache();
  1425. },
  1426. updateDisplayedColor: null,
  1427. _updateDisplayedColorForWebGL: function (parentColor) {
  1428. cc.NodeRGBA.prototype.updateDisplayedColor.call(this, parentColor);
  1429. this.updateColor();
  1430. },
  1431. _updateDisplayedColorForCanvas: function (parentColor) {
  1432. var oldColor = this.getColor();
  1433. cc.NodeRGBA.prototype.updateDisplayedColor.call(this, parentColor);
  1434. var newColor = this._displayedColor;
  1435. if ((oldColor.r === newColor.r) && (oldColor.g === newColor.g) && (oldColor.b === newColor.b))
  1436. return;
  1437. this._changeTextureColor();
  1438. this._setNodeDirtyForCache();
  1439. },
  1440. // Frames
  1441. /**
  1442. * Sets a new display frame to the cc.Sprite.
  1443. * @param {cc.SpriteFrame} newFrame
  1444. */
  1445. setDisplayFrame: null,
  1446. _setDisplayFrameForWebGL: function (newFrame) {
  1447. this.setNodeDirty();
  1448. var frameOffset = newFrame.getOffset();
  1449. this._unflippedOffsetPositionFromCenter.x = frameOffset.x;
  1450. this._unflippedOffsetPositionFromCenter.y = frameOffset.y;
  1451. var pNewTexture = newFrame.getTexture();
  1452. var locTextureLoaded = newFrame.textureLoaded();
  1453. if (!locTextureLoaded) {
  1454. this._textureLoaded = false;
  1455. newFrame.addLoadedEventListener(function (sender) {
  1456. this._textureLoaded = true;
  1457. var locNewTexture = sender.getTexture();
  1458. if (locNewTexture != this._texture)
  1459. this.setTexture(locNewTexture);
  1460. this.setTextureRect(sender.getRect(), sender.isRotated(), sender.getOriginalSize());
  1461. this._callLoadedEventCallbacks();
  1462. }, this);
  1463. }
  1464. // update texture before updating texture rect
  1465. if (pNewTexture != this._texture)
  1466. this.setTexture(pNewTexture);
  1467. // update rect
  1468. this._rectRotated = newFrame.isRotated();
  1469. this.setTextureRect(newFrame.getRect(), this._rectRotated, newFrame.getOriginalSize());
  1470. },
  1471. _setDisplayFrameForCanvas: function (newFrame) {
  1472. this.setNodeDirty();
  1473. var frameOffset = newFrame.getOffset();
  1474. this._unflippedOffsetPositionFromCenter.x = frameOffset.x;
  1475. this._unflippedOffsetPositionFromCenter.y = frameOffset.y;
  1476. // update rect
  1477. this._rectRotated = newFrame.isRotated();
  1478. var pNewTexture = newFrame.getTexture();
  1479. var locTextureLoaded = newFrame.textureLoaded();
  1480. if (!locTextureLoaded) {
  1481. this._textureLoaded = false;
  1482. newFrame.addLoadedEventListener(function (sender) {
  1483. this._textureLoaded = true;
  1484. var locNewTexture = sender.getTexture();
  1485. if (locNewTexture != this._texture)
  1486. this.setTexture(locNewTexture);
  1487. this.setTextureRect(sender.getRect(), sender.isRotated(), sender.getOriginalSize());
  1488. this._callLoadedEventCallbacks();
  1489. }, this);
  1490. }
  1491. // update texture before updating texture rect
  1492. if (pNewTexture != this._texture)
  1493. this.setTexture(pNewTexture);
  1494. if (this._rectRotated)
  1495. this._originalTexture = pNewTexture;
  1496. this.setTextureRect(newFrame.getRect(), this._rectRotated, newFrame.getOriginalSize());
  1497. this._colorized = false;
  1498. if (locTextureLoaded) {
  1499. var curColor = this.getColor();
  1500. if (curColor.r !== 255 || curColor.g !== 255 || curColor.b !== 255)
  1501. this._changeTextureColor();
  1502. }
  1503. },
  1504. /**
  1505. * Returns whether or not a cc.SpriteFrame is being displayed
  1506. * @param {cc.SpriteFrame} frame
  1507. * @return {Boolean}
  1508. */
  1509. isFrameDisplayed: null,
  1510. _isFrameDisplayedForWebGL: function (frame) {
  1511. return (cc.rectEqualToRect(frame.getRect(), this._rect) && frame.getTexture().getName() == this._texture.getName()
  1512. && cc.pointEqualToPoint(frame.getOffset(), this._unflippedOffsetPositionFromCenter));
  1513. },
  1514. _isFrameDisplayedForCanvas: function (frame) {
  1515. if (frame.getTexture() != this._texture)
  1516. return false;
  1517. return cc.rectEqualToRect(frame.getRect(), this._rect);
  1518. },
  1519. /**
  1520. * Returns the current displayed frame.
  1521. * @return {cc.SpriteFrame}
  1522. */
  1523. displayFrame: function () {
  1524. return cc.SpriteFrame.createWithTexture(this._texture,
  1525. cc.RECT_POINTS_TO_PIXELS(this._rect),
  1526. this._rectRotated,
  1527. cc.POINT_POINTS_TO_PIXELS(this._unflippedOffsetPositionFromCenter),
  1528. cc.SIZE_POINTS_TO_PIXELS(this._contentSize));
  1529. },
  1530. /**
  1531. * Sets the batch node to sprite
  1532. * @param {cc.SpriteBatchNode|null} spriteBatchNode
  1533. * @example
  1534. * var batch = cc.SpriteBatchNode.create("Images/grossini_dance_atlas.png", 15);
  1535. * var sprite = cc.Sprite.createWithTexture(batch.getTexture(), cc.rect(0, 0, 57, 57));
  1536. * batch.addChild(sprite);
  1537. * layer.addChild(batch);
  1538. */
  1539. setBatchNode:null,
  1540. _setBatchNodeForWebGL:function (spriteBatchNode) {
  1541. this._batchNode = spriteBatchNode; // weak reference
  1542. // self render
  1543. if (!this._batchNode) {
  1544. this._atlasIndex = cc.SPRITE_INDEX_NOT_INITIALIZED;
  1545. this.setTextureAtlas(null);
  1546. this._recursiveDirty = false;
  1547. this.setDirty(false);
  1548. var x1 = this._offsetPosition.x;
  1549. var y1 = this._offsetPosition.y;
  1550. var x2 = x1 + this._rect.width;
  1551. var y2 = y1 + this._rect.height;
  1552. var locQuad = this._quad;
  1553. locQuad.bl.vertices = {x:x1, y:y1, z:0};
  1554. locQuad.br.vertices = {x:x2, y:y1, z:0};
  1555. locQuad.tl.vertices = {x:x1, y:y2, z:0};
  1556. locQuad.tr.vertices = {x:x2, y:y2, z:0};
  1557. this._quadDirty = true;
  1558. } else {
  1559. // using batch
  1560. this._transformToBatch = cc.AffineTransformIdentity();
  1561. this.setTextureAtlas(this._batchNode.getTextureAtlas()); // weak ref
  1562. }
  1563. },
  1564. _setBatchNodeForCanvas:function (spriteBatchNode) {
  1565. this._batchNode = spriteBatchNode; // weak reference
  1566. // self render
  1567. if (!this._batchNode) {
  1568. this._atlasIndex = cc.SPRITE_INDEX_NOT_INITIALIZED;
  1569. this.setTextureAtlas(null);
  1570. this._recursiveDirty = false;
  1571. this.setDirty(false);
  1572. } else {
  1573. // using batch
  1574. this._transformToBatch = cc.AffineTransformIdentity();
  1575. this.setTextureAtlas(this._batchNode.getTextureAtlas()); // weak ref
  1576. }
  1577. },
  1578. // CCTextureProtocol
  1579. /**
  1580. * Texture of sprite setter
  1581. * @param {cc.Texture2D} texture
  1582. */
  1583. setTexture: null,
  1584. _setTextureForWebGL: function (texture) {
  1585. // CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteSheet
  1586. if(texture && !(texture instanceof cc.Texture2D))
  1587. throw "cc.Sprite.setTexture(): setTexture expects a CCTexture2D. Invalid argument";
  1588. // If batchnode, then texture id should be the same
  1589. if(this._batchNode && this._batchNode.getTexture() != texture) {
  1590. cc.log("cc.Sprite.setTexture(): Batched sprites should use the same texture as the batchnode");
  1591. return;
  1592. }
  1593. if (texture)
  1594. this.setShaderProgram(cc.ShaderCache.getInstance().programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
  1595. else
  1596. this.setShaderProgram(cc.ShaderCache.getInstance().programForKey(cc.SHADER_POSITION_COLOR));
  1597. if (!this._batchNode && this._texture != texture) {
  1598. this._texture = texture;
  1599. this._updateBlendFunc();
  1600. }
  1601. },
  1602. _setTextureForCanvas: function (texture) {
  1603. // CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteSheet
  1604. if(texture && !(texture instanceof cc.Texture2D))
  1605. throw "cc.Sprite.setTexture(): setTexture expects a CCTexture2D. Invalid argument";
  1606. if (this._texture != texture) {
  1607. if (texture && texture.getHtmlElementObj() instanceof HTMLImageElement) {
  1608. this._originalTexture = texture;
  1609. }
  1610. this._texture = texture;
  1611. }
  1612. },
  1613. // Texture protocol
  1614. _updateBlendFunc:function () {
  1615. if(this._batchNode){
  1616. cc.log("cc.Sprite._updateBlendFunc(): _updateBlendFunc doesn't work when the sprite is rendered using a cc.CCSpriteBatchNode");
  1617. return;
  1618. }
  1619. // it's possible to have an untextured sprite
  1620. if (!this._texture || !this._texture.hasPremultipliedAlpha()) {
  1621. this._blendFunc.src = gl.SRC_ALPHA;
  1622. this._blendFunc.dst = gl.ONE_MINUS_SRC_ALPHA;
  1623. this.setOpacityModifyRGB(false);
  1624. } else {
  1625. this._blendFunc.src = cc.BLEND_SRC;
  1626. this._blendFunc.dst = cc.BLEND_DST;
  1627. this.setOpacityModifyRGB(true);
  1628. }
  1629. },
  1630. _changeTextureColor: function () {
  1631. var locElement, locTexture = this._texture, locRect = this._textureRect_Canvas; //this.getTextureRect();
  1632. if (locTexture && locRect.validRect && this._originalTexture) {
  1633. locElement = locTexture.getHtmlElementObj();
  1634. if (!locElement)
  1635. return;
  1636. var cacheTextureForColor = cc.TextureCache.getInstance().getTextureColors(this._originalTexture.getHtmlElementObj());
  1637. if (cacheTextureForColor) {
  1638. this._colorized = true;
  1639. //generate color texture cache
  1640. if (locElement instanceof HTMLCanvasElement && !this._rectRotated && !this._newTextureWhenChangeColor)
  1641. cc.generateTintImage(locElement, cacheTextureForColor, this._displayedColor, locRect, locElement);
  1642. else {
  1643. locElement = cc.generateTintImage(locElement, cacheTextureForColor, this._displayedColor, locRect);
  1644. locTexture = new cc.Texture2D();
  1645. locTexture.initWithElement(locElement);
  1646. locTexture.handleLoadedTexture();
  1647. this.setTexture(locTexture);
  1648. }
  1649. }
  1650. }
  1651. },
  1652. _setTextureCoords:function (rect) {
  1653. rect = cc.RECT_POINTS_TO_PIXELS(rect);
  1654. var tex = this._batchNode ? this._textureAtlas.getTexture() : this._texture;
  1655. if (!tex)
  1656. return;
  1657. var atlasWidth = tex.getPixelsWide();
  1658. var atlasHeight = tex.getPixelsHigh();
  1659. var left, right, top, bottom, tempSwap, locQuad = this._quad;
  1660. if (this._rectRotated) {
  1661. if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
  1662. left = (2 * rect.x + 1) / (2 * atlasWidth);
  1663. right = left + (rect.height * 2 - 2) / (2 * atlasWidth);
  1664. top = (2 * rect.y + 1) / (2 * atlasHeight);
  1665. bottom = top + (rect.width * 2 - 2) / (2 * atlasHeight);
  1666. } else {
  1667. left = rect.x / atlasWidth;
  1668. right = (rect.x + rect.height) / atlasWidth;
  1669. top = rect.y / atlasHeight;
  1670. bottom = (rect.y + rect.width) / atlasHeight;
  1671. }// CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
  1672. if (this._flippedX) {
  1673. tempSwap = top;
  1674. top = bottom;
  1675. bottom = tempSwap;
  1676. }
  1677. if (this._flippedY) {
  1678. tempSwap = left;
  1679. left = right;
  1680. right = tempSwap;
  1681. }
  1682. locQuad.bl.texCoords.u = left;
  1683. locQuad.bl.texCoords.v = top;
  1684. locQuad.br.texCoords.u = left;
  1685. locQuad.br.texCoords.v = bottom;
  1686. locQuad.tl.texCoords.u = right;
  1687. locQuad.tl.texCoords.v = top;
  1688. locQuad.tr.texCoords.u = right;
  1689. locQuad.tr.texCoords.v = bottom;
  1690. } else {
  1691. if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
  1692. left = (2 * rect.x + 1) / (2 * atlasWidth);
  1693. right = left + (rect.width * 2 - 2) / (2 * atlasWidth);
  1694. top = (2 * rect.y + 1) / (2 * atlasHeight);
  1695. bottom = top + (rect.height * 2 - 2) / (2 * atlasHeight);
  1696. } else {
  1697. left = rect.x / atlasWidth;
  1698. right = (rect.x + rect.width) / atlasWidth;
  1699. top = rect.y / atlasHeight;
  1700. bottom = (rect.y + rect.height) / atlasHeight;
  1701. } // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
  1702. if (this._flippedX) {
  1703. tempSwap = left;
  1704. left = right;
  1705. right = tempSwap;
  1706. }
  1707. if (this._flippedY) {
  1708. tempSwap = top;
  1709. top = bottom;
  1710. bottom = tempSwap;
  1711. }
  1712. locQuad.bl.texCoords.u = left;
  1713. locQuad.bl.texCoords.v = bottom;
  1714. locQuad.br.texCoords.u = right;
  1715. locQuad.br.texCoords.v = bottom;
  1716. locQuad.tl.texCoords.u = left;
  1717. locQuad.tl.texCoords.v = top;
  1718. locQuad.tr.texCoords.u = right;
  1719. locQuad.tr.texCoords.v = top;
  1720. }
  1721. this._quadDirty = true;
  1722. },
  1723. /**
  1724. * draw sprite to canvas
  1725. */
  1726. draw: null,
  1727. _drawForWebGL: function () {
  1728. if (!this._textureLoaded)
  1729. return;
  1730. var gl = cc.renderContext, locTexture = this._texture;
  1731. //cc.Assert(!this._batchNode, "If cc.Sprite is being rendered by cc.SpriteBatchNode, cc.Sprite#draw SHOULD NOT be called");
  1732. if (locTexture) {
  1733. if (locTexture._isLoaded) {
  1734. this._shaderProgram.use();
  1735. this._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
  1736. cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst);
  1737. //optimize performance for javascript
  1738. cc.glBindTexture2DN(0, locTexture); // = cc.glBindTexture2D(locTexture);
  1739. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
  1740. gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
  1741. if (this._quadDirty) {
  1742. gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.DYNAMIC_DRAW);
  1743. this._quadDirty = false;
  1744. }
  1745. gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 24, 0); //cc.VERTEX_ATTRIB_POSITION
  1746. gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 24, 12); //cc.VERTEX_ATTRIB_COLOR
  1747. gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 24, 16); //cc.VERTEX_ATTRIB_TEX_COORDS
  1748. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  1749. }
  1750. } else {
  1751. this._shaderProgram.use();
  1752. this._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
  1753. cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst);
  1754. cc.glBindTexture2D(null);
  1755. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR);
  1756. gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
  1757. if (this._quadDirty) {
  1758. cc.renderContext.bufferData(cc.renderContext.ARRAY_BUFFER, this._quad.arrayBuffer, cc.renderContext.STATIC_DRAW);
  1759. this._quadDirty = false;
  1760. }
  1761. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0);
  1762. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12);
  1763. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  1764. }
  1765. cc.g_NumberOfDraws++;
  1766. if (cc.SPRITE_DEBUG_DRAW === 0)
  1767. return;
  1768. if (cc.SPRITE_DEBUG_DRAW === 1) {
  1769. // draw bounding box
  1770. var locQuad = this._quad;
  1771. var verticesG1 = [
  1772. cc.p(locQuad.tl.vertices.x, locQuad.tl.vertices.y),
  1773. cc.p(locQuad.bl.vertices.x, locQuad.bl.vertices.y),
  1774. cc.p(locQuad.br.vertices.x, locQuad.br.vertices.y),
  1775. cc.p(locQuad.tr.vertices.x, locQuad.tr.vertices.y)
  1776. ];
  1777. cc.drawingUtil.drawPoly(verticesG1, 4, true);
  1778. } else if (cc.SPRITE_DEBUG_DRAW === 2) {
  1779. // draw texture box
  1780. var drawSizeG2 = this.getTextureRect()._size;
  1781. var offsetPixG2 = this.getOffsetPosition();
  1782. var verticesG2 = [cc.p(offsetPixG2.x, offsetPixG2.y), cc.p(offsetPixG2.x + drawSizeG2.width, offsetPixG2.y),
  1783. cc.p(offsetPixG2.x + drawSizeG2.width, offsetPixG2.y + drawSizeG2.height), cc.p(offsetPixG2.x, offsetPixG2.y + drawSizeG2.height)];
  1784. cc.drawingUtil.drawPoly(verticesG2, 4, true);
  1785. } // CC_SPRITE_DEBUG_DRAW
  1786. },
  1787. _drawForCanvas: function (ctx) {
  1788. if (!this._textureLoaded)
  1789. return;
  1790. var context = ctx || cc.renderContext;
  1791. if (this._isLighterMode)
  1792. context.globalCompositeOperation = 'lighter';
  1793. var locEGL_ScaleX = cc.EGLView.getInstance().getScaleX(), locEGL_ScaleY = cc.EGLView.getInstance().getScaleY();
  1794. context.globalAlpha = this._displayedOpacity / 255;
  1795. var locRect = this._rect, locContentSize = this._contentSize, locOffsetPosition = this._offsetPosition, locDrawSizeCanvas = this._drawSize_Canvas;
  1796. var flipXOffset = 0 | (locOffsetPosition.x), flipYOffset = -locOffsetPosition.y - locRect.height, locTextureCoord = this._textureRect_Canvas;
  1797. locDrawSizeCanvas.width = locRect.width * locEGL_ScaleX;
  1798. locDrawSizeCanvas.height = locRect.height * locEGL_ScaleY;
  1799. if (this._flippedX || this._flippedY) {
  1800. context.save();
  1801. if (this._flippedX) {
  1802. flipXOffset = -locOffsetPosition.x - locRect.width;
  1803. context.scale(-1, 1);
  1804. }
  1805. if (this._flippedY) {
  1806. flipYOffset = locOffsetPosition.y;
  1807. context.scale(1, -1);
  1808. }
  1809. }
  1810. flipXOffset *= locEGL_ScaleX;
  1811. flipYOffset *= locEGL_ScaleY;
  1812. if (this._texture && locTextureCoord.validRect) {
  1813. var image = this._texture.getHtmlElementObj();
  1814. if (this._colorized) {
  1815. context.drawImage(image,
  1816. 0, 0, locTextureCoord.width, locTextureCoord.height,
  1817. flipXOffset, flipYOffset, locDrawSizeCanvas.width, locDrawSizeCanvas.height);
  1818. } else {
  1819. context.drawImage(image,
  1820. locTextureCoord.x, locTextureCoord.y, locTextureCoord.width, locTextureCoord.height,
  1821. flipXOffset, flipYOffset, locDrawSizeCanvas.width , locDrawSizeCanvas.height);
  1822. }
  1823. } else if (locContentSize.width !== 0) {
  1824. var curColor = this.getColor();
  1825. context.fillStyle = "rgba(" + curColor.r + "," + curColor.g + "," + curColor.b + ",1)";
  1826. context.fillRect(flipXOffset, flipYOffset, locContentSize.width * locEGL_ScaleX, locContentSize.height * locEGL_ScaleY);
  1827. }
  1828. if (cc.SPRITE_DEBUG_DRAW === 1) {
  1829. // draw bounding box
  1830. context.strokeStyle = "rgba(0,255,0,1)";
  1831. flipXOffset /= locEGL_ScaleX;
  1832. flipYOffset /= locEGL_ScaleY;
  1833. flipYOffset = -flipYOffset;
  1834. var vertices1 = [cc.p(flipXOffset, flipYOffset),
  1835. cc.p(flipXOffset + locRect.width, flipYOffset),
  1836. cc.p(flipXOffset + locRect.width, flipYOffset - locRect.height),
  1837. cc.p(flipXOffset, flipYOffset - locRect.height)];
  1838. cc.drawingUtil.drawPoly(vertices1, 4, true);
  1839. } else if (cc.SPRITE_DEBUG_DRAW === 2) {
  1840. // draw texture box
  1841. context.strokeStyle = "rgba(0,255,0,1)";
  1842. var drawSize = this._rect._size;
  1843. flipYOffset = -flipYOffset;
  1844. var vertices2 = [cc.p(flipXOffset, flipYOffset), cc.p(flipXOffset + drawSize.width, flipYOffset),
  1845. cc.p(flipXOffset + drawSize.width, flipYOffset - drawSize.height), cc.p(flipXOffset, flipYOffset - drawSize.height)];
  1846. cc.drawingUtil.drawPoly(vertices2, 4, true);
  1847. }
  1848. if (this._flippedX || this._flippedY)
  1849. context.restore();
  1850. cc.g_NumberOfDraws++;
  1851. }
  1852. });
  1853. if(cc.Browser.supportWebGL){
  1854. cc.Sprite.prototype._spriteFrameLoadedCallback = cc.Sprite.prototype._spriteFrameLoadedCallbackForWebGL;
  1855. cc.Sprite.prototype.setOpacityModifyRGB = cc.Sprite.prototype._setOpacityModifyRGBForWebGL;
  1856. cc.Sprite.prototype.updateDisplayedOpacity = cc.Sprite.prototype._updateDisplayedOpacityForWebGL;
  1857. cc.Sprite.prototype.ctor = cc.Sprite.prototype._ctorForWebGL;
  1858. cc.Sprite.prototype.setBlendFunc = cc.Sprite.prototype._setBlendFuncForWebGL;
  1859. cc.Sprite.prototype.init = cc.Sprite.prototype._initForWebGL;
  1860. cc.Sprite.prototype.initWithTexture = cc.Sprite.prototype._initWithTextureForWebGL;
  1861. cc.Sprite.prototype._textureLoadedCallback = cc.Sprite.prototype._textureLoadedCallbackForWebGL;
  1862. cc.Sprite.prototype.setTextureRect = cc.Sprite.prototype._setTextureRectForWebGL;
  1863. cc.Sprite.prototype.updateTransform = cc.Sprite.prototype._updateTransformForWebGL;
  1864. cc.Sprite.prototype.addChild = cc.Sprite.prototype._addChildForWebGL;
  1865. cc.Sprite.prototype.setOpacity = cc.Sprite.prototype._setOpacityForWebGL;
  1866. cc.Sprite.prototype.setColor = cc.Sprite.prototype._setColorForWebGL;
  1867. cc.Sprite.prototype.updateDisplayedColor = cc.Sprite.prototype._updateDisplayedColorForWebGL;
  1868. cc.Sprite.prototype.setDisplayFrame = cc.Sprite.prototype._setDisplayFrameForWebGL;
  1869. cc.Sprite.prototype.isFrameDisplayed = cc.Sprite.prototype._isFrameDisplayedForWebGL;
  1870. cc.Sprite.prototype.setBatchNode = cc.Sprite.prototype._setBatchNodeForWebGL;
  1871. cc.Sprite.prototype.setTexture = cc.Sprite.prototype._setTextureForWebGL;
  1872. cc.Sprite.prototype.draw = cc.Sprite.prototype._drawForWebGL;
  1873. }else{
  1874. cc.Sprite.prototype._spriteFrameLoadedCallback = cc.Sprite.prototype._spriteFrameLoadedCallbackForCanvas;
  1875. cc.Sprite.prototype.setOpacityModifyRGB = cc.Sprite.prototype._setOpacityModifyRGBForCanvas;
  1876. cc.Sprite.prototype.updateDisplayedOpacity = cc.Sprite.prototype._updateDisplayedOpacityForCanvas;
  1877. cc.Sprite.prototype.ctor = cc.Sprite.prototype._ctorForCanvas;
  1878. cc.Sprite.prototype.setBlendFunc = cc.Sprite.prototype._setBlendFuncForCanvas;
  1879. cc.Sprite.prototype.init = cc.Sprite.prototype._initForCanvas;
  1880. cc.Sprite.prototype.initWithTexture = cc.Sprite.prototype._initWithTextureForCanvas;
  1881. cc.Sprite.prototype._textureLoadedCallback = cc.Sprite.prototype._textureLoadedCallbackForCanvas;
  1882. cc.Sprite.prototype.setTextureRect = cc.Sprite.prototype._setTextureRectForCanvas;
  1883. cc.Sprite.prototype.updateTransform = cc.Sprite.prototype._updateTransformForCanvas;
  1884. cc.Sprite.prototype.addChild = cc.Sprite.prototype._addChildForCanvas;
  1885. cc.Sprite.prototype.setOpacity = cc.Sprite.prototype._setOpacityForCanvas;
  1886. cc.Sprite.prototype.setColor = cc.Sprite.prototype._setColorForCanvas;
  1887. cc.Sprite.prototype.updateDisplayedColor = cc.Sprite.prototype._updateDisplayedColorForCanvas;
  1888. cc.Sprite.prototype.setDisplayFrame = cc.Sprite.prototype._setDisplayFrameForCanvas;
  1889. cc.Sprite.prototype.isFrameDisplayed = cc.Sprite.prototype._isFrameDisplayedForCanvas;
  1890. cc.Sprite.prototype.setBatchNode = cc.Sprite.prototype._setBatchNodeForCanvas;
  1891. cc.Sprite.prototype.setTexture = cc.Sprite.prototype._setTextureForCanvas;
  1892. cc.Sprite.prototype.draw = cc.Sprite.prototype._drawForCanvas;
  1893. }
  1894. /**
  1895. * <p>
  1896. * Creates a sprite with an exsiting texture contained in a CCTexture2D object <br/>
  1897. * After creation, the rect will be the size of the texture, and the offset will be (0,0).
  1898. * </p>
  1899. * @constructs
  1900. * @param {cc.Texture2D} texture A pointer to an existing CCTexture2D object. You can use a CCTexture2D object for many sprites.
  1901. * @param {cc.Rect} rect Only the contents inside the rect of this texture will be applied for this sprite.
  1902. * @return {cc.Sprite} A valid sprite object
  1903. * @example
  1904. * //get an image
  1905. * var img = cc.TextureCache.getInstance().addImage("HelloHTML5World.png");
  1906. *
  1907. * //create a sprite with texture
  1908. * var sprite1 = cc.Sprite.createWithTexture(img);
  1909. *
  1910. * //create a sprite with texture and rect
  1911. * var sprite2 = cc.Sprite.createWithTexture(img, cc.rect(0,0,480,320));
  1912. *
  1913. */
  1914. cc.Sprite.createWithTexture = function (texture, rect) {
  1915. var argnum = arguments.length;
  1916. var sprite = new cc.Sprite();
  1917. switch (argnum) {
  1918. case 1:
  1919. /** Creates an sprite with a texture.
  1920. The rect used will be the size of the texture.
  1921. The offset will be (0,0).
  1922. */
  1923. if (sprite && sprite.initWithTexture(texture))
  1924. return sprite;
  1925. return null;
  1926. break;
  1927. case 2:
  1928. /** Creates an sprite with a texture and a rect.
  1929. The offset will be (0,0).
  1930. */
  1931. if (sprite && sprite.initWithTexture(texture, rect))
  1932. return sprite;
  1933. return null;
  1934. break;
  1935. default:
  1936. throw "Sprite.createWithTexture(): Argument must be non-nil ";
  1937. break;
  1938. }
  1939. };
  1940. /**
  1941. * Create a sprite with filename and rect
  1942. * @constructs
  1943. * @param {String} fileName The string which indicates a path to image file, e.g., "scene1/monster.png".
  1944. * @param {cc.Rect} rect Only the contents inside rect of pszFileName's texture will be applied for this sprite.
  1945. * @return {cc.Sprite} A valid sprite object
  1946. * @example
  1947. * //create a sprite with filename
  1948. * var sprite1 = cc.Sprite.create("HelloHTML5World.png");
  1949. *
  1950. * //create a sprite with filename and rect
  1951. * var sprite2 = cc.Sprite.create("HelloHTML5World.png",cc.rect(0,0,480,320));
  1952. */
  1953. cc.Sprite.create = function (fileName, rect) {
  1954. var argnum = arguments.length;
  1955. var sprite = new cc.Sprite();
  1956. if (argnum === 0) {
  1957. if (sprite.init())
  1958. return sprite;
  1959. } else {
  1960. /** Creates an sprite with an image filename.
  1961. If the rect equal undefined, the rect used will be the size of the image.
  1962. The offset will be (0,0).
  1963. */
  1964. if (sprite && sprite.init(fileName, rect))
  1965. return sprite;
  1966. }
  1967. return null;
  1968. };
  1969. /**
  1970. * <p>
  1971. * Creates a sprite with a sprite frame. <br/>
  1972. * <br/>
  1973. * A CCSpriteFrame will be fetched from the CCSpriteFrameCache by pszSpriteFrameName param. <br/>
  1974. * If the CCSpriteFrame doesn't exist it will raise an exception.
  1975. * </p>
  1976. * @param {String} spriteFrameName A sprite frame which involves a texture and a rect
  1977. * @return {cc.Sprite} A valid sprite object
  1978. * @example
  1979. *
  1980. * //create a sprite with a sprite frame
  1981. * var sprite = cc.Sprite.createWithSpriteFrameName('grossini_dance_01.png');
  1982. */
  1983. cc.Sprite.createWithSpriteFrameName = function (spriteFrameName) {
  1984. var spriteFrame = null;
  1985. if (typeof(spriteFrameName) == 'string') {
  1986. spriteFrame = cc.SpriteFrameCache.getInstance().getSpriteFrame(spriteFrameName);
  1987. if (!spriteFrame) {
  1988. cc.log("Invalid spriteFrameName: " + spriteFrameName);
  1989. return null;
  1990. }
  1991. } else {
  1992. cc.log("Invalid argument. Expecting string.");
  1993. return null;
  1994. }
  1995. var sprite = new cc.Sprite();
  1996. if (sprite && sprite.initWithSpriteFrame(spriteFrame)) {
  1997. return sprite;
  1998. }
  1999. return null;
  2000. };
  2001. /**
  2002. * <p>
  2003. * Creates a sprite with a sprite frame. <br/>
  2004. * <br/>
  2005. * A CCSpriteFrame will be fetched from the CCSpriteFrameCache by pszSpriteFrameName param. <br/>
  2006. * If the CCSpriteFrame doesn't exist it will raise an exception.
  2007. * </p>
  2008. * @param {cc.SpriteFrame} spriteFrame A sprite frame which involves a texture and a rect
  2009. * @return {cc.Sprite} A valid sprite object
  2010. * @example
  2011. * //get a sprite frame
  2012. * var spriteFrame = cc.SpriteFrameCache.getInstance().getSpriteFrame("grossini_dance_01.png");
  2013. *
  2014. * //create a sprite with a sprite frame
  2015. * var sprite = cc.Sprite.createWithSpriteFrame(spriteFrame);
  2016. */
  2017. cc.Sprite.createWithSpriteFrame = function (spriteFrame) {
  2018. var sprite = new cc.Sprite();
  2019. if (sprite && sprite.initWithSpriteFrame(spriteFrame)) {
  2020. return sprite;
  2021. }
  2022. return null;
  2023. };