CCLayer.js 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  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. /** Layer will receive all the touches at once The onTouchesXXX API will be called
  23. */
  24. cc.TOUCH_ALL_AT_ONCE = 0;
  25. /** Layer will receive only one touch at the time. The onTouchXXX API will be called */
  26. cc.TOUCH_ONE_BY_ONE = 1;
  27. /** cc.Layer is a subclass of cc.Node that implements the TouchEventsDelegate protocol.<br/>
  28. * All features from cc.Node are valid, plus the following new features:<br/>
  29. * It can receive iPhone Touches<br/>
  30. * It can receive Accelerometer input
  31. * @class
  32. * @extends cc.Node
  33. */
  34. cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
  35. _isTouchEnabled:false,
  36. _isAccelerometerEnabled:false,
  37. _isKeyboardEnabled:false,
  38. _touchPriority:0,
  39. _touchMode:cc.TOUCH_ALL_AT_ONCE,
  40. _isMouseEnabled:false,
  41. _mousePriority:0,
  42. // This is only useful in mode TOUCH_ONE_BY_ONE
  43. _swallowTouch:true,
  44. ctor: function () {
  45. cc.Node.prototype.ctor.call(this);
  46. this._isTouchEnabled = false;
  47. this._isAccelerometerEnabled = false;
  48. this._isKeyboardEnabled = false;
  49. this._touchPriority = 0;
  50. this._touchMode = cc.TOUCH_ALL_AT_ONCE;
  51. this._isMouseEnabled = false;
  52. this._mousePriority = 0;
  53. },
  54. _initLayer:function () {
  55. this.setAnchorPoint(0.5, 0.5);
  56. this._ignoreAnchorPointForPosition = true;
  57. var director = cc.Director.getInstance();
  58. this.setContentSize(director.getWinSize());
  59. },
  60. /**
  61. *
  62. * @return {Boolean}
  63. */
  64. init:function () {
  65. cc.Node.prototype.init.call(this);
  66. this._initLayer();
  67. return true;
  68. },
  69. /**
  70. * use for jsb
  71. * @param enable
  72. */
  73. setKeypadEnabled:function(enable){
  74. },
  75. /**
  76. * If isTouchEnabled, this method is called onEnter.
  77. */
  78. registerWithTouchDispatcher:function () {
  79. if (this._touchMode === cc.TOUCH_ALL_AT_ONCE)
  80. cc.registerStandardDelegate(this,this._touchPriority);
  81. else
  82. cc.registerTargetedDelegate(this._touchPriority, this._swallowTouch, this);
  83. },
  84. isMouseEnabled:function () {
  85. return this._isMouseEnabled;
  86. },
  87. setMouseEnabled:function (enabled) {
  88. if(!cc.MouseDispatcher)
  89. throw "cc.MouseDispatcher is undefined, maybe it has been removed from js loading list.";
  90. if (this._isMouseEnabled != enabled) {
  91. this._isMouseEnabled = enabled;
  92. if (this._running) {
  93. if (enabled)
  94. cc.Director.getInstance().getMouseDispatcher().addMouseDelegate(this, this._mousePriority);
  95. else
  96. cc.Director.getInstance().getMouseDispatcher().removeMouseDelegate(this);
  97. }
  98. }
  99. },
  100. setMousePriority:function (priority) {
  101. if(!cc.MouseDispatcher)
  102. throw "cc.MouseDispatcher is undefined, maybe it has been removed from js loading list.";
  103. if (this._mousePriority !== priority) {
  104. this._mousePriority = priority;
  105. // Update touch priority with handler
  106. if (this._isMouseEnabled) {
  107. this.setMouseEnabled(false);
  108. this.setMouseEnabled(true);
  109. }
  110. }
  111. },
  112. getMousePriority:function () {
  113. return this._mousePriority;
  114. },
  115. /**
  116. * whether or not it will receive Touch events.<br/>
  117. * You can enable / disable touch events with this property.<br/>
  118. * Only the touches of this node will be affected. This "method" is not propagated to it's children.<br/>
  119. * @return {Boolean}
  120. */
  121. isTouchEnabled:function () {
  122. return this._isTouchEnabled;
  123. },
  124. /**
  125. * Enable touch events
  126. * @param {Boolean} enabled
  127. * @param {Boolean} [swallow=true] if the event listener will swallow touch after been triggered
  128. */
  129. setTouchEnabled:function (enabled, swallow) {
  130. if (this._isTouchEnabled !== enabled) {
  131. this._isTouchEnabled = enabled;
  132. this._swallowTouch = (swallow === false ? false : true);
  133. if (this._running) {
  134. if (enabled) {
  135. this.registerWithTouchDispatcher();
  136. } else {
  137. // have problems?
  138. cc.unregisterTouchDelegate(this);
  139. }
  140. }
  141. }
  142. },
  143. /** returns the priority of the touch event handler
  144. * @return {Number}
  145. */
  146. getTouchPriority:function () {
  147. return this._touchPriority;
  148. },
  149. /** Sets the touch event handler priority. Default is 0.
  150. * @param {Number} priority
  151. */
  152. setTouchPriority:function (priority) {
  153. if (this._touchPriority !== priority) {
  154. this._touchPriority = priority;
  155. // Update touch priority with handler
  156. if (this._isTouchEnabled) {
  157. this.setTouchEnabled(false);
  158. this.setTouchEnabled(true);
  159. }
  160. }
  161. },
  162. /** returns the touch mode.
  163. * @return {Number}
  164. */
  165. getTouchMode:function () {
  166. return this._touchMode;
  167. },
  168. /** Sets the touch mode.
  169. * @param {Number} mode
  170. */
  171. setTouchMode:function (mode) {
  172. if (this._touchMode !== mode) {
  173. this._touchMode = mode;
  174. // update the mode with handler
  175. if (this._isTouchEnabled) {
  176. this.setTouchEnabled(false);
  177. this.setTouchEnabled(true);
  178. }
  179. }
  180. },
  181. /**
  182. * whether or not it will receive Accelerometer events<br/>
  183. * You can enable / disable accelerometer events with this property.
  184. * @return {Boolean}
  185. */
  186. isAccelerometerEnabled:function () {
  187. return this._isAccelerometerEnabled;
  188. },
  189. /**
  190. * isAccelerometerEnabled setter
  191. * @param {Boolean} enabled
  192. */
  193. setAccelerometerEnabled:function (enabled) {
  194. if(!cc.Accelerometer)
  195. throw "cc.Accelerometer is undefined, maybe it has been removed from js loading list.";
  196. if (enabled !== this._isAccelerometerEnabled) {
  197. this._isAccelerometerEnabled = enabled;
  198. if (this._running) {
  199. var director = cc.Director.getInstance();
  200. if (enabled)
  201. director.getAccelerometer().setDelegate(this);
  202. else
  203. director.getAccelerometer().setDelegate(null);
  204. }
  205. }
  206. },
  207. /**
  208. * accelerometerInterval setter
  209. * @param {Number} interval
  210. */
  211. setAccelerometerInterval:function (interval) {
  212. if (this._isAccelerometerEnabled && cc.Accelerometer)
  213. cc.Director.getInstance().getAccelerometer().setAccelerometerInterval(interval);
  214. },
  215. onAccelerometer:function (accelerationValue) {
  216. cc.log("onAccelerometer event should be handled.")
  217. },
  218. /**
  219. * whether or not it will receive keyboard events<br/>
  220. * You can enable / disable accelerometer events with this property.<br/>
  221. * it's new in cocos2d-x
  222. * @return {Boolean}
  223. */
  224. isKeyboardEnabled:function () {
  225. return this._isKeyboardEnabled;
  226. },
  227. /**
  228. * Enable Keyboard interaction
  229. * @param {Boolean} enabled
  230. */
  231. setKeyboardEnabled:function (enabled) {
  232. if(!cc.KeyboardDispatcher)
  233. throw "cc.KeyboardDispatcher is undefined, maybe it has been removed from js loading list.";
  234. if (enabled !== this._isKeyboardEnabled) {
  235. this._isKeyboardEnabled = enabled;
  236. if (this._running) {
  237. var director = cc.Director.getInstance();
  238. if (enabled) {
  239. director.getKeyboardDispatcher().addDelegate(this);
  240. } else {
  241. director.getKeyboardDispatcher().removeDelegate(this);
  242. }
  243. }
  244. }
  245. },
  246. /**
  247. * This is run when ever a layer just become visible
  248. */
  249. onEnter:function () {
  250. var director = cc.Director.getInstance();
  251. // register 'parent' nodes first
  252. // since events are propagated in reverse order
  253. if (this._isTouchEnabled)
  254. this.registerWithTouchDispatcher();
  255. // then iterate over all the children
  256. cc.Node.prototype.onEnter.call(this);
  257. // add this layer to concern the Accelerometer Sensor
  258. if (this._isAccelerometerEnabled && cc.Accelerometer)
  259. director.getAccelerometer().setDelegate(this);
  260. // add this layer to concern the kaypad msg
  261. if (this._isKeyboardEnabled && cc.KeyboardDispatcher)
  262. director.getKeyboardDispatcher().addDelegate(this);
  263. if (this._isMouseEnabled && cc.MouseDispatcher)
  264. director.getMouseDispatcher().addMouseDelegate(this, this._mousePriority);
  265. },
  266. /**
  267. * @function
  268. */
  269. onExit:function () {
  270. var director = cc.Director.getInstance();
  271. if (this._isTouchEnabled)
  272. cc.unregisterTouchDelegate(this);
  273. // remove this layer from the delegates who concern Accelerometer Sensor
  274. if (this._isAccelerometerEnabled && cc.Accelerometer)
  275. director.getAccelerometer().setDelegate(null);
  276. // remove this layer from the delegates who concern the kaypad msg
  277. if (this._isKeyboardEnabled && cc.KeyboardDispatcher)
  278. director.getKeyboardDispatcher().removeDelegate(this);
  279. if (this._isMouseEnabled && cc.MouseDispatcher)
  280. director.getMouseDispatcher().removeMouseDelegate(this);
  281. cc.Node.prototype.onExit.call(this);
  282. },
  283. /**
  284. * this is called when ever a layer is a child of a scene that just finished a transition
  285. */
  286. onEnterTransitionDidFinish:function () {
  287. if (this._isAccelerometerEnabled && cc.Accelerometer)
  288. cc.Director.getInstance().getAccelerometer().setDelegate(this);
  289. cc.Node.prototype.onEnterTransitionDidFinish.call(this);
  290. },
  291. // ---------------------CCTouchDelegate interface------------------------------
  292. /**
  293. * default implements are used to call script callback if exist<br/>
  294. * you must override these touch functions if you wish to utilize them
  295. * @param {cc.Touch} touch
  296. * @param {event} event
  297. * @return {Boolean}
  298. */
  299. onTouchBegan:function (touch, event) {
  300. cc.log("onTouchBegan event should be handled.");
  301. return true;
  302. },
  303. /**
  304. * callback when a touch event moved
  305. * @param {cc.Touch} touch
  306. * @param {event} event
  307. */
  308. onTouchMoved:function (touch, event) {
  309. },
  310. /**
  311. * callback when a touch event finished
  312. * @param {cc.Touch} touch
  313. * @param {event} event
  314. */
  315. onTouchEnded:function (touch, event) {
  316. },
  317. /**
  318. * @param {cc.Touch} touch
  319. * @param {event} event
  320. */
  321. onTouchCancelled:function (touch, event) {
  322. },
  323. /**
  324. * Touches is the same as onTouchBegan, except this one can handle multi-touch
  325. * @param {array} touches
  326. * @param {event} event
  327. */
  328. onTouchesBegan:function (touches, event) {
  329. },
  330. /**
  331. * @param {array} touches
  332. * @param {event} event
  333. */
  334. onTouchesMoved:function (touches, event) {
  335. },
  336. /**
  337. * @param {array} touches
  338. * @param {event} event
  339. */
  340. onTouchesEnded:function (touches, event) {
  341. },
  342. /**
  343. * @param {array} touches
  344. * @param event
  345. */
  346. onTouchesCancelled:function (touches, event) {
  347. },
  348. // ---------------------CCMouseEventDelegate interface------------------------------
  349. /**
  350. * <p>called when the "mouseDown" event is received. <br/>
  351. * Return YES to avoid propagating the event to other delegates. </p>
  352. * @param {cc.Mouse} mouse
  353. * @return {Boolean}
  354. */
  355. onMouseDown:function (mouse) {
  356. return false;
  357. },
  358. /**
  359. * <p>called when the "mouseDragged" event is received. <br/>
  360. * Return YES to avoid propagating the event to other delegates.</p>
  361. * @param {cc.Mouse} mouse
  362. * @return {Boolean}
  363. */
  364. onMouseDragged:function (mouse) {
  365. return false;
  366. },
  367. /**
  368. * <p> called when the "mouseMoved" event is received. <br/>
  369. * Return YES to avoid propagating the event to other delegates. </p>
  370. * @param {cc.Mouse} mouse
  371. * @return {Boolean}
  372. */
  373. onMouseMoved:function (mouse) {
  374. return false;
  375. },
  376. /**
  377. * <p> called when the "mouseUp" event is received. <br/>
  378. * Return YES to avoid propagating the event to other delegates. </p>
  379. * @param {cc.Mouse} mouse
  380. * @return {Boolean}
  381. */
  382. onMouseUp:function (mouse) {
  383. return false;
  384. },
  385. //right
  386. /**
  387. * <p> called when the "rightMouseDown" event is received. <br/>
  388. * Return YES to avoid propagating the event to other delegates. </p>
  389. * @param {cc.Mouse} mouse
  390. * @return {Boolean}
  391. */
  392. onRightMouseDown:function (mouse) {
  393. return false;
  394. },
  395. /**
  396. * <p> called when the "rightMouseDragged" event is received. <br/>
  397. * Return YES to avoid propagating the event to other delegates. </p>
  398. * @param {cc.Mouse} mouse
  399. * @return {Boolean}
  400. */
  401. onRightMouseDragged:function (mouse) {
  402. return false;
  403. },
  404. /**
  405. * <p> called when the "rightMouseUp" event is received. <br/>
  406. * Return YES to avoid propagating the event to other delegates. </p>
  407. * @param {cc.Mouse} mouse
  408. * @return {Boolean}
  409. */
  410. onRightMouseUp:function (mouse) {
  411. return false;
  412. },
  413. //other
  414. /**
  415. * <p>called when the "otherMouseDown" event is received. <br/>
  416. * Return YES to avoid propagating the event to other delegates. </p>
  417. * @param {cc.Mouse} mouse
  418. * @return {Boolean}
  419. */
  420. onOtherMouseDown:function (mouse) {
  421. return false;
  422. },
  423. /**
  424. * <p> called when the "otherMouseDragged" event is received. <br/>
  425. * Return YES to avoid propagating the event to other delegates. </p>
  426. * @param {cc.Mouse} mouse
  427. * @return {Boolean}
  428. */
  429. onOtherMouseDragged:function (mouse) {
  430. return false;
  431. },
  432. /**
  433. * <p> called when the "otherMouseUp" event is received. <br/>
  434. * Return YES to avoid propagating the event to other delegates. </p>
  435. * @param {cc.Mouse} mouse
  436. * @return {Boolean}
  437. */
  438. onOtherMouseUp:function (mouse) {
  439. return false;
  440. },
  441. //scroll wheel
  442. /**
  443. * <p> called when the "scrollWheel" event is received. <br/>
  444. * Return YES to avoid propagating the event to other delegates. </p>
  445. * @param {cc.Mouse} mouse
  446. * @return {Boolean}
  447. */
  448. onScrollWheel:function (mouse) {
  449. return false;
  450. },
  451. // enter / exit
  452. /**
  453. * <p> called when the "mouseEntered" event is received. <br/>
  454. * Return YES to avoid propagating the event to other delegates. </p>
  455. * @param {cc.Mouse} mouse
  456. * @return {Boolean}
  457. */
  458. onMouseEntered:function (mouse) {
  459. return false;
  460. },
  461. /**
  462. * <p> called when the "mouseExited" event is received. <br/>
  463. * Return YES to avoid propagating the event to other delegates. </p>
  464. * @param {cc.Mouse} mouse
  465. * @return {Boolean}
  466. */
  467. onMouseExited:function (mouse) {
  468. return false;
  469. },
  470. // ---------------------CCKeyboardDelegate interface------------------------------
  471. /**
  472. * Call back when a key is pressed down
  473. * @param {Number} keyCode
  474. * @example
  475. * // example
  476. * if(keyCode == cc.KEY.w){}
  477. */
  478. onKeyDown:function (keyCode) {
  479. },
  480. /**
  481. * Call back when a key is released
  482. * @param {Number} keyCode
  483. * @example
  484. * // example
  485. * if(keyCode == cc.KEY.w){}
  486. */
  487. onKeyUp:function (keyCode) {
  488. }
  489. });
  490. /**
  491. * creates a layer
  492. * @example
  493. * // Example
  494. * var myLayer = cc.Layer.create();
  495. * //Yes! it's that simple
  496. * @return {cc.Layer|Null}
  497. */
  498. cc.Layer.create = function () {
  499. var ret = new cc.Layer();
  500. if (ret && ret.init())
  501. return ret;
  502. return null;
  503. };
  504. /**
  505. * <p>
  506. * CCLayerRGBA is a subclass of CCLayer that implements the CCRGBAProtocol protocol using a solid color as the background. <br/>
  507. * All features from CCLayer are valid, plus the following new features that propagate into children that conform to the CCRGBAProtocol: <br/>
  508. * - opacity <br/>
  509. * - RGB colors
  510. * </p>
  511. * @class
  512. * @extends cc.Layer
  513. */
  514. cc.LayerRGBA = cc.Layer.extend(/** @lends cc.LayerRGBA# */{
  515. RGBAProtocol:true,
  516. _displayedOpacity: 0,
  517. _realOpacity: 0,
  518. _displayedColor: null,
  519. _realColor: null,
  520. _cascadeOpacityEnabled: false,
  521. _cascadeColorEnabled: false,
  522. ctor: function () {
  523. cc.Layer.prototype.ctor.call(this);
  524. this.RGBAProtocol = true;
  525. this._displayedOpacity = 255;
  526. this._realOpacity = 255;
  527. this._displayedColor = cc.white();
  528. this._realColor = cc.white();
  529. this._cascadeOpacityEnabled = false;
  530. this._cascadeColorEnabled = false;
  531. },
  532. init: function () {
  533. if(cc.Layer.prototype.init.call(this)){
  534. this.setCascadeOpacityEnabled(false);
  535. this.setCascadeColorEnabled(false);
  536. return true;
  537. }
  538. return false;
  539. },
  540. /**
  541. * Get the opacity of Layer
  542. * @returns {number} opacity
  543. */
  544. getOpacity: function () {
  545. return this._realOpacity;
  546. },
  547. /**
  548. * Get the displayed opacity of Layer
  549. * @returns {number} displayed opacity
  550. */
  551. getDisplayedOpacity: function () {
  552. return this._displayedOpacity;
  553. },
  554. /**
  555. * Override synthesized setOpacity to recurse items
  556. * @param {Number} opacity
  557. */
  558. setOpacity: function (opacity) {
  559. this._displayedOpacity = this._realOpacity = opacity;
  560. var parentOpacity = 255, locParent = this._parent;
  561. if (locParent && locParent.RGBAProtocol && locParent.isCascadeOpacityEnabled())
  562. parentOpacity = locParent.getDisplayedOpacity();
  563. this.updateDisplayedOpacity(parentOpacity);
  564. },
  565. /**
  566. * Update displayed opacity of Layer
  567. * @param {Number} parentOpacity
  568. */
  569. updateDisplayedOpacity: function (parentOpacity) {
  570. this._displayedOpacity = 0 | (this._realOpacity * parentOpacity / 255.0);
  571. if (this._cascadeOpacityEnabled) {
  572. var locChildren = this._children;
  573. for (var i = 0; i < locChildren.length; i++) {
  574. var selItem = locChildren[i];
  575. if (selItem && selItem.RGBAProtocol)
  576. selItem.updateDisplayedOpacity(this._displayedOpacity);
  577. }
  578. }
  579. },
  580. /**
  581. * whether or not it will set cascade opacity.
  582. * @returns {boolean}
  583. */
  584. isCascadeOpacityEnabled: function () {
  585. return this._cascadeOpacityEnabled;
  586. },
  587. /**
  588. * Enable or disable cascade opacity
  589. * @param {boolean} cascadeOpacityEnabled
  590. */
  591. setCascadeOpacityEnabled: function (cascadeOpacityEnabled) {
  592. if(this._cascadeOpacityEnabled === cascadeOpacityEnabled)
  593. return;
  594. this._cascadeOpacityEnabled = cascadeOpacityEnabled;
  595. if(cascadeOpacityEnabled)
  596. this._enableCascadeOpacity();
  597. else
  598. this._disableCascadeOpacity();
  599. },
  600. _enableCascadeOpacity:function(){
  601. var parentOpacity = 255, locParent = this._parent;
  602. if (locParent && locParent.RGBAProtocol && locParent.isCascadeOpacityEnabled())
  603. parentOpacity = locParent.getDisplayedOpacity();
  604. this.updateDisplayedOpacity(parentOpacity);
  605. },
  606. _disableCascadeOpacity:function(){
  607. this._displayedOpacity = this._realOpacity;
  608. var selChildren = this._children;
  609. for(var i = 0; i< selChildren.length;i++){
  610. var item = selChildren[i];
  611. if(item && item.RGBAProtocol)
  612. item.updateDisplayedOpacity(255);
  613. }
  614. },
  615. /**
  616. * Get the color of Layer
  617. * @returns {cc.Color3B}
  618. */
  619. getColor: function () {
  620. var locRealColor = this._realColor;
  621. return cc.c3b(locRealColor.r, locRealColor.g, locRealColor.b);
  622. },
  623. /**
  624. * Get the displayed color of Layer
  625. * @returns {cc.Color3B}
  626. */
  627. getDisplayedColor: function () {
  628. var locDisplayedColor = this._displayedColor;
  629. return cc.c3b(locDisplayedColor.r, locDisplayedColor.g, locDisplayedColor.b);
  630. },
  631. /**
  632. * Set the color of Layer
  633. * @param {cc.Color3B} color
  634. */
  635. setColor: function (color) {
  636. var locDisplayed = this._displayedColor, locRealColor = this._realColor;
  637. locDisplayed.r = locRealColor.r = color.r;
  638. locDisplayed.g = locRealColor.g = color.g;
  639. locDisplayed.b = locRealColor.b = color.b;
  640. var parentColor, locParent = this._parent;
  641. if (locParent && locParent.RGBAProtocol && locParent.isCascadeColorEnabled())
  642. parentColor = locParent.getDisplayedColor();
  643. else
  644. parentColor = cc.white();
  645. this.updateDisplayedColor(parentColor);
  646. },
  647. /**
  648. * update the displayed color of Node
  649. * @param {cc.Color3B} parentColor
  650. */
  651. updateDisplayedColor: function (parentColor) {
  652. var locDisplayedColor = this._displayedColor, locRealColor = this._realColor;
  653. locDisplayedColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
  654. locDisplayedColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
  655. locDisplayedColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
  656. if (this._cascadeColorEnabled) {
  657. var locChildren = this._children;
  658. for (var i = 0; i < locChildren.length; i++) {
  659. var selItem = locChildren[i];
  660. if (selItem && selItem.RGBAProtocol)
  661. selItem.updateDisplayedColor(locDisplayedColor);
  662. }
  663. }
  664. },
  665. /**
  666. * whether or not it will set cascade color.
  667. * @returns {boolean}
  668. */
  669. isCascadeColorEnabled: function () {
  670. return this._cascadeColorEnabled;
  671. },
  672. /**
  673. * Enable or disable cascade color
  674. * @param {boolean} cascadeColorEnabled
  675. */
  676. setCascadeColorEnabled: function (cascadeColorEnabled) {
  677. if(this._cascadeColorEnabled === cascadeColorEnabled)
  678. return;
  679. this._cascadeColorEnabled = cascadeColorEnabled;
  680. if(this._cascadeColorEnabled)
  681. this._enableCascadeColor();
  682. else
  683. this._disableCascadeColor();
  684. },
  685. _enableCascadeColor: function(){
  686. var parentColor , locParent = this._parent;
  687. if (locParent && locParent.RGBAProtocol && locParent.isCascadeColorEnabled())
  688. parentColor = locParent.getDisplayedColor();
  689. else
  690. parentColor = cc.white();
  691. this.updateDisplayedColor(parentColor);
  692. },
  693. _disableCascadeColor: function(){
  694. var locDisplayedColor = this._displayedColor, locRealColor = this._realColor;
  695. locDisplayedColor.r = locRealColor.r;
  696. locDisplayedColor.g = locRealColor.g;
  697. locDisplayedColor.b = locRealColor.b;
  698. var selChildren = this._children, whiteColor = cc.white();
  699. for(var i = 0; i< selChildren.length;i++){
  700. var item = selChildren[i];
  701. if(item && item.RGBAProtocol)
  702. item.updateDisplayedColor(whiteColor);
  703. }
  704. },
  705. /**
  706. * add a child to layer
  707. * @overried
  708. * @param {cc.Node} child A child node
  709. * @param {Number} [zOrder=] Z order for drawing priority. Please refer to setZOrder(int)
  710. * @param {Number} [tag=] A integer to identify the node easily. Please refer to setTag(int)
  711. */
  712. addChild:function(child, zOrder, tag){
  713. cc.Node.prototype.addChild.call(this, child, zOrder, tag);
  714. if(this._cascadeColorEnabled)
  715. this._enableCascadeColor();
  716. if(this._cascadeOpacityEnabled)
  717. this._enableCascadeOpacity();
  718. },
  719. setOpacityModifyRGB: function (bValue) {
  720. },
  721. isOpacityModifyRGB: function () {
  722. return false;
  723. }
  724. });
  725. /**
  726. * <p>
  727. * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol. <br/>
  728. * All features from CCLayer are valid, plus the following new features: <br/>
  729. * <ul><li>opacity</li> <br/>
  730. * <li>RGB colors</li></ul> <br/>
  731. * </p>
  732. * @class
  733. * @extends cc.LayerRGBA
  734. */
  735. cc.LayerColor = cc.LayerRGBA.extend(/** @lends cc.LayerColor# */{
  736. _blendFunc:null,
  737. /**
  738. * blendFunc getter
  739. * @return {cc.BlendFunc}
  740. */
  741. getBlendFunc:function () {
  742. return this._blendFunc;
  743. },
  744. /**
  745. * change width and height in Points
  746. * @param {Number} w width
  747. * @param {Number} h height
  748. */
  749. changeWidthAndHeight:function (w, h) {
  750. this.setContentSize(w, h);
  751. },
  752. /**
  753. * change width in Points
  754. * @param {Number} w width
  755. */
  756. changeWidth:function (w) {
  757. this.setContentSize(w, this._contentSize.height);
  758. },
  759. /**
  760. * change height in Points
  761. * @param {Number} h height
  762. */
  763. changeHeight:function (h) {
  764. this.setContentSize(this._contentSize.width, h);
  765. },
  766. /**
  767. * set OpacityModifyRGB of cc.LayerColor
  768. * @param {Boolean} value
  769. */
  770. setOpacityModifyRGB:function (value) {
  771. },
  772. /**
  773. * is OpacityModifyRGB
  774. * @return {Boolean}
  775. */
  776. isOpacityModifyRGB:function () {
  777. return false;
  778. },
  779. setColor:function(color){
  780. cc.LayerRGBA.prototype.setColor.call(this, color);
  781. this._updateColor();
  782. },
  783. setOpacity:function(opacity){
  784. cc.LayerRGBA.prototype.setOpacity.call(this, opacity);
  785. this._updateColor();
  786. },
  787. _isLighterMode:false,
  788. _squareVertices:null,
  789. _squareColors:null,
  790. _verticesFloat32Buffer:null,
  791. _colorsUint8Buffer:null,
  792. _squareVerticesAB:null,
  793. _squareColorsAB:null,
  794. _ctorForCanvas: function () {
  795. cc.LayerRGBA.prototype.ctor.call(this);
  796. this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
  797. },
  798. _ctorForWebGL: function () {
  799. cc.LayerRGBA.prototype.ctor.call(this);
  800. this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
  801. this._squareVerticesAB = new ArrayBuffer(32);
  802. this._squareColorsAB = new ArrayBuffer(64);
  803. var locSquareVerticesAB = this._squareVerticesAB, locSquareColorsAB = this._squareColorsAB;
  804. var locVertex2FLen = cc.Vertex2F.BYTES_PER_ELEMENT, locColor4FLen = cc.Color4F.BYTES_PER_ELEMENT;
  805. this._squareVertices = [new cc.Vertex2F(0, 0, locSquareVerticesAB, 0),
  806. new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen),
  807. new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 2),
  808. new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 3)];
  809. this._squareColors = [new cc.Color4F(0, 0, 0, 1, locSquareColorsAB, 0),
  810. new cc.Color4F(0, 0, 0, 1, locSquareColorsAB, locColor4FLen),
  811. new cc.Color4F(0, 0, 0, 1, locSquareColorsAB, locColor4FLen * 2),
  812. new cc.Color4F(0, 0, 0, 1, locSquareColorsAB, locColor4FLen * 3)];
  813. this._verticesFloat32Buffer = cc.renderContext.createBuffer();
  814. this._colorsUint8Buffer = cc.renderContext.createBuffer();
  815. },
  816. /**
  817. * blendFunc setter
  818. * @param {Number} src
  819. * @param {Number} dst
  820. */
  821. setBlendFunc:function (src, dst) {
  822. if (dst === undefined)
  823. this._blendFunc = src;
  824. else
  825. this._blendFunc = {src:src, dst:dst};
  826. if(cc.renderContextType === cc.CANVAS)
  827. this._isLighterMode = (this._blendFunc && (this._blendFunc.src == 1) && (this._blendFunc.dst == 771));
  828. },
  829. /**
  830. * @param {cc.Color4B} [color=]
  831. * @param {Number} [width=]
  832. * @param {Number} [height=]
  833. * @return {Boolean}
  834. */
  835. init:function (color, width, height) {
  836. if(!cc.Layer.prototype.init.call(this))
  837. return false;
  838. if(cc.renderContextType !== cc.CANVAS)
  839. this.setShaderProgram(cc.ShaderCache.getInstance().programForKey(cc.SHADER_POSITION_COLOR));
  840. var winSize = cc.Director.getInstance().getWinSize();
  841. color = color || new cc.Color4B(0, 0, 0, 255);
  842. width = width || winSize.width;
  843. height = height || winSize.height;
  844. var locDisplayedColor = this._displayedColor;
  845. locDisplayedColor.r = color.r;
  846. locDisplayedColor.g = color.g;
  847. locDisplayedColor.b = color.b;
  848. var locRealColor = this._realColor;
  849. locRealColor.r = color.r;
  850. locRealColor.g = color.g;
  851. locRealColor.b = color.b;
  852. this._displayedOpacity = color.a;
  853. this._realOpacity = color.a;
  854. this.setContentSize(width, height);
  855. this._updateColor();
  856. return true;
  857. },
  858. /**
  859. * Sets the untransformed size of the LayerColor.
  860. * @override
  861. * @param {cc.Size|Number} size The untransformed size of the LayerColor or The untransformed size's width of the LayerColor.
  862. * @param {Number} [height] The untransformed size's height of the LayerColor.
  863. */
  864. setContentSize:null,
  865. _setContentSizeForWebGL:function (size, height) {
  866. var locSquareVertices = this._squareVertices;
  867. if (height === undefined) {
  868. locSquareVertices[1].x = size.width;
  869. locSquareVertices[2].y = size.height;
  870. locSquareVertices[3].x = size.width;
  871. locSquareVertices[3].y = size.height;
  872. } else {
  873. locSquareVertices[1].x = size;
  874. locSquareVertices[2].y = height;
  875. locSquareVertices[3].x = size;
  876. locSquareVertices[3].y = height;
  877. }
  878. this._bindLayerVerticesBufferData();
  879. cc.Layer.prototype.setContentSize.call(this, size, height);
  880. },
  881. _updateColor:null,
  882. _updateColorForCanvas:function () {
  883. },
  884. _updateColorForWebGL:function () {
  885. var locDisplayedColor = this._displayedColor;
  886. var locDisplayedOpacity = this._displayedOpacity, locSquareColors = this._squareColors;
  887. for (var i = 0; i < 4; i++) {
  888. locSquareColors[i].r = locDisplayedColor.r / 255;
  889. locSquareColors[i].g = locDisplayedColor.g / 255;
  890. locSquareColors[i].b = locDisplayedColor.b / 255;
  891. locSquareColors[i].a = locDisplayedOpacity / 255;
  892. }
  893. this._bindLayerColorsBufferData();
  894. },
  895. updateDisplayedColor:function(parentColor){
  896. cc.LayerRGBA.prototype.updateDisplayedColor.call(this, parentColor);
  897. this._updateColor();
  898. },
  899. updateDisplayedOpacity: function(parentOpacity){
  900. cc.LayerRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity);
  901. this._updateColor();
  902. },
  903. _bindLayerVerticesBufferData:function () {
  904. var glContext = cc.renderContext;
  905. glContext.bindBuffer(glContext.ARRAY_BUFFER, this._verticesFloat32Buffer);
  906. glContext.bufferData(glContext.ARRAY_BUFFER, this._squareVerticesAB , glContext.STATIC_DRAW);
  907. },
  908. _bindLayerColorsBufferData:function () {
  909. var glContext = cc.renderContext;
  910. glContext.bindBuffer(glContext.ARRAY_BUFFER, this._colorsUint8Buffer);
  911. glContext.bufferData(glContext.ARRAY_BUFFER, this._squareColorsAB, glContext.STATIC_DRAW);
  912. },
  913. /**
  914. * renders the layer
  915. * @param {CanvasRenderingContext2D|Null} ctx
  916. */
  917. draw:null,
  918. _drawForCanvas:function (ctx) {
  919. var context = ctx || cc.renderContext;
  920. var locContentSize = this.getContentSize(), locEGLViewer = cc.EGLView.getInstance();
  921. var locDisplayedColor = this._displayedColor;
  922. context.fillStyle = "rgba(" + (0 | locDisplayedColor.r) + "," + (0 | locDisplayedColor.g) + ","
  923. + (0 | locDisplayedColor.b) + "," + this._displayedOpacity / 255 + ")";
  924. context.fillRect(0, 0, locContentSize.width * locEGLViewer.getScaleX(), -locContentSize.height * locEGLViewer.getScaleY());
  925. cc.g_NumberOfDraws++;
  926. },
  927. _drawForWebGL:function (ctx) {
  928. var context = ctx || cc.renderContext;
  929. cc.NODE_DRAW_SETUP(this);
  930. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR);
  931. //
  932. // Attributes
  933. //
  934. context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer);
  935. context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, context.FLOAT, false, 0, 0);
  936. context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer);
  937. context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.FLOAT, false, 0, 0);
  938. cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst);
  939. context.drawArrays(context.TRIANGLE_STRIP, 0, 4);
  940. }
  941. });
  942. if(cc.Browser.supportWebGL){
  943. cc.LayerColor.prototype.ctor = cc.LayerColor.prototype._ctorForWebGL;
  944. cc.LayerColor.prototype.setContentSize = cc.LayerColor.prototype._setContentSizeForWebGL;
  945. cc.LayerColor.prototype._updateColor = cc.LayerColor.prototype._updateColorForWebGL;
  946. cc.LayerColor.prototype.draw = cc.LayerColor.prototype._drawForWebGL;
  947. } else {
  948. cc.LayerColor.prototype.ctor = cc.LayerColor.prototype._ctorForCanvas;
  949. cc.LayerColor.prototype.setContentSize = cc.LayerRGBA.prototype.setContentSize;
  950. cc.LayerColor.prototype._updateColor = cc.LayerColor.prototype._updateColorForCanvas;
  951. cc.LayerColor.prototype.draw = cc.LayerColor.prototype._drawForCanvas;
  952. }
  953. /**
  954. * creates a cc.Layer with color, width and height in Points
  955. * @param {cc.Color4B} color
  956. * @param {Number|Null} [width=]
  957. * @param {Number|Null} [height=]
  958. * @return {cc.LayerColor}
  959. * @example
  960. * // Example
  961. * //Create a yellow color layer as background
  962. * var yellowBackground = cc.LayerColor.create(cc.c4b(255,255,0,255));
  963. * //If you didnt pass in width and height, it defaults to the same size as the canvas
  964. *
  965. * //create a yellow box, 200 by 200 in size
  966. * var yellowBox = cc.LayerColor.create(cc.c4b(255,255,0,255), 200, 200);
  967. */
  968. cc.LayerColor.create = function (color, width, height) {
  969. var ret = new cc.LayerColor();
  970. switch (arguments.length) {
  971. case 0:
  972. ret.init();
  973. break;
  974. case 1:
  975. ret.init(color);
  976. break;
  977. case 3:
  978. ret.init(color, width, height);
  979. break;
  980. default :
  981. ret.init();
  982. break;
  983. }
  984. return ret;
  985. };
  986. /**
  987. * <p>
  988. * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.<br/>
  989. *<br/>
  990. * All features from cc.LayerColor are valid, plus the following new features:<br/>
  991. * <ul><li>direction</li>
  992. * <li>final color</li>
  993. * <li>interpolation mode</li></ul>
  994. * <br/>
  995. * Color is interpolated between the startColor and endColor along the given<br/>
  996. * vector (starting at the origin, ending at the terminus). If no vector is<br/>
  997. * supplied, it defaults to (0, -1) -- a fade from top to bottom.<br/>
  998. * <br/>
  999. * If 'compressedInterpolation' is disabled, you will not see either the start or end color for<br/>
  1000. * non-cardinal vectors; a smooth gradient implying both end points will be still<br/>
  1001. * be drawn, however.<br/>
  1002. *<br/>
  1003. * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient.
  1004. * </p>
  1005. * @class
  1006. * @extends cc.LayerColor
  1007. */
  1008. cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
  1009. _startColor:null,
  1010. _endColor:null,
  1011. _startOpacity:null,
  1012. _endOpacity:null,
  1013. _alongVector:null,
  1014. _compressedInterpolation:false,
  1015. _gradientStartPoint:null,
  1016. _gradientEndPoint:null,
  1017. /**
  1018. * Constructor
  1019. * @function
  1020. */
  1021. ctor:function () {
  1022. cc.LayerColor.prototype.ctor.call(this);
  1023. this._startColor = new cc.Color3B(0, 0, 0);
  1024. this._endColor = new cc.Color3B(0, 0, 0);
  1025. this._alongVector = cc.p(0, -1);
  1026. this._startOpacity = 255;
  1027. this._endOpacity = 255;
  1028. this._gradientStartPoint = cc.p(0, 0);
  1029. this._gradientEndPoint = cc.p(0, 0);
  1030. },
  1031. /**
  1032. * Sets the untransformed size of the LayerGradient.
  1033. * @override
  1034. * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient.
  1035. * @param {Number} [height] The untransformed size's height of the LayerGradient.
  1036. */
  1037. setContentSize:function(size, height){
  1038. cc.LayerColor.prototype.setContentSize.call(this,size, height);
  1039. this._updateColor();
  1040. },
  1041. /**
  1042. * get the starting color
  1043. * @return {cc.Color3B}
  1044. */
  1045. getStartColor:function () {
  1046. return this._realColor;
  1047. },
  1048. /**
  1049. * set the starting color
  1050. * @param {cc.Color3B} color
  1051. * @example
  1052. * // Example
  1053. * myGradientLayer.setStartColor(cc.c3b(255,0,0));
  1054. * //set the starting gradient to red
  1055. */
  1056. setStartColor:function (color) {
  1057. this.setColor(color);
  1058. },
  1059. /**
  1060. * set the end gradient color
  1061. * @param {cc.Color3B} color
  1062. * @example
  1063. * // Example
  1064. * myGradientLayer.setEndColor(cc.c3b(255,0,0));
  1065. * //set the ending gradient to red
  1066. */
  1067. setEndColor:function (color) {
  1068. this._endColor = color;
  1069. this._updateColor();
  1070. },
  1071. /**
  1072. * get the end color
  1073. * @return {cc.Color3B}
  1074. */
  1075. getEndColor:function () {
  1076. return this._endColor;
  1077. },
  1078. /**
  1079. * set starting gradient opacity
  1080. * @param {Number} o from 0 to 255, 0 is transparent
  1081. */
  1082. setStartOpacity:function (o) {
  1083. this._startOpacity = o;
  1084. this._updateColor();
  1085. },
  1086. /**
  1087. * get the starting gradient opacity
  1088. * @return {Number}
  1089. */
  1090. getStartOpacity:function () {
  1091. return this._startOpacity;
  1092. },
  1093. /**
  1094. * set the end gradient opacity
  1095. * @param {Number} o
  1096. */
  1097. setEndOpacity:function (o) {
  1098. this._endOpacity = o;
  1099. this._updateColor();
  1100. },
  1101. /**
  1102. * get the end gradient opacity
  1103. * @return {Number}
  1104. */
  1105. getEndOpacity:function () {
  1106. return this._endOpacity;
  1107. },
  1108. /**
  1109. * set vector
  1110. * @param {cc.Point} Var
  1111. */
  1112. setVector:function (Var) {
  1113. this._alongVector.x = Var.x;
  1114. this._alongVector.y = Var.y;
  1115. this._updateColor();
  1116. },
  1117. /**
  1118. * @return {cc.Point}
  1119. */
  1120. getVector:function () {
  1121. return cc.p(this._alongVector.x, this._alongVector.y);
  1122. },
  1123. /** is Compressed Interpolation
  1124. * @return {Boolean}
  1125. */
  1126. isCompressedInterpolation:function () {
  1127. return this._compressedInterpolation;
  1128. },
  1129. /**
  1130. * @param {Boolean} compress
  1131. */
  1132. setCompressedInterpolation:function (compress) {
  1133. this._compressedInterpolation = compress;
  1134. this._updateColor();
  1135. },
  1136. /**
  1137. * @param {cc.Color4B} start starting color
  1138. * @param {cc.Color4B} end
  1139. * @param {cc.Point|Null} v
  1140. * @return {Boolean}
  1141. */
  1142. init:function (start, end, v) {
  1143. start = start || cc.c4(0,0,0,255);
  1144. end = end || cc.c4(0,0,0,255);
  1145. v = v || cc.p(0, -1);
  1146. // Initializes the CCLayer with a gradient between start and end in the direction of v.
  1147. var locStartColor = this._startColor, locEndColor = this._endColor;
  1148. locStartColor.r = start.r;
  1149. locStartColor.g = start.g;
  1150. locStartColor.b = start.b;
  1151. this._startOpacity = start.a;
  1152. locEndColor.r = end.r;
  1153. locEndColor.g = end.g;
  1154. locEndColor.b = end.b;
  1155. this._endOpacity = end.a;
  1156. this._alongVector = v;
  1157. this._compressedInterpolation = true;
  1158. cc.LayerColor.prototype.init.call(this,cc.c4b(start.r, start.g, start.b, 255));
  1159. return true;
  1160. },
  1161. draw:function (ctx) {
  1162. if (cc.renderContextType === cc.WEBGL){
  1163. cc.LayerColor.prototype.draw.call(this, ctx);
  1164. return;
  1165. }
  1166. var context = ctx || cc.renderContext;
  1167. if (this._isLighterMode)
  1168. context.globalCompositeOperation = 'lighter';
  1169. context.save();
  1170. var locEGLViewer = cc.EGLView.getInstance(), opacityf = this._displayedOpacity / 255.0;
  1171. var tWidth = this.getContentSize().width * locEGLViewer.getScaleX();
  1172. var tHeight = this.getContentSize().height * locEGLViewer.getScaleY();
  1173. var tGradient = context.createLinearGradient(this._gradientStartPoint.x, this._gradientStartPoint.y,
  1174. this._gradientEndPoint.x, this._gradientEndPoint.y);
  1175. var locDisplayedColor = this._displayedColor;
  1176. var locEndColor = this._endColor;
  1177. tGradient.addColorStop(0, "rgba(" + Math.round(locDisplayedColor.r) + "," + Math.round(locDisplayedColor.g) + ","
  1178. + Math.round(locDisplayedColor.b) + "," + (opacityf * (this._startOpacity / 255)).toFixed(4) + ")");
  1179. tGradient.addColorStop(1, "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + ","
  1180. + Math.round(locEndColor.b) + "," + (opacityf * (this._endOpacity / 255)).toFixed(4) + ")");
  1181. context.fillStyle = tGradient;
  1182. context.fillRect(0, 0, tWidth, -tHeight);
  1183. if (this._rotation != 0)
  1184. context.rotate(this._rotationRadians);
  1185. context.restore();
  1186. },
  1187. _updateColor:function () {
  1188. var locAlongVector = this._alongVector;
  1189. if (cc.renderContextType === cc.CANVAS) {
  1190. var tWidth = this.getContentSize().width * 0.5;
  1191. var tHeight = this.getContentSize().height * 0.5;
  1192. this._gradientStartPoint.x = tWidth * (-locAlongVector.x) + tWidth;
  1193. this._gradientStartPoint.y = tHeight * locAlongVector.y - tHeight;
  1194. this._gradientEndPoint.x = tWidth * locAlongVector.x + tWidth;
  1195. this._gradientEndPoint.y = tHeight * (-locAlongVector.y) - tHeight;
  1196. } else {
  1197. var h = cc.pLength(locAlongVector);
  1198. if (h === 0)
  1199. return;
  1200. var c = Math.sqrt(2.0);
  1201. var u = cc.p(locAlongVector.x / h, locAlongVector.y / h);
  1202. // Compressed Interpolation mode
  1203. if (this._compressedInterpolation) {
  1204. var h2 = 1 / ( Math.abs(u.x) + Math.abs(u.y) );
  1205. u = cc.pMult(u, h2 * c);
  1206. }
  1207. var opacityf = this._displayedOpacity / 255.0;
  1208. var locDisplayedColor = this._displayedColor, locEndColor = this._endColor;
  1209. var S = { r: locDisplayedColor.r / 255, g: locDisplayedColor.g / 255, b: locDisplayedColor.b / 255, a: (this._startOpacity * opacityf) / 255};
  1210. var E = {r: locEndColor.r / 255, g: locEndColor.g / 255, b: locEndColor.b / 255, a: (this._endOpacity * opacityf) / 255};
  1211. // (-1, -1)
  1212. var locSquareColors = this._squareColors;
  1213. var locSquareColor0 = locSquareColors[0], locSquareColor1 = locSquareColors[1], locSquareColor2 = locSquareColors[2],locSquareColor3 = locSquareColors[3];
  1214. locSquareColor0.r = ((E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0 * c))));
  1215. locSquareColor0.g = ((E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0 * c))));
  1216. locSquareColor0.b = ((E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0 * c))));
  1217. locSquareColor0.a = ((E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0 * c))));
  1218. // (1, -1)
  1219. locSquareColor1.r = ((E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0 * c))));
  1220. locSquareColor1.g = ((E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0 * c))));
  1221. locSquareColor1.b = ((E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0 * c))));
  1222. locSquareColor1.a = ((E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0 * c))));
  1223. // (-1, 1)
  1224. locSquareColor2.r = ((E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0 * c))));
  1225. locSquareColor2.g = ((E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0 * c))));
  1226. locSquareColor2.b = ((E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0 * c))));
  1227. locSquareColor2.a = ((E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0 * c))));
  1228. // (1, 1)
  1229. locSquareColor3.r = ((E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0 * c))));
  1230. locSquareColor3.g = ((E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0 * c))));
  1231. locSquareColor3.b = ((E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0 * c))));
  1232. locSquareColor3.a = ((E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0 * c))));
  1233. this._bindLayerColorsBufferData();
  1234. }
  1235. }
  1236. });
  1237. /**
  1238. * creates a gradient layer
  1239. * @param {cc.Color3B} start starting color
  1240. * @param {cc.Color3B} end ending color
  1241. * @param {cc.Point|Null} v
  1242. * @return {cc.LayerGradient}
  1243. */
  1244. cc.LayerGradient.create = function (start, end, v) {
  1245. var layer = new cc.LayerGradient();
  1246. switch (arguments.length) {
  1247. case 2:
  1248. /** Creates a full-screen CCLayer with a gradient between start and end. */
  1249. if (layer && layer.init(start, end))
  1250. return layer;
  1251. break;
  1252. case 3:
  1253. /** Creates a full-screen CCLayer with a gradient between start and end in the direction of v. */
  1254. if (layer && layer.init(start, end, v))
  1255. return layer;
  1256. break;
  1257. case 0:
  1258. if (layer && layer.init())
  1259. return layer;
  1260. break;
  1261. default:
  1262. throw "Arguments error ";
  1263. break;
  1264. }
  1265. return null;
  1266. };
  1267. /**
  1268. * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.<br/>
  1269. * Features:<br/>
  1270. * <ul><li>- It supports one or more children</li>
  1271. * <li>- Only one children will be active a time</li></ul>
  1272. * @class
  1273. * @extends cc.Layer
  1274. */
  1275. cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{
  1276. _enabledLayer:0,
  1277. _layers:null,
  1278. /**
  1279. * @param {cc.Layer} layer
  1280. * @deprecated merged with initWithLayers
  1281. * @return {Boolean}
  1282. */
  1283. initWithLayer:function (layer) {
  1284. this._layers = [];
  1285. this._layers.push(layer);
  1286. this._enabledLayer = 0;
  1287. this.addChild(layer);
  1288. return true;
  1289. },
  1290. /**
  1291. * @param {Array} args an array of cc.Layer
  1292. * @return {Boolean}
  1293. */
  1294. initWithLayers:function (args) {
  1295. this._layers = args;
  1296. this._enabledLayer = 0;
  1297. this.addChild(this._layers[this._enabledLayer]);
  1298. return true;
  1299. },
  1300. /**
  1301. * switches to a certain layer indexed by n.<br/>
  1302. * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
  1303. * @param {Number} n the layer index to switch to
  1304. */
  1305. switchTo:function (n) {
  1306. if(n >= this._layers.length){
  1307. cc.log("cc.LayerMultiplex.switchTo():Invalid index in MultiplexLayer switchTo message");
  1308. return;
  1309. }
  1310. this.removeChild(this._layers[this._enabledLayer], true);
  1311. this._enabledLayer = n;
  1312. this.addChild(this._layers[n]);
  1313. },
  1314. /** release the current layer and switches to another layer indexed by n.<br/>
  1315. * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
  1316. * @param {Number} n the layer index to switch to
  1317. */
  1318. switchToAndReleaseMe:function (n) {
  1319. if(n >= this._layers.length){
  1320. cc.log("cc.LayerMultiplex.switchToAndReleaseMe():Invalid index in MultiplexLayer switchTo message");
  1321. return;
  1322. }
  1323. this.removeChild(this._layers[this._enabledLayer], true);
  1324. //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]];
  1325. this._layers[this._enabledLayer] = null;
  1326. this._enabledLayer = n;
  1327. this.addChild(this._layers[n]);
  1328. },
  1329. /**
  1330. * @param {cc.Layer} layer
  1331. */
  1332. addLayer:function (layer) {
  1333. if(!layer){
  1334. cc.log("cc.Layer.addLayer(): layer should be non-null");
  1335. return;
  1336. }
  1337. this._layers.push(layer);
  1338. }
  1339. });
  1340. /**
  1341. * creates a cc.LayerMultiplex with one or more layers using a variable argument list.
  1342. * @return {cc.LayerMultiplex|Null}
  1343. * @example
  1344. * // Example
  1345. * var multiLayer = cc.LayerMultiple.create(layer1, layer2, layer3);//any number of layers
  1346. */
  1347. cc.LayerMultiplex.create = function (/*Multiple Arguments*/) {
  1348. if((arguments.length > 0) && (arguments[arguments.length-1] == null))
  1349. cc.log("parameters should not be ending with null in Javascript");
  1350. var multiplexLayer = new cc.LayerMultiplex();
  1351. if (multiplexLayer.initWithLayers(arguments)) {
  1352. return multiplexLayer;
  1353. }
  1354. return null;
  1355. };