diff --git a/AUTHORS.txt b/AUTHORS.txt
index e61d18e5cb..5a20dc7535 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -1,22 +1,20 @@
Cocos2d-html5 authors
-(ordered by the join in time)
+(Ordered by join time)
Core Developers:
Shun Lin (Sean Lin)
- Hao Wu (WuHao)
-
- Dingping Lv (David Lv)
-
Ricardo Quesada
Huabin LING (@pandamicro)
Sijie Wang (@VisualSJ)
- Jialong Zhai (@JoshuaAstray)
+ Long Jiang (@jianglong0156)
+
+ Menghe Zhang (@ZhangMenghe)
Contributors:
Name GithubID Main contribution
@@ -165,6 +163,7 @@ erykwalder @erykwalder Function.prototype.bind bug fix
ZippoLag @ZippoLag cc.Application.getCurrentLanguage bug fix
typo fix
+ Fixed `cc.TMXObjectGroup#objectNamed` not returning the result bug
Asano @LaercioAsano cc.Node bug fix
@@ -178,6 +177,8 @@ Mykyta Usikov @musikov cc.ClippingNode bugs fix
cc.Scale9Sprite bugs fix
cc.RenderTexture bug fix
cc.ParticleSystem bug fix
+ Made CCProgressTimerCanvasRenderCmd to properly show colorized sprites
+ cc.ScrollView and cc.TableView: added check for parent visibility in onTouchBegan method
Han XiaoLong @kpkhxlgy0 cc.ParticleSytem bug fix
@@ -243,6 +244,8 @@ Dany Ellement @DEllement cc.FontDefinition & ccui.RichText improvemen
IShm @IShm cc.Screen bug fix
cc.ParticleSystem bug fix
ccui.PageView bug fix
+ Fixed crash when character not found into BMP font
+ Fixed restoring of sprite's color issue
Thomas Jablonski @thomas-jablonski cc.audioEngine bug fix
Cocostudio typo fix
@@ -255,11 +258,28 @@ feijing566 @feijing566 cc.Audio bug fix
RackovychV @RackovychV Fixed a bug of `cc.Scheduler`'s `pauseAllTargetsWithMinPriority`
+giuseppelt @giuseppelt Fixed TransitionSlideX callback sequence issue
+
+YShumov @pixmaster Fixed issue in music end event
+
+SPACELAN @spacelan Fixed `inverse` function bug of `cc.math.Matrix4`
+
+patriciog @patriciog Allowed timeline animations with only one frame
+
+Ningxin Hu @huningxin SIMD.js optimization for kazmath functions
+
+Zachary Lester @ZLester Fix typo in AUTHORS.txt
+
+Juan Carlos @Ruluk Fixed a bug where not resetting cc.Audio._ignoreEnded when replaying a sound caused it to stay in a "playing" state
+Maxim Litvinov @metalim Throw new Error object instead of error message string
Retired Core Developers:
Shengxiang Chen (Nero Chan)
Xingsen Ma
+ Jialong Zhai (@JoshuaAstray)
+ Hao Wu (WuHao)
+ Dingping Lv (David Lv)
Cocos2d-x and cocos2d-html5 can not grow so fast without the active community.
diff --git a/CCBoot.js b/CCBoot.js
index 1be2d4ff3b..22c50494b6 100644
--- a/CCBoot.js
+++ b/CCBoot.js
@@ -1,6 +1,6 @@
/****************************************************************************
Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
@@ -32,9 +32,7 @@ var cc = cc || {};
cc._tmp = cc._tmp || {};
cc._LogInfos = {};
-/** @expose */
-window._p;
-_p = window;
+var _p = window;
/** @expose */
_p.gl;
/** @expose */
@@ -45,8 +43,10 @@ _p.DeviceOrientationEvent;
_p.DeviceMotionEvent;
/** @expose */
_p.AudioContext;
-/** @expose */
-_p.webkitAudioContext;
+if (!_p.AudioContext) {
+ /** @expose */
+ _p.webkitAudioContext;
+}
/** @expose */
_p.mozAudioContext;
_p = Object.prototype;
@@ -54,18 +54,35 @@ _p = Object.prototype;
_p._super;
/** @expose */
_p.ctor;
-delete window._p;
+_p = null;
-cc.newElement = function (x) {
- return document.createElement(x);
-};
+/**
+ * drawing primitive of game engine
+ * @type {cc.DrawingPrimitive}
+ */
+cc._drawingUtil = null;
-cc._addEventListener = function (element, type, listener, useCapture) {
- element.addEventListener(type, listener, useCapture);
-};
+/**
+ * main Canvas 2D/3D Context of game engine
+ * @type {CanvasRenderingContext2D|WebGLRenderingContext}
+ */
+cc._renderContext = null;
+cc._supportRender = false;
+
+/**
+ * Main canvas of game engine
+ * @type {HTMLCanvasElement}
+ */
+cc._canvas = null;
+
+/**
+ * The element contains the game canvas
+ * @type {HTMLDivElement}
+ */
+cc.container = null;
+cc._gameDiv = null;
-//is nodejs ? Used to support node-webkit.
-cc._isNodeJs = typeof require !== 'undefined' && require("fs");
+window.ENABLE_IMAEG_POOL = true;
/**
* Iterate over an object or an array, executing a function for each matched element.
@@ -95,11 +112,11 @@ cc.each = function (obj, iterator, context) {
* @param {object} *sources
* @returns {object}
*/
-cc.extend = function(target) {
+cc.extend = function (target) {
var sources = arguments.length >= 2 ? Array.prototype.slice.call(arguments, 1) : [];
- cc.each(sources, function(src) {
- for(var key in src) {
+ cc.each(sources, function (src) {
+ for (var key in src) {
if (src.hasOwnProperty(key)) {
target[key] = src[key];
}
@@ -108,12 +125,32 @@ cc.extend = function(target) {
return target;
};
+/**
+ * Another way to subclass: Using Google Closure.
+ * The following code was copied + pasted from goog.base / goog.inherits
+ * @function
+ * @param {Function} childCtor
+ * @param {Function} parentCtor
+ */
+cc.inherits = function (childCtor, parentCtor) {
+ function tempCtor() {}
+ tempCtor.prototype = parentCtor.prototype;
+ childCtor.superClass_ = parentCtor.prototype;
+ childCtor.prototype = new tempCtor();
+ childCtor.prototype.constructor = childCtor;
+
+ // Copy "static" method, but doesn't generate subclasses.
+ // for( var i in parentCtor ) {
+ // childCtor[ i ] = parentCtor[ i ];
+ // }
+};
+
/**
* Check the obj whether is function or not
* @param {*} obj
* @returns {boolean}
*/
-cc.isFunction = function(obj) {
+cc.isFunction = function (obj) {
return typeof obj === 'function';
};
@@ -122,7 +159,7 @@ cc.isFunction = function(obj) {
* @param {*} obj
* @returns {boolean}
*/
-cc.isNumber = function(obj) {
+cc.isNumber = function (obj) {
return typeof obj === 'number' || Object.prototype.toString.call(obj) === '[object Number]';
};
@@ -131,7 +168,7 @@ cc.isNumber = function(obj) {
* @param {*} obj
* @returns {boolean}
*/
-cc.isString = function(obj) {
+cc.isString = function (obj) {
return typeof obj === 'string' || Object.prototype.toString.call(obj) === '[object String]';
};
@@ -140,7 +177,7 @@ cc.isString = function(obj) {
* @param {*} obj
* @returns {boolean}
*/
-cc.isArray = function(obj) {
+cc.isArray = function (obj) {
return Array.isArray(obj) ||
(typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Array]');
};
@@ -150,7 +187,7 @@ cc.isArray = function(obj) {
* @param {*} obj
* @returns {boolean}
*/
-cc.isUndefined = function(obj) {
+cc.isUndefined = function (obj) {
return typeof obj === 'undefined';
};
@@ -159,7 +196,7 @@ cc.isUndefined = function(obj) {
* @param {*} obj
* @returns {boolean}
*/
-cc.isObject = function(obj) {
+cc.isObject = function (obj) {
return typeof obj === "object" && Object.prototype.toString.call(obj) === '[object Object]';
};
@@ -192,8 +229,9 @@ cc.isCrossOrigin = function (url) {
* @param {object} target
* @constructor
*/
-cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){
+cc.AsyncPool = function (srcObj, limit, iterator, onEnd, target) {
var self = this;
+ self._finished = false;
self._srcObj = srcObj;
self._limit = limit;
self._pool = [];
@@ -202,10 +240,10 @@ cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){
self._onEnd = onEnd;
self._onEndTarget = target;
self._results = srcObj instanceof Array ? [] : {};
- self._isErr = false;
+ self._errors = srcObj instanceof Array ? [] : {};
- cc.each(srcObj, function(value, index){
- self._pool.push({index : index, value : value});
+ cc.each(srcObj, function (value, index) {
+ self._pool.push({index: index, value: value});
});
self.size = self._pool.length;
@@ -214,43 +252,42 @@ cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){
self._limit = self._limit || self.size;
- self.onIterator = function(iterator, target){
+ self.onIterator = function (iterator, target) {
self._iterator = iterator;
self._iteratorTarget = target;
};
- self.onEnd = function(endCb, endCbTarget){
+ self.onEnd = function (endCb, endCbTarget) {
self._onEnd = endCb;
self._onEndTarget = endCbTarget;
};
- self._handleItem = function(){
+ self._handleItem = function () {
var self = this;
- if(self._pool.length === 0 || self._workingSize >= self._limit)
+ if (self._pool.length === 0 || self._workingSize >= self._limit)
return; //return directly if the array's length = 0 or the working size great equal limit number
var item = self._pool.shift();
var value = item.value, index = item.index;
self._workingSize++;
self._iterator.call(self._iteratorTarget, value, index,
- function(err) {
- if (self._isErr)
+ function (err, result) {
+ if (self._finished) {
return;
+ }
- self.finishedSize++;
- self._workingSize--;
if (err) {
- self._isErr = true;
- if (self._onEnd)
- self._onEnd.call(self._onEndTarget, err);
- return;
+ self._errors[this.index] = err;
+ }
+ else {
+ self._results[this.index] = result;
}
- var arr = Array.prototype.slice.call(arguments, 1);
- self._results[this.index] = arr[0];
+ self.finishedSize++;
+ self._workingSize--;
if (self.finishedSize === self.size) {
- if (self._onEnd)
- self._onEnd.call(self._onEndTarget, null, self._results);
+ var errors = self._errors.length === 0 ? null : self._errors;
+ self.onEnd(errors, self._results);
return;
}
self._handleItem();
@@ -258,16 +295,27 @@ cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){
self);
};
- self.flow = function(){
+ self.flow = function () {
var self = this;
- if(self._pool.length === 0) {
- if(self._onEnd)
+ if (self._pool.length === 0) {
+ if (self._onEnd)
self._onEnd.call(self._onEndTarget, null, []);
- return;
+ return;
}
- for(var i = 0; i < self._limit; i++)
+ for (var i = 0; i < self._limit; i++)
self._handleItem();
- }
+ };
+
+ self.onEnd = function(errors, results) {
+ self._finished = true;
+ if (self._onEnd) {
+ var selector = self._onEnd;
+ var target = self._onEndTarget;
+ self._onEnd = null;
+ self._onEndTarget = null;
+ selector.call(target, errors, results);
+ }
+ };
};
/**
@@ -281,8 +329,8 @@ cc.async = /** @lends cc.async# */{
* @param {Object} [target]
* @return {cc.AsyncPool}
*/
- series : function(tasks, cb, target){
- var asyncPool = new cc.AsyncPool(tasks, 1, function(func, index, cb1){
+ series: function (tasks, cb, target) {
+ var asyncPool = new cc.AsyncPool(tasks, 1, function (func, index, cb1) {
func.call(target, cb1);
}, cb, target);
asyncPool.flow();
@@ -296,8 +344,8 @@ cc.async = /** @lends cc.async# */{
* @param {Object} [target]
* @return {cc.AsyncPool}
*/
- parallel : function(tasks, cb, target){
- var asyncPool = new cc.AsyncPool(tasks, 0, function(func, index, cb1){
+ parallel: function (tasks, cb, target) {
+ var asyncPool = new cc.AsyncPool(tasks, 0, function (func, index, cb1) {
func.call(target, cb1);
}, cb, target);
asyncPool.flow();
@@ -311,14 +359,14 @@ cc.async = /** @lends cc.async# */{
* @param {Object} [target]
* @return {cc.AsyncPool}
*/
- waterfall : function(tasks, cb, target){
+ waterfall: function (tasks, cb, target) {
var args = [];
var lastResults = [null];//the array to store the last results
var asyncPool = new cc.AsyncPool(tasks, 1,
function (func, index, cb1) {
args.push(function (err) {
args = Array.prototype.slice.call(arguments, 1);
- if(tasks.length - 1 === index) lastResults = lastResults.concat(args);//while the last task
+ if (tasks.length - 1 === index) lastResults = lastResults.concat(args);//while the last task
cb1.apply(null, arguments);
});
func.apply(target, args);
@@ -341,9 +389,9 @@ cc.async = /** @lends cc.async# */{
* @param {Object} [target]
* @return {cc.AsyncPool}
*/
- map : function(tasks, iterator, callback, target){
+ map: function (tasks, iterator, callback, target) {
var locIterator = iterator;
- if(typeof(iterator) === "object"){
+ if (typeof(iterator) === "object") {
callback = iterator.cb;
target = iterator.iteratorTarget;
locIterator = iterator.iterator;
@@ -361,7 +409,7 @@ cc.async = /** @lends cc.async# */{
* @param {function} cb callback
* @param {Object} [target]
*/
- mapLimit : function(tasks, limit, iterator, cb, target){
+ mapLimit: function (tasks, limit, iterator, cb, target) {
var asyncPool = new cc.AsyncPool(tasks, limit, iterator, cb, target);
asyncPool.flow();
return asyncPool;
@@ -374,6 +422,8 @@ cc.async = /** @lends cc.async# */{
* @class
*/
cc.path = /** @lends cc.path# */{
+ normalizeRE: /[^\.\/]+\/\.\.\//,
+
/**
* Join strings to be a path.
* @example
@@ -413,11 +463,11 @@ cc.path = /** @lends cc.path# */{
* @param {string} fileName
* @returns {string}
*/
- mainFileName: function(fileName){
- if(fileName){
- var idx = fileName.lastIndexOf(".");
- if(idx !== -1)
- return fileName.substring(0,idx);
+ mainFileName: function (fileName) {
+ if (fileName) {
+ var idx = fileName.lastIndexOf(".");
+ if (idx !== -1)
+ return fileName.substring(0, idx);
}
return fileName;
},
@@ -510,526 +560,722 @@ cc.path = /** @lends cc.path# */{
index = pathStr.lastIndexOf("/");
index = index <= 0 ? 0 : index + 1;
return pathStr.substring(0, index) + basename + ext + tempStr;
+ },
+ //todo make public after verification
+ _normalize: function (url) {
+ var oldUrl = url = String(url);
+
+ //removing all ../
+ do {
+ oldUrl = url;
+ url = url.replace(this.normalizeRE, "");
+ } while (oldUrl.length !== url.length);
+ return url;
}
};
//+++++++++++++++++++++++++something about path end++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++something about loader start+++++++++++++++++++++++++++
/**
- * Loader for resource loading process. It's a singleton object.
+ * Resource loading management. Created by in CCBoot.js as a singleton
+ * cc.loader.
+ * @name cc.Loader
* @class
+ * @memberof cc
+ * @see cc.loader
*/
-cc.loader = /** @lends cc.loader# */{
- _jsCache: {},//cache for js
- _register: {},//register of loaders
- _langPathCache: {},//cache for lang path
- _aliases: {},//aliases for res url
- resPath: "",//root path of resource
- audioPath: "",//root path of audio
- cache: {},//cache for data loaded
-
- /**
- * Get XMLHttpRequest.
- * @returns {XMLHttpRequest}
- */
- getXMLHttpRequest: function () {
- return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP");
+var imagePool = {
+ _pool: new Array(10),
+ _MAX: 10,
+ _smallImg: "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=",
+
+ count: 0,
+ get: function () {
+ if (this.count > 0) {
+ this.count--;
+ var result = this._pool[this.count];
+ this._pool[this.count] = null;
+ return result;
+ }
+ else {
+ return new Image();
+ }
},
+ put: function (img) {
+ var pool = this._pool;
+ if (img instanceof HTMLImageElement && this.count < this._MAX) {
+ img.src = this._smallImg;
+ pool[this.count] = img;
+ this.count++;
+ }
+ }
+};
+
+/**
+ * Singleton instance of cc.Loader.
+ * @name cc.loader
+ * @member {cc.Loader}
+ * @memberof cc
+ */
+cc.loader = (function () {
+ var _jsCache = {}, //cache for js
+ _register = {}, //register of loaders
+ _langPathCache = {}, //cache for lang path
+ _aliases = {}, //aliases for res url
+ _queue = {}, // Callback queue for resources already loading
+ _urlRegExp = new RegExp("^(?:https?|ftp)://\\S*$", "i");
+
+ return /** @lends cc.Loader# */{
+ /**
+ * Root path of resources.
+ * @type {String}
+ */
+ resPath: "",
+
+ /**
+ * Root path of audio resources
+ * @type {String}
+ */
+ audioPath: "",
+
+ /**
+ * Cache for data loaded.
+ * @type {Object}
+ */
+ cache: {},
+
+ /**
+ * Get XMLHttpRequest.
+ * @returns {XMLHttpRequest}
+ */
+ getXMLHttpRequest: function () {
+ var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP");
+ xhr.timeout = 10000;
+ if (xhr.ontimeout === undefined) {
+ xhr._timeoutId = -1;
+ }
+ return xhr;
+ },
- //@MODE_BEGIN DEV
+ //@MODE_BEGIN DEV
- _getArgs4Js: function (args) {
- var a0 = args[0], a1 = args[1], a2 = args[2], results = ["", null, null];
+ _getArgs4Js: function (args) {
+ var a0 = args[0], a1 = args[1], a2 = args[2], results = ["", null, null];
- if (args.length === 1) {
- results[1] = a0 instanceof Array ? a0 : [a0];
- } else if (args.length === 2) {
- if (typeof a1 === "function") {
+ if (args.length === 1) {
results[1] = a0 instanceof Array ? a0 : [a0];
- results[2] = a1;
- } else {
+ } else if (args.length === 2) {
+ if (typeof a1 === "function") {
+ results[1] = a0 instanceof Array ? a0 : [a0];
+ results[2] = a1;
+ } else {
+ results[0] = a0 || "";
+ results[1] = a1 instanceof Array ? a1 : [a1];
+ }
+ } else if (args.length === 3) {
results[0] = a0 || "";
results[1] = a1 instanceof Array ? a1 : [a1];
- }
- } else if (args.length === 3) {
- results[0] = a0 || "";
- results[1] = a1 instanceof Array ? a1 : [a1];
- results[2] = a2;
- } else throw "arguments error to load js!";
- return results;
- },
-
- /**
- * Load js files.
- * If the third parameter doesn't exist, then the baseDir turns to be "".
- *
- * @param {string} [baseDir] The pre path for jsList or the list of js path.
- * @param {array} jsList List of js path.
- * @param {function} [cb] Callback function
- * @returns {*}
- */
- loadJs: function (baseDir, jsList, cb) {
- var self = this, localJsCache = self._jsCache,
- args = self._getArgs4Js(arguments);
-
- var preDir = args[0], list = args[1], callback = args[2];
- if (navigator.userAgent.indexOf("Trident/5") > -1) {
- self._loadJs4Dependency(preDir, list, 0, callback);
- } else {
- cc.async.map(list, function (item, index, cb1) {
- var jsPath = cc.path.join(preDir, item);
- if (localJsCache[jsPath]) return cb1(null);
- self._createScript(jsPath, false, cb1);
- }, callback);
- }
- },
- /**
- * Load js width loading image.
- *
- * @param {string} [baseDir]
- * @param {array} jsList
- * @param {function} [cb]
- */
- loadJsWithImg: function (baseDir, jsList, cb) {
- var self = this, jsLoadingImg = self._loadJsImg(),
- args = self._getArgs4Js(arguments);
- this.loadJs(args[0], args[1], function (err) {
- if (err) throw err;
- jsLoadingImg.parentNode.removeChild(jsLoadingImg);//remove loading gif
- if (args[2]) args[2]();
- });
- },
- _createScript: function (jsPath, isAsync, cb) {
- var d = document, self = this, s = cc.newElement('script');
- s.async = isAsync;
- self._jsCache[jsPath] = true;
- if(cc.game.config["noCache"] && typeof jsPath === "string"){
- if(self._noCacheRex.test(jsPath))
- s.src = jsPath + "&_t=" + (new Date() - 0);
- else
- s.src = jsPath + "?_t=" + (new Date() - 0);
- }else{
- s.src = jsPath;
- }
- cc._addEventListener(s, 'load', function () {
- s.parentNode.removeChild(s);
- this.removeEventListener('load', arguments.callee, false);
- cb();
- }, false);
- cc._addEventListener(s, 'error', function () {
- s.parentNode.removeChild(s);
- cb("Load " + jsPath + " failed!");
- }, false);
- d.body.appendChild(s);
- },
- _loadJs4Dependency: function (baseDir, jsList, index, cb) {
- if (index >= jsList.length) {
- if (cb) cb();
- return;
- }
- var self = this;
- self._createScript(cc.path.join(baseDir, jsList[index]), false, function (err) {
- if (err) return cb(err);
- self._loadJs4Dependency(baseDir, jsList, index + 1, cb);
- });
- },
- _loadJsImg: function () {
- var d = document, jsLoadingImg = d.getElementById("cocos2d_loadJsImg");
- if (!jsLoadingImg) {
- jsLoadingImg = cc.newElement('img');
-
- if (cc._loadingImage)
- jsLoadingImg.src = cc._loadingImage;
-
- var canvasNode = d.getElementById(cc.game.config["id"]);
- canvasNode.style.backgroundColor = "black";
- canvasNode.parentNode.appendChild(jsLoadingImg);
-
- var canvasStyle = getComputedStyle ? getComputedStyle(canvasNode) : canvasNode.currentStyle;
- if (!canvasStyle)
- canvasStyle = {width: canvasNode.width, height: canvasNode.height};
- jsLoadingImg.style.left = canvasNode.offsetLeft + (parseFloat(canvasStyle.width) - jsLoadingImg.width) / 2 + "px";
- jsLoadingImg.style.top = canvasNode.offsetTop + (parseFloat(canvasStyle.height) - jsLoadingImg.height) / 2 + "px";
- jsLoadingImg.style.position = "absolute";
- }
- return jsLoadingImg;
- },
- //@MODE_END DEV
-
- /**
- * Load a single resource as txt.
- * @param {string} url
- * @param {function} [cb] arguments are : err, txt
- */
- loadTxt: function (url, cb) {
- if (!cc._isNodeJs) {
- var xhr = this.getXMLHttpRequest(),
- errInfo = "load " + url + " failed!";
- xhr.open("GET", url, true);
- if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
- // IE-specific logic here
- xhr.setRequestHeader("Accept-Charset", "utf-8");
- xhr.onreadystatechange = function () {
- if(xhr.readyState === 4)
- xhr.status === 200 ? cb(null, xhr.responseText) : cb(errInfo);
- };
+ results[2] = a2;
+ } else throw new Error("arguments error to load js!");
+ return results;
+ },
+
+ isLoading: function (url) {
+ return (_queue[url] !== undefined);
+ },
+
+ /**
+ * Load js files.
+ * If the third parameter doesn't exist, then the baseDir turns to be "".
+ *
+ * @param {string} [baseDir] The pre path for jsList or the list of js path.
+ * @param {array} jsList List of js path.
+ * @param {function} [cb] Callback function
+ * @returns {*}
+ */
+ loadJs: function (baseDir, jsList, cb) {
+ var self = this,
+ args = self._getArgs4Js(arguments);
+
+ var preDir = args[0], list = args[1], callback = args[2];
+ if (navigator.userAgent.indexOf("Trident/5") > -1) {
+ self._loadJs4Dependency(preDir, list, 0, callback);
} else {
- if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
- xhr.onload = function () {
- if(xhr.readyState === 4)
- xhr.status === 200 ? cb(null, xhr.responseText) : cb(errInfo);
- };
+ cc.async.map(list, function (item, index, cb1) {
+ var jsPath = cc.path.join(preDir, item);
+ if (_jsCache[jsPath]) return cb1(null);
+ self._createScript(jsPath, false, cb1);
+ }, callback);
}
- xhr.send(null);
- } else {
- var fs = require("fs");
- fs.readFile(url, function (err, data) {
- err ? cb(err) : cb(null, data.toString());
+ },
+ /**
+ * Load js width loading image.
+ *
+ * @param {string} [baseDir]
+ * @param {array} jsList
+ * @param {function} [cb]
+ */
+ loadJsWithImg: function (baseDir, jsList, cb) {
+ var self = this, jsLoadingImg = self._loadJsImg(),
+ args = self._getArgs4Js(arguments);
+ this.loadJs(args[0], args[1], function (err) {
+ if (err) throw new Error(err);
+ jsLoadingImg.parentNode.removeChild(jsLoadingImg);//remove loading gif
+ if (args[2]) args[2]();
});
- }
- },
- _loadTxtSync: function (url) {
- if (!cc._isNodeJs) {
- var xhr = this.getXMLHttpRequest();
- xhr.open("GET", url, false);
- if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
- // IE-specific logic here
- xhr.setRequestHeader("Accept-Charset", "utf-8");
+ },
+ _createScript: function (jsPath, isAsync, cb) {
+ var d = document, self = this, s = document.createElement('script');
+ s.async = isAsync;
+ _jsCache[jsPath] = true;
+ if (cc.game.config["noCache"] && typeof jsPath === "string") {
+ if (self._noCacheRex.test(jsPath))
+ s.src = jsPath + "&_t=" + (new Date() - 0);
+ else
+ s.src = jsPath + "?_t=" + (new Date() - 0);
} else {
- if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
+ s.src = jsPath;
}
- xhr.send(null);
- if (!xhr.readyState === 4 || xhr.status !== 200) {
- return null;
+ s.addEventListener('load', function () {
+ s.parentNode.removeChild(s);
+ this.removeEventListener('load', arguments.callee, false);
+ cb();
+ }, false);
+ s.addEventListener('error', function () {
+ s.parentNode.removeChild(s);
+ cb("Load " + jsPath + " failed!");
+ }, false);
+ d.body.appendChild(s);
+ },
+ _loadJs4Dependency: function (baseDir, jsList, index, cb) {
+ if (index >= jsList.length) {
+ if (cb) cb();
+ return;
}
- return xhr.responseText;
- } else {
- var fs = require("fs");
- return fs.readFileSync(url).toString();
- }
- },
-
- loadCsb: function(url, cb){
- var xhr = new XMLHttpRequest();
- xhr.open("GET", url, true);
- xhr.responseType = "arraybuffer";
-
- xhr.onload = function () {
- var arrayBuffer = xhr.response; // Note: not oReq.responseText
- if (arrayBuffer) {
- window.msg = arrayBuffer;
+ var self = this;
+ self._createScript(cc.path.join(baseDir, jsList[index]), false, function (err) {
+ if (err) return cb(err);
+ self._loadJs4Dependency(baseDir, jsList, index + 1, cb);
+ });
+ },
+ _loadJsImg: function () {
+ var d = document, jsLoadingImg = d.getElementById("cocos2d_loadJsImg");
+ if (!jsLoadingImg) {
+ jsLoadingImg = document.createElement('img');
+
+ if (cc._loadingImage)
+ jsLoadingImg.src = cc._loadingImage;
+
+ var canvasNode = d.getElementById(cc.game.config["id"]);
+ canvasNode.style.backgroundColor = "transparent";
+ canvasNode.parentNode.appendChild(jsLoadingImg);
+
+ var canvasStyle = getComputedStyle ? getComputedStyle(canvasNode) : canvasNode.currentStyle;
+ if (!canvasStyle)
+ canvasStyle = {width: canvasNode.width, height: canvasNode.height};
+ jsLoadingImg.style.left = canvasNode.offsetLeft + (parseFloat(canvasStyle.width) - jsLoadingImg.width) / 2 + "px";
+ jsLoadingImg.style.top = canvasNode.offsetTop + (parseFloat(canvasStyle.height) - jsLoadingImg.height) / 2 + "px";
+ jsLoadingImg.style.position = "absolute";
}
- if(xhr.readyState === 4)
- xhr.status === 200 ? cb(null, xhr.response) : cb("load " + url + " failed!");
- };
+ return jsLoadingImg;
+ },
+ //@MODE_END DEV
+
+ /**
+ * Load a single resource as txt.
+ * @param {string} url
+ * @param {function} [cb] arguments are : err, txt
+ */
+ loadTxt: function (url, cb) {
+ if (!cc._isNodeJs) {
+ var xhr = this.getXMLHttpRequest(),
+ errInfo = "load " + url + " failed!";
+ xhr.open("GET", url, true);
+ if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
+ // IE-specific logic here
+ xhr.setRequestHeader("Accept-Charset", "utf-8");
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4)
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ };
+ } else {
+ if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ if (xhr.readyState === 4) {
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ }
+ };
+ var errorCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: errInfo}, null);
+ };
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
+ if (xhr.ontimeout === undefined) {
+ xhr._timeoutId = setTimeout(function () {
+ timeoutCallback();
+ }, xhr.timeout);
+ }
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
+ }
+ xhr.send(null);
+ } else {
+ var fs = require("fs");
+ fs.readFile(url, function (err, data) {
+ err ? cb(err) : cb(null, data.toString());
+ });
+ }
+ },
- xhr.send(null);
- },
+ loadCsb: function(url, cb){
+ var xhr = cc.loader.getXMLHttpRequest(),
+ errInfo = "load " + url + " failed!";
+ xhr.open("GET", url, true);
+ xhr.responseType = "arraybuffer";
- /**
- * Load a single resource as json.
- * @param {string} url
- * @param {function} [cb] arguments are : err, json
- */
- loadJson: function (url, cb) {
- this.loadTxt(url, function (err, txt) {
- if (err) {
- cb(err);
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ var arrayBuffer = xhr.response; // Note: not oReq.responseText
+ if (arrayBuffer) {
+ window.msg = arrayBuffer;
+ }
+ if (xhr.readyState === 4) {
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.response) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ }
+ };
+ var errorCallback = function(){
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status:xhr.status, errorMessage:errInfo}, null);
+ };
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
+ if (xhr.ontimeout === undefined) {
+ xhr._timeoutId = setTimeout(function () {
+ timeoutCallback();
+ }, xhr.timeout);
}
else {
- try {
- var result = JSON.parse(txt);
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
+ xhr.send(null);
+ },
+
+ /**
+ * Load a single resource as json.
+ * @param {string} url
+ * @param {function} [cb] arguments are : err, json
+ */
+ loadJson: function (url, cb) {
+ this.loadTxt(url, function (err, txt) {
+ if (err) {
+ cb(err);
}
- catch (e) {
- throw "parse json [" + url + "] failed : " + e;
- return;
+ else {
+ try {
+ var result = JSON.parse(txt);
+ }
+ catch (e) {
+ throw new Error("parse json [" + url + "] failed : " + e);
+ return;
+ }
+ cb(null, result);
}
- cb(null, result);
+ });
+ },
+
+ _checkIsImageURL: function (url) {
+ var ext = /(\.png)|(\.jpg)|(\.bmp)|(\.jpeg)|(\.gif)/.exec(url);
+ return (ext != null);
+ },
+ /**
+ * Load a single image.
+ * @param {!string} url
+ * @param {object} [option]
+ * @param {function} callback
+ * @returns {Image}
+ */
+ loadImg: function (url, option, callback, img) {
+ var opt = {
+ isCrossOrigin: true
+ };
+ if (callback !== undefined)
+ opt.isCrossOrigin = option.isCrossOrigin === undefined ? opt.isCrossOrigin : option.isCrossOrigin;
+ else if (option !== undefined)
+ callback = option;
+
+ var texture = this.getRes(url);
+ if (texture) {
+ callback && callback(null, texture);
+ return null;
}
- });
- },
-
- _checkIsImageURL: function (url) {
- var ext = /(\.png)|(\.jpg)|(\.bmp)|(\.jpeg)|(\.gif)/.exec(url);
- return (ext != null);
- },
- /**
- * Load a single image.
- * @param {!string} url
- * @param {object} [option]
- * @param {function} callback
- * @returns {Image}
- */
- loadImg: function (url, option, callback) {
- var opt = {
- isCrossOrigin: true
- };
- if (callback !== undefined)
- opt.isCrossOrigin = option.isCrossOrigin === null ? opt.isCrossOrigin : option.isCrossOrigin;
- else if (option !== undefined)
- callback = option;
-
- var img = this.getRes(url);
- if (img) {
- callback && callback(null, img);
- return img;
- }
- img = new Image();
- if (opt.isCrossOrigin && location.origin !== "file://")
- img.crossOrigin = "Anonymous";
-
- var loadCallback = function () {
- this.removeEventListener('load', loadCallback, false);
- this.removeEventListener('error', errorCallback, false);
+ var queue = _queue[url];
+ if (queue) {
+ queue.callbacks.push(callback);
+ return queue.img;
+ }
- cc.loader.cache[url] = img;
- if (callback)
- callback(null, img);
- };
+ img = img || imagePool.get();
+ if (opt.isCrossOrigin && location.origin !== "file://")
+ img.crossOrigin = "Anonymous";
+ else
+ img.crossOrigin = null;
+
+ var loadCallback = function () {
+ this.removeEventListener('load', loadCallback, false);
+ this.removeEventListener('error', errorCallback, false);
+
+ var queue = _queue[url];
+ if (queue) {
+ var callbacks = queue.callbacks;
+ for (var i = 0; i < callbacks.length; ++i) {
+ var cb = callbacks[i];
+ if (cb) {
+ cb(null, img);
+ }
+ }
+ queue.img = null;
+ delete _queue[url];
+ }
- var self = this;
- var errorCallback = function () {
- this.removeEventListener('error', errorCallback, false);
-
- if(img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous"){
- opt.isCrossOrigin = false;
- self.release(url);
- cc.loader.loadImg(url, opt, callback);
- }else{
- typeof callback === "function" && callback("load image failed");
- }
- };
+ if (window.ENABLE_IMAEG_POOL && cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
+ };
+
+ var self = this;
+ var errorCallback = function () {
+ this.removeEventListener('load', loadCallback, false);
+ this.removeEventListener('error', errorCallback, false);
+
+ if (window.location.protocol !== 'https:' && img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous") {
+ opt.isCrossOrigin = false;
+ self.release(url);
+ cc.loader.loadImg(url, opt, callback, img);
+ } else {
+ var queue = _queue[url];
+ if (queue) {
+ var callbacks = queue.callbacks;
+ for (var i = 0; i < callbacks.length; ++i) {
+ var cb = callbacks[i];
+ if (cb) {
+ cb("load image failed");
+ }
+ }
+ queue.img = null;
+ delete _queue[url];
+ }
- cc._addEventListener(img, "load", loadCallback);
- cc._addEventListener(img, "error", errorCallback);
- img.src = url;
- return img;
- },
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
+ }
+ };
- /**
- * Iterator function to load res
- * @param {object} item
- * @param {number} index
- * @param {function} [cb]
- * @returns {*}
- * @private
- */
- _loadResIterator: function (item, index, cb) {
- var self = this, url = null;
- var type = item.type;
- if (type) {
- type = "." + type.toLowerCase();
- url = item.src ? item.src : item.name + type;
- } else {
- url = item;
- type = cc.path.extname(url);
- }
+ _queue[url] = {
+ img: img,
+ callbacks: callback ? [callback] : []
+ };
- var obj = self.getRes(url);
- if (obj)
- return cb(null, obj);
- var loader = null;
- if (type) {
- loader = self._register[type.toLowerCase()];
- }
- if (!loader) {
- cc.error("loader for [" + type + "] not exists!");
- return cb();
- }
- var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
- var realUrl = self.getUrl(basePath, url);
- if(cc.game.config["noCache"] && typeof realUrl === "string"){
- if(self._noCacheRex.test(realUrl))
- realUrl += "&_t=" + (new Date() - 0);
- else
- realUrl += "?_t=" + (new Date() - 0);
- }
- loader.load(realUrl, url, item, function (err, data) {
- if (err) {
- cc.log(err);
- self.cache[url] = null;
- delete self.cache[url];
- cb();
+ img.addEventListener("load", loadCallback);
+ img.addEventListener("error", errorCallback);
+ img.src = url;
+ return img;
+ },
+
+ /**
+ * Iterator function to load res
+ * @param {object} item
+ * @param {number} index
+ * @param {function} [cb]
+ * @returns {*}
+ * @private
+ */
+ _loadResIterator: function (item, index, cb) {
+ var self = this, url = null;
+ var type = item.type;
+ if (type) {
+ type = "." + type.toLowerCase();
+ url = item.src ? item.src : item.name + type;
} else {
- self.cache[url] = data;
- cb(null, data);
+ url = item;
+ type = cc.path.extname(url);
}
- });
- },
- _noCacheRex: /\?/,
- /**
- * Get url with basePath.
- * @param {string} basePath
- * @param {string} [url]
- * @returns {*}
- */
- getUrl: function (basePath, url) {
- var self = this, langPathCache = self._langPathCache, path = cc.path;
- if (basePath !== undefined && url === undefined) {
- url = basePath;
- var type = path.extname(url);
- type = type ? type.toLowerCase() : "";
- var loader = self._register[type];
- if (!loader)
- basePath = self.resPath;
- else
- basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
- }
- url = cc.path.join(basePath || "", url);
- if (url.match(/[\/(\\\\)]lang[\/(\\\\)]/i)) {
- if (langPathCache[url])
- return langPathCache[url];
- var extname = path.extname(url) || "";
- url = langPathCache[url] = url.substring(0, url.length - extname.length) + "_" + cc.sys.language + extname;
- }
- return url;
- },
+ var obj = self.getRes(url);
+ if (obj)
+ return cb(null, obj);
+ var loader = null;
+ if (type) {
+ loader = _register[type.toLowerCase()];
+ }
+ if (!loader) {
+ cc.error("loader for [" + type + "] doesn't exist!");
+ return cb();
+ }
+ var realUrl = url;
+ if (!_urlRegExp.test(url)) {
+ var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
+ realUrl = self.getUrl(basePath, url);
+ }
- /**
- * Load resources then call the callback.
- * @param {string} resources
- * @param {function} [option] callback or trigger
- * @param {function|Object} [loadCallback]
- * @return {cc.AsyncPool}
- */
- load : function(resources, option, loadCallback){
- var self = this;
- var len = arguments.length;
- if(len === 0)
- throw "arguments error!";
-
- if(len === 3){
- if(typeof option === "function"){
- if(typeof loadCallback === "function")
- option = {trigger : option, cb : loadCallback };
+ if (cc.game.config["noCache"] && typeof realUrl === "string") {
+ if (self._noCacheRex.test(realUrl))
+ realUrl += "&_t=" + (new Date() - 0);
else
- option = { cb : option, cbTarget : loadCallback};
+ realUrl += "?_t=" + (new Date() - 0);
}
- }else if(len === 2){
- if(typeof option === "function")
- option = {cb : option};
- }else if(len === 1){
- option = {};
- }
-
- if(!(resources instanceof Array))
- resources = [resources];
- var asyncPool = new cc.AsyncPool(
- resources, 0,
- function (value, index, AsyncPoolCallback, aPool) {
- self._loadResIterator(value, index, function (err) {
- if (err)
- return AsyncPoolCallback(err);
- var arr = Array.prototype.slice.call(arguments, 1);
- if (option.trigger)
- option.trigger.call(option.triggerTarget, arr[0], aPool.size, aPool.finishedSize); //call trigger
- AsyncPoolCallback(null, arr[0]);
- });
- },
- option.cb, option.cbTarget);
- asyncPool.flow();
- return asyncPool;
- },
-
- _handleAliases: function (fileNames, cb) {
- var self = this, aliases = self._aliases;
- var resList = [];
- for (var key in fileNames) {
- var value = fileNames[key];
- aliases[key] = value;
- resList.push(value);
- }
- this.load(resList, cb);
- },
-
- /**
- *
- * Loads alias map from the contents of a filename.
- *
- * @note The plist file name should follow the format below:
- *
- *
- *
- *
- * filenames
- *
- * sounds/click.wav
- * sounds/click.caf
- * sounds/endgame.wav
- * sounds/endgame.caf
- * sounds/gem-0.wav
- * sounds/gem-0.caf
- *
- * metadata
- *
- * version
- * 1
- *
- *
- *
- *
- * @param {String} url The plist file name.
- * @param {Function} [callback]
- */
- loadAliases: function (url, callback) {
- var self = this, dict = self.getRes(url);
- if (!dict) {
- self.load(url, function (err, results) {
- self._handleAliases(results[0]["filenames"], callback);
+ loader.load(realUrl, url, item, function (err, data) {
+ if (err) {
+ cc.log(err);
+ self.cache[url] = null;
+ delete self.cache[url];
+ cb({status: 520, errorMessage: err}, null);
+ } else {
+ self.cache[url] = data;
+ cb(null, data);
+ }
});
- } else
- self._handleAliases(dict["filenames"], callback);
- },
+ },
+ _noCacheRex: /\?/,
+
+ /**
+ * Get url with basePath.
+ * @param {string} basePath
+ * @param {string} [url]
+ * @returns {*}
+ */
+ getUrl: function (basePath, url) {
+ var self = this, path = cc.path;
+ if (basePath !== undefined && url === undefined) {
+ url = basePath;
+ var type = path.extname(url);
+ type = type ? type.toLowerCase() : "";
+ var loader = _register[type];
+ if (!loader)
+ basePath = self.resPath;
+ else
+ basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
+ }
+ url = cc.path.join(basePath || "", url);
+ if (url.match(/[\/(\\\\)]lang[\/(\\\\)]/i)) {
+ if (_langPathCache[url])
+ return _langPathCache[url];
+ var extname = path.extname(url) || "";
+ url = _langPathCache[url] = url.substring(0, url.length - extname.length) + "_" + cc.sys.language + extname;
+ }
+ return url;
+ },
+
+ /**
+ * Load resources then call the callback.
+ * @param {string} resources
+ * @param {function} [option] callback or trigger
+ * @param {function|Object} [loadCallback]
+ * @return {cc.AsyncPool}
+ */
+ load: function (resources, option, loadCallback) {
+ var self = this;
+ var len = arguments.length;
+ if (len === 0)
+ throw new Error("arguments error!");
+
+ if (len === 3) {
+ if (typeof option === "function") {
+ if (typeof loadCallback === "function")
+ option = {trigger: option, cb: loadCallback};
+ else
+ option = {cb: option, cbTarget: loadCallback};
+ }
+ } else if (len === 2) {
+ if (typeof option === "function")
+ option = {cb: option};
+ } else if (len === 1) {
+ option = {};
+ }
- /**
- * Register a resource loader into loader.
- * @param {string} extNames
- * @param {function} loader
- */
- register: function (extNames, loader) {
- if (!extNames || !loader) return;
- var self = this;
- if (typeof extNames === "string")
- return this._register[extNames.trim().toLowerCase()] = loader;
- for (var i = 0, li = extNames.length; i < li; i++) {
- self._register["." + extNames[i].trim().toLowerCase()] = loader;
+ if (!(resources instanceof Array))
+ resources = [resources];
+ var asyncPool = new cc.AsyncPool(
+ resources, cc.CONCURRENCY_HTTP_REQUEST_COUNT,
+ function (value, index, AsyncPoolCallback, aPool) {
+ self._loadResIterator(value, index, function (err) {
+ var arr = Array.prototype.slice.call(arguments, 1);
+ if (option.trigger)
+ option.trigger.call(option.triggerTarget, arr[0], aPool.size, aPool.finishedSize); //call trigger
+ AsyncPoolCallback(err, arr[0]);
+ });
+ },
+ option.cb, option.cbTarget);
+ asyncPool.flow();
+ return asyncPool;
+ },
+
+ _handleAliases: function (fileNames, cb) {
+ var self = this;
+ var resList = [];
+ for (var key in fileNames) {
+ var value = fileNames[key];
+ _aliases[key] = value;
+ resList.push(value);
+ }
+ this.load(resList, cb);
+ },
+
+ /**
+ *
+ * Loads alias map from the contents of a filename.
+ *
+ * @note The plist file name should follow the format below:
+ *
+ *
+ *
+ *
+ * filenames
+ *
+ * sounds/click.wav
+ * sounds/click.caf
+ * sounds/endgame.wav
+ * sounds/endgame.caf
+ * sounds/gem-0.wav
+ * sounds/gem-0.caf
+ *
+ * metadata
+ *
+ * version
+ * 1
+ *
+ *
+ *
+ *
+ * @param {String} url The plist file name.
+ * @param {Function} [callback]
+ */
+ loadAliases: function (url, callback) {
+ var self = this, dict = self.getRes(url);
+ if (!dict) {
+ self.load(url, function (err, results) {
+ self._handleAliases(results[0]["filenames"], callback);
+ });
+ } else
+ self._handleAliases(dict["filenames"], callback);
+ },
+
+ /**
+ * Register a resource loader into loader.
+ * @param {string} extNames
+ * @param {function} loader
+ */
+ register: function (extNames, loader) {
+ if (!extNames || !loader) return;
+ var self = this;
+ if (typeof extNames === "string")
+ return _register[extNames.trim().toLowerCase()] = loader;
+ for (var i = 0, li = extNames.length; i < li; i++) {
+ _register["." + extNames[i].trim().toLowerCase()] = loader;
+ }
+ },
+
+ /**
+ * Get resource data by url.
+ * @param url
+ * @returns {*}
+ */
+ getRes: function (url) {
+ return this.cache[url] || this.cache[_aliases[url]];
+ },
+
+ /**
+ * Get aliase by url.
+ * @param url
+ * @returns {*}
+ */
+ _getAliase: function (url) {
+ return _aliases[url];
+ },
+
+ /**
+ * Release the cache of resource by url.
+ * @param url
+ */
+ release: function (url) {
+ var cache = this.cache;
+ var queue = _queue[url];
+ if (queue) {
+ queue.img = null;
+ delete _queue[url];
+ }
+ delete cache[url];
+ delete cache[_aliases[url]];
+ delete _aliases[url];
+ },
+
+ /**
+ * Resource cache of all resources.
+ */
+ releaseAll: function () {
+ var locCache = this.cache;
+ for (var key in locCache)
+ delete locCache[key];
+ for (var key in _aliases)
+ delete _aliases[key];
}
- },
-
- /**
- * Get resource data by url.
- * @param url
- * @returns {*}
- */
- getRes: function (url) {
- return this.cache[url] || this.cache[this._aliases[url]];
- },
-
- /**
- * Release the cache of resource by url.
- * @param url
- */
- release: function (url) {
- var cache = this.cache, aliases = this._aliases;
- delete cache[url];
- delete cache[aliases[url]];
- delete aliases[url];
- },
-
- /**
- * Resource cache of all resources.
- */
- releaseAll: function () {
- var locCache = this.cache, aliases = this._aliases;
- for (var key in locCache)
- delete locCache[key];
- for (var key in aliases)
- delete aliases[key];
- }
-};
+ };
+})();
//+++++++++++++++++++++++++something about loader end+++++++++++++++++++++++++++++
/**
@@ -1039,143 +1285,65 @@ cc.loader = /** @lends cc.loader# */{
* cc.formatStr(a, b, c);
* @returns {String}
*/
-cc.formatStr = function(){
+cc.formatStr = function () {
var args = arguments;
var l = args.length;
- if(l < 1)
+ if (l < 1)
return "";
var str = args[0];
var needToFormat = true;
- if(typeof str === "object"){
+ if (typeof str === "object") {
needToFormat = false;
}
- for(var i = 1; i < l; ++i){
+ for (var i = 1; i < l; ++i) {
var arg = args[i];
- if(needToFormat){
- while(true){
+ if (needToFormat) {
+ while (true) {
var result = null;
- if(typeof arg === "number"){
+ if (typeof arg === "number") {
result = str.match(/(%d)|(%s)/);
- if(result){
+ if (result) {
str = str.replace(/(%d)|(%s)/, arg);
break;
}
}
result = str.match(/%s/);
- if(result)
+ if (result)
str = str.replace(/%s/, arg);
else
str += " " + arg;
break;
}
- }else
+ } else
str += " " + arg;
}
return str;
};
-//+++++++++++++++++++++++++something about window events begin+++++++++++++++++++++++++++
+//+++++++++++++++++++++++++Engine initialization function begin+++++++++++++++++++++++++++
(function () {
- var win = window, hidden, visibilityChange, _undef = "undefined";
- if (!cc.isUndefined(document.hidden)) {
- hidden = "hidden";
- visibilityChange = "visibilitychange";
- } else if (!cc.isUndefined(document.mozHidden)) {
- hidden = "mozHidden";
- visibilityChange = "mozvisibilitychange";
- } else if (!cc.isUndefined(document.msHidden)) {
- hidden = "msHidden";
- visibilityChange = "msvisibilitychange";
- } else if (!cc.isUndefined(document.webkitHidden)) {
- hidden = "webkitHidden";
- visibilityChange = "webkitvisibilitychange";
- }
-
- var onHidden = function () {
- if (cc.eventManager && cc.game._eventHide)
- cc.eventManager.dispatchEvent(cc.game._eventHide);
- };
- var onShow = function () {
- if (cc.eventManager && cc.game._eventShow)
- cc.eventManager.dispatchEvent(cc.game._eventShow);
- if(cc.game._intervalId){
- window.cancelAnimationFrame(cc.game._intervalId);
+var _tmpCanvas1 = document.createElement("canvas"),
+ _tmpCanvas2 = document.createElement("canvas");
- cc.game._runMainLoop();
+cc.create3DContext = function (canvas, opt_attribs) {
+ var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
+ var context = null;
+ for (var ii = 0; ii < names.length; ++ii) {
+ try {
+ context = canvas.getContext(names[ii], opt_attribs);
+ } catch (e) {
+ }
+ if (context) {
+ break;
}
- };
-
- if (hidden) {
- cc._addEventListener(document, visibilityChange, function () {
- if (document[hidden]) onHidden();
- else onShow();
- }, false);
- } else {
- cc._addEventListener(win, "blur", onHidden, false);
- cc._addEventListener(win, "focus", onShow, false);
- }
-
- if(navigator.userAgent.indexOf("MicroMessenger") > -1){
- win.onfocus = function(){ onShow() };
}
+ return context;
+};
- if ("onpageshow" in window && "onpagehide" in window) {
- cc._addEventListener(win, "pagehide", onHidden, false);
- cc._addEventListener(win, "pageshow", onShow, false);
- }
- win = null;
- visibilityChange = null;
-})();
-//+++++++++++++++++++++++++something about window events end+++++++++++++++++++++++++++++
-
-//+++++++++++++++++++++++++something about log start++++++++++++++++++++++++++++
-
-//to make sure the cc.log, cc.warn, cc.error and cc.assert would not throw error before init by debugger mode.
-
-cc.log = cc.warn = cc.error = cc.assert = function () {
-};
-
-//+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
-
-/**
- * create a webgl context
- * @param {HTMLCanvasElement} canvas
- * @param {Object} opt_attribs
- * @return {WebGLRenderingContext}
- */
-cc.create3DContext = function (canvas, opt_attribs) {
- var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
- var context = null;
- for (var ii = 0; ii < names.length; ++ii) {
- try {
- context = canvas.getContext(names[ii], opt_attribs);
- } catch (e) {
- }
- if (context) {
- break;
- }
- }
- return context;
-};
-//+++++++++++++++++++++++++something about sys begin+++++++++++++++++++++++++++++
-cc._initSys = function (config, CONFIG_KEY) {
- /**
- * Canvas of render type
- * @constant
- * @type {Number}
- */
- cc._RENDER_TYPE_CANVAS = 0;
-
- /**
- * WebGL of render type
- * @constant
- * @type {Number}
- */
- cc._RENDER_TYPE_WEBGL = 1;
-
+var _initSys = function () {
/**
* System variables
* @namespace
@@ -1319,6 +1487,15 @@ cc._initSys = function (config, CONFIG_KEY) {
*/
sys.LANGUAGE_POLISH = "pl";
+ /**
+ * Unknown language code
+ * @memberof cc.sys
+ * @name LANGUAGE_UNKNOWN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_UNKNOWN = "unkonwn";
+
/**
* @memberof cc.sys
* @name OS_IOS
@@ -1404,55 +1581,55 @@ cc._initSys = function (config, CONFIG_KEY) {
* @default
* @type {Number}
*/
- sys.UNKNOWN = 0;
+ sys.UNKNOWN = -1;
/**
* @memberof cc.sys
- * @name IOS
+ * @name WIN32
* @constant
* @default
* @type {Number}
*/
- sys.IOS = 1;
+ sys.WIN32 = 0;
/**
* @memberof cc.sys
- * @name ANDROID
+ * @name LINUX
* @constant
* @default
* @type {Number}
*/
- sys.ANDROID = 2;
+ sys.LINUX = 1;
/**
* @memberof cc.sys
- * @name WIN32
+ * @name MACOS
* @constant
* @default
* @type {Number}
*/
- sys.WIN32 = 3;
+ sys.MACOS = 2;
/**
* @memberof cc.sys
- * @name MARMALADE
+ * @name ANDROID
* @constant
* @default
* @type {Number}
*/
- sys.MARMALADE = 4;
+ sys.ANDROID = 3;
/**
* @memberof cc.sys
- * @name LINUX
+ * @name IOS
* @constant
* @default
* @type {Number}
*/
- sys.LINUX = 5;
+ sys.IPHONE = 4;
/**
* @memberof cc.sys
- * @name BADA
+ * @name IOS
* @constant
* @default
* @type {Number}
*/
- sys.BADA = 6;
+ sys.IPAD = 5;
/**
* @memberof cc.sys
* @name BLACKBERRY
@@ -1460,15 +1637,7 @@ cc._initSys = function (config, CONFIG_KEY) {
* @default
* @type {Number}
*/
- sys.BLACKBERRY = 7;
- /**
- * @memberof cc.sys
- * @name MACOS
- * @constant
- * @default
- * @type {Number}
- */
- sys.MACOS = 8;
+ sys.BLACKBERRY = 6;
/**
* @memberof cc.sys
* @name NACL
@@ -1476,7 +1645,7 @@ cc._initSys = function (config, CONFIG_KEY) {
* @default
* @type {Number}
*/
- sys.NACL = 9;
+ sys.NACL = 7;
/**
* @memberof cc.sys
* @name EMSCRIPTEN
@@ -1484,7 +1653,7 @@ cc._initSys = function (config, CONFIG_KEY) {
* @default
* @type {Number}
*/
- sys.EMSCRIPTEN = 10;
+ sys.EMSCRIPTEN = 8;
/**
* @memberof cc.sys
* @name TIZEN
@@ -1492,15 +1661,15 @@ cc._initSys = function (config, CONFIG_KEY) {
* @default
* @type {Number}
*/
- sys.TIZEN = 11;
+ sys.TIZEN = 9;
/**
* @memberof cc.sys
- * @name QT5
+ * @name WINRT
* @constant
* @default
* @type {Number}
*/
- sys.QT5 = 12;
+ sys.WINRT = 10;
/**
* @memberof cc.sys
* @name WP8
@@ -1508,15 +1677,7 @@ cc._initSys = function (config, CONFIG_KEY) {
* @default
* @type {Number}
*/
- sys.WP8 = 13;
- /**
- * @memberof cc.sys
- * @name WINRT
- * @constant
- * @default
- * @type {Number}
- */
- sys.WINRT = 14;
+ sys.WP8 = 11;
/**
* @memberof cc.sys
* @name MOBILE_BROWSER
@@ -1537,6 +1698,7 @@ cc._initSys = function (config, CONFIG_KEY) {
sys.BROWSER_TYPE_WECHAT = "wechat";
sys.BROWSER_TYPE_ANDROID = "androidbrowser";
sys.BROWSER_TYPE_IE = "ie";
+ sys.BROWSER_TYPE_QQ_APP = "qq"; // QQ App
sys.BROWSER_TYPE_QQ = "qqbrowser";
sys.BROWSER_TYPE_MOBILE_QQ = "mqqbrowser";
sys.BROWSER_TYPE_UC = "ucbrowser";
@@ -1572,7 +1734,7 @@ cc._initSys = function (config, CONFIG_KEY) {
* @name isMobile
* @type {Boolean}
*/
- sys.isMobile = ua.indexOf('mobile') !== -1 || ua.indexOf('android') !== -1;
+ sys.isMobile = /mobile|android|iphone|ipad/.test(ua);
/**
* Indicate the running platform
@@ -1594,31 +1756,26 @@ cc._initSys = function (config, CONFIG_KEY) {
*/
sys.language = currLanguage;
- var browserType = sys.BROWSER_TYPE_UNKNOWN;
- var browserTypes = ua.match(/sogou|qzone|liebao|micromessenger|qqbrowser|ucbrowser|360 aphone|360browser|baiduboxapp|baidubrowser|maxthon|trident|oupeng|opera|miuibrowser|firefox/i)
- || ua.match(/chrome|safari/i);
- if (browserTypes && browserTypes.length > 0) {
- browserType = browserTypes[0];
- if (browserType === 'micromessenger') {
- browserType = sys.BROWSER_TYPE_WECHAT;
- } else if (browserType === "safari" && (ua.match(/android.*applewebkit/)))
- browserType = sys.BROWSER_TYPE_ANDROID;
- else if (browserType === "trident") browserType = sys.BROWSER_TYPE_IE;
- else if (browserType === "360 aphone") browserType = sys.BROWSER_TYPE_360;
- }else if(ua.indexOf("iphone") && ua.indexOf("mobile")){
- browserType = "safari";
+ // Get the os of system
+ var isAndroid = false, iOS = false, osVersion = '', osMainVersion = 0;
+ var uaResult = /android (\d+(?:\.\d+)+)/i.exec(ua) || /android (\d+(?:\.\d+)+)/i.exec(nav.platform);
+ if (uaResult) {
+ isAndroid = true;
+ osVersion = uaResult[1] || '';
+ osMainVersion = parseInt(osVersion) || 0;
+ }
+ uaResult = /(iPad|iPhone|iPod).*OS ((\d+_?){2,3})/i.exec(ua);
+ if (uaResult) {
+ iOS = true;
+ osVersion = uaResult[2] || '';
+ osMainVersion = parseInt(osVersion) || 0;
+ }
+ else if (/(iPhone|iPad|iPod)/.exec(nav.platform)) {
+ iOS = true;
+ osVersion = '';
+ osMainVersion = 0;
}
- /**
- * Indicate the running browser type
- * @memberof cc.sys
- * @name browserType
- * @type {String}
- */
- sys.browserType = browserType;
- // Get the os of system
- var iOS = ( ua.match(/(iPad|iPhone|iPod)/i) ? true : false );
- var isAndroid = ua.match(/android/i) || nav.platform.match(/android/i) ? true : false;
var osName = sys.OS_UNKNOWN;
if (nav.appVersion.indexOf("Win") !== -1) osName = sys.OS_WINDOWS;
else if (iOS) osName = sys.OS_IOS;
@@ -1634,78 +1791,116 @@ cc._initSys = function (config, CONFIG_KEY) {
* @type {String}
*/
sys.os = osName;
+ /**
+ * Indicate the running os version string
+ * @memberof cc.sys
+ * @name osVersion
+ * @type {String}
+ */
+ sys.osVersion = osVersion;
+ /**
+ * Indicate the running os main version number
+ * @memberof cc.sys
+ * @name osMainVersion
+ * @type {Number}
+ */
+ sys.osMainVersion = osMainVersion;
- var multipleAudioWhiteList = [
- sys.BROWSER_TYPE_BAIDU, sys.BROWSER_TYPE_OPERA, sys.BROWSER_TYPE_FIREFOX, sys.BROWSER_TYPE_CHROME, sys.BROWSER_TYPE_BAIDU_APP,
- sys.BROWSER_TYPE_SAFARI, sys.BROWSER_TYPE_UC, sys.BROWSER_TYPE_QQ, sys.BROWSER_TYPE_MOBILE_QQ, sys.BROWSER_TYPE_IE
- ];
+ /**
+ * Indicate the running browser type
+ * @memberof cc.sys
+ * @name browserType
+ * @type {String}
+ */
+ sys.browserType = sys.BROWSER_TYPE_UNKNOWN;
+ /* Determine the browser type */
+ (function(){
+ var typeReg1 = /micromessenger|mqqbrowser|sogou|qzone|liebao|ucbrowser|360 aphone|360browser|baiduboxapp|baidubrowser|maxthon|mxbrowser|trident|miuibrowser/i;
+ var typeReg2 = /qqbrowser|qq|chrome|safari|firefox|opr|oupeng|opera/i;
+ var browserTypes = typeReg1.exec(ua);
+ if(!browserTypes) browserTypes = typeReg2.exec(ua);
+ var browserType = browserTypes ? browserTypes[0] : sys.BROWSER_TYPE_UNKNOWN;
+ if (browserType === 'micromessenger')
+ browserType = sys.BROWSER_TYPE_WECHAT;
+ else if (browserType === "safari" && isAndroid)
+ browserType = sys.BROWSER_TYPE_ANDROID;
+ else if (browserType === "trident")
+ browserType = sys.BROWSER_TYPE_IE;
+ else if (browserType === "360 aphone")
+ browserType = sys.BROWSER_TYPE_360;
+ else if (browserType === "mxbrowser")
+ browserType = sys.BROWSER_TYPE_MAXTHON;
+ else if (browserType === "opr")
+ browserType = sys.BROWSER_TYPE_OPERA;
- sys._supportMultipleAudio = multipleAudioWhiteList.indexOf(sys.browserType) > -1;
+ sys.browserType = browserType;
+ })();
+ /**
+ * Indicate the running browser version
+ * @memberof cc.sys
+ * @name browserVersion
+ * @type {String}
+ */
+ sys.browserVersion = "";
+ /* Determine the browser version number */
+ (function(){
+ var versionReg1 = /(mqqbrowser|micromessenger|sogou|qzone|liebao|maxthon|mxbrowser|baidu)(mobile)?(browser)?\/?([\d.]+)/i;
+ var versionReg2 = /(msie |rv:|firefox|chrome|ucbrowser|qq|oupeng|opera|opr|safari|miui)(mobile)?(browser)?\/?([\d.]+)/i;
+ var tmp = ua.match(versionReg1);
+ if(!tmp) tmp = ua.match(versionReg2);
+ sys.browserVersion = tmp ? tmp[4] : "";
+ })();
- //++++++++++++++++++something about cc._renderTYpe and cc._supportRender begin++++++++++++++++++++++++++++
+ var w = window.innerWidth || document.documentElement.clientWidth;
+ var h = window.innerHeight || document.documentElement.clientHeight;
+ var ratio = window.devicePixelRatio || 1;
- (function(sys, config){
- var userRenderMode = config[CONFIG_KEY.renderMode] - 0;
- if(isNaN(userRenderMode) || userRenderMode > 2 || userRenderMode < 0)
- userRenderMode = 0;
- var shieldOs = [sys.OS_ANDROID];
- var shieldBrowser = [];
- var tmpCanvas = cc.newElement("canvas");
- cc._renderType = cc._RENDER_TYPE_CANVAS;
- cc._supportRender = false;
+ /**
+ * Indicate the real pixel resolution of the whole game window
+ * @memberof cc.sys
+ * @name windowPixelResolution
+ * @type {Size}
+ */
+ sys.windowPixelResolution = {
+ width: ratio * w,
+ height: ratio * h
+ };
- var supportWebGL = win.WebGLRenderingContext;
+ sys._checkWebGLRenderMode = function () {
+ if (cc._renderType !== cc.game.RENDER_TYPE_WEBGL)
+ throw new Error("This feature supports WebGL render mode only.");
+ };
- if(userRenderMode === 2 || (userRenderMode === 0 && supportWebGL && shieldOs.indexOf(sys.os) === -1 && shieldBrowser.indexOf(sys.browserType) === -1))
- try{
- var context = cc.create3DContext(tmpCanvas, {'stencil': true, 'preserveDrawingBuffer': true });
- if(context){
- cc._renderType = cc._RENDER_TYPE_WEBGL;
- cc._supportRender = true;
- }
- }catch(e){}
-
- if(userRenderMode === 1 || (userRenderMode === 0 && cc._supportRender === false))
- try {
- tmpCanvas.getContext("2d");
- cc._renderType = cc._RENDER_TYPE_CANVAS;
- cc._supportRender = true;
- } catch (e) {}
- })(sys, config);
-
- sys._canUseCanvasNewBlendModes = function(){
- var canvas = document.createElement('canvas');
+ //Whether or not the Canvas BlendModes are supported.
+ sys._supportCanvasNewBlendModes = (function(){
+ var canvas = _tmpCanvas1;
canvas.width = 1;
canvas.height = 1;
var context = canvas.getContext('2d');
context.fillStyle = '#000';
- context.fillRect(0,0,1,1);
+ context.fillRect(0, 0, 1, 1);
context.globalCompositeOperation = 'multiply';
- var canvas2 = document.createElement('canvas');
+ var canvas2 = _tmpCanvas2;
canvas2.width = 1;
canvas2.height = 1;
var context2 = canvas2.getContext('2d');
context2.fillStyle = '#fff';
- context2.fillRect(0,0,1,1);
-
+ context2.fillRect(0, 0, 1, 1);
context.drawImage(canvas2, 0, 0, 1, 1);
- return context.getImageData(0,0,1,1).data[0] === 0;
- };
-
- //Whether or not the Canvas BlendModes are supported.
- sys._supportCanvasNewBlendModes = sys._canUseCanvasNewBlendModes();
+ return context.getImageData(0, 0, 1, 1).data[0] === 0;
+ })();
- //++++++++++++++++++something about cc._renderType and cc._supportRender end++++++++++++++++++++++++++++++
+ // Adjust mobile css settings
+ if (cc.sys.isMobile) {
+ var fontStyle = document.createElement("style");
+ fontStyle.type = "text/css";
+ document.body.appendChild(fontStyle);
- // check if browser supports Web Audio
- // check Web Audio's context
- try {
- sys._supportWebAudio = !!(win.AudioContext || win.webkitAudioContext || win.mozAudioContext);
- } catch (e) {
- sys._supportWebAudio = false;
+ fontStyle.textContent = "body,canvas,div{ -moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;"
+ + "-webkit-tap-highlight-color:rgba(0,0,0,0);}";
}
/**
@@ -1720,16 +1915,84 @@ cc._initSys = function (config, CONFIG_KEY) {
localStorage.removeItem("storage");
localStorage = null;
} catch (e) {
- if (e.name === "SECURITY_ERR" || e.name === "QuotaExceededError") {
+ var warn = function () {
cc.warn("Warning: localStorage isn't enabled. Please confirm browser cookie or privacy option");
- }
- sys.localStorage = function () {
+ };
+ sys.localStorage = {
+ getItem : warn,
+ setItem : warn,
+ removeItem : warn,
+ clear : warn
};
}
- var capabilities = sys.capabilities = {"canvas": true};
- if (cc._renderType === cc._RENDER_TYPE_WEBGL)
- capabilities["opengl"] = true;
+ var _supportCanvas = !!_tmpCanvas1.getContext("2d");
+ var _supportWebGL = false;
+ if (win.WebGLRenderingContext) {
+ var tmpCanvas = document.createElement("CANVAS");
+ try{
+ var context = cc.create3DContext(tmpCanvas);
+ if (context) {
+ _supportWebGL = true;
+ }
+
+ if (_supportWebGL && sys.os === sys.OS_IOS && sys.osMainVersion === 9) {
+ // Not activating WebGL in iOS 9 UIWebView because it may crash when entering background
+ if (!window.indexedDB) {
+ _supportWebGL = false;
+ }
+ }
+
+ if (_supportWebGL && sys.os === sys.OS_ANDROID) {
+ var browserVer = parseFloat(sys.browserVersion);
+ switch (sys.browserType) {
+ case sys.BROWSER_TYPE_MOBILE_QQ:
+ case sys.BROWSER_TYPE_BAIDU:
+ case sys.BROWSER_TYPE_BAIDU_APP:
+ // QQ & Baidu Brwoser 6.2+ (using blink kernel)
+ if (browserVer >= 6.2) {
+ _supportWebGL = true;
+ }
+ else {
+ _supportWebGL = false;
+ }
+ break;
+ case sys.BROWSER_TYPE_CHROME:
+ // Chrome on android supports WebGL from v.30
+ if(browserVer >= 30.0) {
+ _supportWebGL = true;
+ } else {
+ _supportWebGL = false;
+ }
+ break;
+ case sys.BROWSER_TYPE_ANDROID:
+ // Android 5+ default browser
+ if (sys.osMainVersion && sys.osMainVersion >= 5) {
+ _supportWebGL = true;
+ }
+ break;
+ case sys.BROWSER_TYPE_UNKNOWN:
+ case sys.BROWSER_TYPE_360:
+ case sys.BROWSER_TYPE_MIUI:
+ case sys.BROWSER_TYPE_UC:
+ _supportWebGL = false;
+ }
+ }
+ }
+ catch (e) {}
+ tmpCanvas = null;
+ }
+
+ /**
+ * The capabilities of the current platform
+ * @memberof cc.sys
+ * @name capabilities
+ * @type {Object}
+ */
+ var capabilities = sys.capabilities = {
+ "canvas": _supportCanvas,
+ "opengl": _supportWebGL
+ };
if (docEle['ontouchstart'] !== undefined || doc['ontouchstart'] !== undefined || nav.msPointerEnabled)
capabilities["touches"] = true;
if (docEle['onmouseup'] !== undefined)
@@ -1807,11 +2070,14 @@ cc._initSys = function (config, CONFIG_KEY) {
str += "isMobile : " + self.isMobile + "\r\n";
str += "language : " + self.language + "\r\n";
str += "browserType : " + self.browserType + "\r\n";
+ str += "browserVersion : " + self.browserVersion + "\r\n";
str += "capabilities : " + JSON.stringify(self.capabilities) + "\r\n";
str += "os : " + self.os + "\r\n";
+ str += "osVersion : " + self.osVersion + "\r\n";
str += "platform : " + self.platform + "\r\n";
+ str += "Using " + (cc._renderType === cc.game.RENDER_TYPE_WEBGL ? "WEBGL" : "CANVAS") + " renderer." + "\r\n";
cc.log(str);
- }
+ };
/**
* Open a url in browser
@@ -1821,264 +2087,307 @@ cc._initSys = function (config, CONFIG_KEY) {
*/
sys.openURL = function(url){
window.open(url);
- }
-};
-
-//+++++++++++++++++++++++++something about sys end+++++++++++++++++++++++++++++
-
-//+++++++++++++++++++++++++something about CCGame begin+++++++++++++++++++++++++++
+ };
-/**
- * Device oriented vertically, home button on the bottom
- * @constant
- * @type {Number}
- */
-cc.ORIENTATION_PORTRAIT = 0;
+ /**
+ * Get the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
+ * @memberof cc.sys
+ * @name now
+ * @return {Number}
+ */
+ sys.now = function () {
+ if (Date.now) {
+ return Date.now();
+ }
+ else {
+ return +(new Date);
+ }
+ };
+};
+_initSys();
-/**
- * Device oriented vertically, home button on the top
- * @constant
- * @type {Number}
- */
-cc.ORIENTATION_PORTRAIT_UPSIDE_DOWN = 1;
+_tmpCanvas1 = null;
+_tmpCanvas2 = null;
-/**
- * Device oriented horizontally, home button on the right
- * @constant
- * @type {Number}
- */
-cc.ORIENTATION_LANDSCAPE_LEFT = 2;
+//to make sure the cc.log, cc.warn, cc.error and cc.assert would not throw error before init by debugger mode.
+cc.log = cc.warn = cc.error = cc.assert = function () {
+};
-/**
- * Device oriented horizontally, home button on the left
- * @constant
- * @type {Number}
- */
-cc.ORIENTATION_LANDSCAPE_RIGHT = 3;
+var _config = null,
+ //cache for js and module that has added into jsList to be loaded.
+ _jsAddedCache = {},
+ _engineInitCalled = false,
+ _engineLoadedCallback = null;
-/**
- * drawing primitive of game engine
- * @type {cc.DrawingPrimitive}
- */
-cc._drawingUtil = null;
+cc._engineLoaded = false;
-/**
- * main Canvas 2D/3D Context of game engine
- * @type {CanvasRenderingContext2D|WebGLRenderingContext}
- */
-cc._renderContext = null;
+function _determineRenderType(config) {
+ var CONFIG_KEY = cc.game.CONFIG_KEY,
+ userRenderMode = parseInt(config[CONFIG_KEY.renderMode]) || 0;
-/**
- * main Canvas of game engine
- * @type {HTMLCanvasElement}
- */
-cc._canvas = null;
+ // Adjust RenderType
+ if (isNaN(userRenderMode) || userRenderMode > 2 || userRenderMode < 0)
+ config[CONFIG_KEY.renderMode] = 0;
-/**
- * This Div element contain all game canvas
- * @type {HTMLDivElement}
- */
-cc._gameDiv = null;
+ // Determine RenderType
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc._supportRender = false;
-cc._rendererInitialized = false;
-/**
- *
- * setup game main canvas,renderContext,gameDiv and drawingUtil with argument
- *
- * can receive follow type of arguemnt:
- * - empty: create a canvas append to document's body, and setup other option
- * - string: search the element by document.getElementById(),
- * if this element is HTMLCanvasElement, set this element as main canvas of engine, and set it's ParentNode as cc._gameDiv.
- * if this element is HTMLDivElement, set it's ParentNode to cc._gameDiv, and create a canvas as main canvas of engine.
- *
- * @function
- * @example
- * //setup with null
- * cc._setup();
- *
- * // setup with HTMLCanvasElement, gameCanvas is Canvas element
- * // declare like this:
- * cc._setup("gameCanvas");
- *
- * //setup with HTMLDivElement, gameDiv is Div element
- * // declare like this:
- * cc._setup("Cocos2dGameContainer");
- */
-cc._setupCalled = false;
-cc._setup = function (el, width, height) {
- // Avoid setup to be called twice.
- if (cc._setupCalled) return;
- else cc._setupCalled = true;
- var win = window;
- var element = cc.$(el) || cc.$('#' + el);
- var localCanvas, localContainer, localConStyle;
-
- cc.game._setAnimFrame();
-
- if (element.tagName === "CANVAS") {
- width = width || element.width;
- height = height || element.height;
-
- //it is already a canvas, we wrap it around with a div
- localContainer = cc.container = cc.newElement("DIV");
- localCanvas = cc._canvas = element;
- localCanvas.parentNode.insertBefore(localContainer, localCanvas);
- localCanvas.appendTo(localContainer);
- localContainer.setAttribute('id', 'Cocos2dGameContainer');
- } else {//we must make a new canvas and place into this element
- if (element.tagName !== "DIV") {
- cc.log("Warning: target element is not a DIV or CANVAS");
+ if (userRenderMode === 0) {
+ if (cc.sys.capabilities["opengl"]) {
+ cc._renderType = cc.game.RENDER_TYPE_WEBGL;
+ cc._supportRender = true;
}
- width = width || element.clientWidth;
- height = height || element.clientHeight;
- localContainer = cc.container = element;
- localCanvas = cc._canvas = cc.$(cc.newElement("CANVAS"));
- element.appendChild(localCanvas);
+ else if (cc.sys.capabilities["canvas"]) {
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc._supportRender = true;
+ }
+ }
+ else if (userRenderMode === 1 && cc.sys.capabilities["canvas"]) {
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc._supportRender = true;
+ }
+ else if (userRenderMode === 2 && cc.sys.capabilities["opengl"]) {
+ cc._renderType = cc.game.RENDER_TYPE_WEBGL;
+ cc._supportRender = true;
+ }
+}
+
+function _getJsListOfModule(moduleMap, moduleName, dir) {
+ if (_jsAddedCache[moduleName]) return null;
+ dir = dir || "";
+ var jsList = [];
+ var tempList = moduleMap[moduleName];
+ if (!tempList) throw new Error("can not find module [" + moduleName + "]");
+ var ccPath = cc.path;
+ for (var i = 0, li = tempList.length; i < li; i++) {
+ var item = tempList[i];
+ if (_jsAddedCache[item]) continue;
+ var extname = ccPath.extname(item);
+ if (!extname) {
+ var arr = _getJsListOfModule(moduleMap, item, dir);
+ if (arr) jsList = jsList.concat(arr);
+ } else if (extname.toLowerCase() === ".js") jsList.push(ccPath.join(dir, item));
+ _jsAddedCache[item] = 1;
}
+ return jsList;
+}
+
+function _afterEngineLoaded(config) {
+ if (cc._initDebugSetting)
+ cc._initDebugSetting(config[cc.game.CONFIG_KEY.debugMode]);
+ cc._engineLoaded = true;
+ console.log(cc.ENGINE_VERSION);
+ if (_engineLoadedCallback) _engineLoadedCallback();
+}
+
+function _load(config) {
+ var self = this;
+ var CONFIG_KEY = cc.game.CONFIG_KEY, engineDir = config[CONFIG_KEY.engineDir], loader = cc.loader;
- localCanvas.addClass("gameCanvas");
- localCanvas.setAttribute("width", width || 480);
- localCanvas.setAttribute("height", height || 320);
- localCanvas.setAttribute("tabindex", 99);
- localCanvas.style.outline = "none";
- localConStyle = localContainer.style;
- localConStyle.width = (width || 480) + "px";
- localConStyle.height = (height || 320) + "px";
- localConStyle.margin = "0 auto";
-
- localConStyle.position = 'relative';
- localConStyle.overflow = 'hidden';
- localContainer.top = '100%';
-
- if (cc._renderType === cc._RENDER_TYPE_WEBGL)
- cc._renderContext = cc.webglContext = cc.create3DContext(localCanvas, {
- 'stencil': true,
- 'preserveDrawingBuffer': true,
- 'antialias': !cc.sys.isMobile,
- 'alpha': false
- });
- if (cc._renderContext) {
- win.gl = cc._renderContext; // global variable declared in CCMacro.js
- cc._drawingUtil = new cc.DrawingPrimitiveWebGL(cc._renderContext);
- cc._rendererInitialized = true;
- cc.textureCache._initializingRenderer();
- cc.shaderCache._init();
+ if (cc.Class) {
+ // Single file loaded
+ _afterEngineLoaded(config);
} else {
- cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d"));
- cc._drawingUtil = cc.DrawingPrimitiveCanvas ? new cc.DrawingPrimitiveCanvas(cc._renderContext) : null;
+ // Load cocos modules
+ var ccModulesPath = cc.path.join(engineDir, "moduleConfig.json");
+ loader.loadJson(ccModulesPath, function (err, modulesJson) {
+ if (err) throw new Error(err);
+ var modules = config["modules"] || [];
+ var moduleMap = modulesJson["module"];
+ var jsList = [];
+ if (cc.sys.capabilities["opengl"] && modules.indexOf("base4webgl") < 0) modules.splice(0, 0, "base4webgl");
+ else if (modules.indexOf("core") < 0) modules.splice(0, 0, "core");
+ for (var i = 0, li = modules.length; i < li; i++) {
+ var arr = _getJsListOfModule(moduleMap, modules[i], engineDir);
+ if (arr) jsList = jsList.concat(arr);
+ }
+ cc.loader.loadJsWithImg(jsList, function (err) {
+ if (err) throw err;
+ _afterEngineLoaded(config);
+ });
+ });
}
-
- cc._gameDiv = localContainer;
- cc.log(cc.ENGINE_VERSION);
- cc._setContextMenuEnable(false);
-
- if (cc.sys.isMobile) {
- var fontStyle = cc.newElement("style");
- fontStyle.type = "text/css";
- document.body.appendChild(fontStyle);
-
- fontStyle.textContent = "body,canvas,div{ -moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;"
- + "-webkit-tap-highlight-color:rgba(0,0,0,0);}";
+}
+
+function _windowLoaded() {
+ this.removeEventListener('load', _windowLoaded, false);
+ _load(cc.game.config);
+}
+
+cc.initEngine = function (config, cb) {
+ if (_engineInitCalled) {
+ var previousCallback = _engineLoadedCallback;
+ _engineLoadedCallback = function () {
+ previousCallback && previousCallback();
+ cb && cb();
+ }
+ return;
}
- // Init singletons
+ _engineLoadedCallback = cb;
- /**
- * @type {cc.EGLView}
- * @name cc.view
- * cc.view is the shared view object.
- */
- cc.view = cc.EGLView._getInstance();
- // register system events
- cc.inputManager.registerSystemEvent(cc._canvas);
-
- /**
- * @type {cc.Director}
- * @name cc.director
- */
- cc.director = cc.Director._getInstance();
- if (cc.director.setOpenGLView)
- cc.director.setOpenGLView(cc.view);
- /**
- * @type {cc.Size}
- * @name cc.winSize
- * cc.winSize is the alias object for the size of the current game window.
- */
- cc.winSize = cc.director.getWinSize();
+ // Config uninitialized and given, initialize with it
+ if (!cc.game.config && config) {
+ cc.game.config = config;
+ }
+ // No config given and no config set before, load it
+ else if (!cc.game.config) {
+ cc.game._loadConfig();
+ }
+ config = cc.game.config;
- // Parsers
- cc.saxParser = new cc.SAXParser();
- /**
- * @type {cc.PlistParser}
- * @name cc.plistParser
- * A Plist Parser
- */
- cc.plistParser = new cc.PlistParser();
-};
+ _determineRenderType(config);
-cc._checkWebGLRenderMode = function () {
- if (cc._renderType !== cc._RENDER_TYPE_WEBGL)
- throw "This feature supports WebGL render mode only.";
+ document.body ? _load(config) : cc._addEventListener(window, 'load', _windowLoaded, false);
+ _engineInitCalled = true;
};
-cc._isContextMenuEnable = false;
-/**
- * enable/disable contextMenu for Canvas
- * @param {Boolean} enabled
- */
-cc._setContextMenuEnable = function (enabled) {
- cc._isContextMenuEnable = enabled;
- cc._canvas.oncontextmenu = function () {
- if (!cc._isContextMenuEnable) return false;
- };
-};
+})();
+//+++++++++++++++++++++++++Engine initialization function end+++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++something about CCGame begin+++++++++++++++++++++++++++
/**
* An object to boot the game.
* @class
* @name cc.game
+ *
*/
cc.game = /** @lends cc.game# */{
+ /**
+ * Debug mode: No debugging. {@static}
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_NONE: 0,
+ /**
+ * Debug mode: Info, warning, error to console.
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_INFO: 1,
+ /**
+ * Debug mode: Warning, error to console.
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_WARN: 2,
+ /**
+ * Debug mode: Error to console.
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_ERROR: 3,
+ /**
+ * Debug mode: Info, warning, error to web page.
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_INFO_FOR_WEB_PAGE: 4,
+ /**
+ * Debug mode: Warning, error to web page.
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_WARN_FOR_WEB_PAGE: 5,
+ /**
+ * Debug mode: Error to web page.
+ * @const {Number}
+ * @static
+ */
DEBUG_MODE_ERROR_FOR_WEB_PAGE: 6,
+ /**
+ * Event that is fired when the game is hidden.
+ * @constant {String}
+ */
EVENT_HIDE: "game_on_hide",
+ /**
+ * Event that is fired when the game is shown.
+ * @constant {String}
+ */
EVENT_SHOW: "game_on_show",
+ /**
+ * Event that is fired when the game is resized.
+ * @constant {String}
+ */
+ EVENT_RESIZE: "game_on_resize",
+ /**
+ * Event that is fired when the renderer is done being initialized.
+ * @constant {String}
+ */
+ EVENT_RENDERER_INITED: "renderer_inited",
+
+ /** @constant {Number} */
+ RENDER_TYPE_CANVAS: 0,
+ /** @constant {Number} */
+ RENDER_TYPE_WEBGL: 1,
+ /** @constant {Number} */
+ RENDER_TYPE_OPENGL: 2,
+
_eventHide: null,
_eventShow: null,
- _onBeforeStartArr: [],
/**
- * Key of config
+ * Keys found in project.json.
+ *
* @constant
* @type {Object}
+ *
+ * @prop {String} engineDir - In debug mode, if you use the whole engine to develop your game, you should specify its relative path with "engineDir".
+ * @prop {String} modules - Defines which modules you will need in your game, it's useful only on web
+ * @prop {String} debugMode - Debug mode, see DEBUG_MODE_XXX constant definitions.
+ * @prop {String} exposeClassName - Expose class name to chrome debug tools
+ * @prop {String} showFPS - Left bottom corner fps information will show when "showFPS" equals true, otherwise it will be hide.
+ * @prop {String} frameRate - Sets the wanted frame rate for your game, but the real fps depends on your game implementation and the running environment.
+ * @prop {String} id - Sets the id of your canvas element on the web page, it's useful only on web.
+ * @prop {String} renderMode - Sets the renderer type, only useful on web, 0: Automatic, 1: Canvas, 2: WebGL
+ * @prop {String} jsList - Sets the list of js files in your game.
*/
CONFIG_KEY: {
+ width: "width",
+ height: "height",
engineDir: "engineDir",
- dependencies: "dependencies",
+ modules: "modules",
debugMode: "debugMode",
+ exposeClassName: "exposeClassName",
showFPS: "showFPS",
frameRate: "frameRate",
id: "id",
renderMode: "renderMode",
- jsList: "jsList",
- classReleaseMode: "classReleaseMode"
+ jsList: "jsList"
},
+ // states
+ _paused: true,//whether the game is paused
+ _configLoaded: false,//whether config loaded
_prepareCalled: false,//whether the prepare function has been called
_prepared: false,//whether the engine has prepared
- _paused: true,//whether the game is paused
+ _rendererInitialized: false,
+
+ _renderContext: null,
_intervalId: null,//interval target of main
-
+
_lastTime: null,
_frameTime: null,
+ /**
+ * The outer frame of the game canvas, parent of cc.container
+ * @type {Object}
+ */
+ frame: null,
+ /**
+ * The container of game canvas, equals to cc.container
+ * @type {Object}
+ */
+ container: null,
+ /**
+ * The canvas of the game, equals to cc._canvas
+ * @type {Object}
+ */
+ canvas: null,
+
/**
* Config of game
* @type {Object}
@@ -2087,16 +2396,19 @@ cc.game = /** @lends cc.game# */{
/**
* Callback when the scripts of engine have been load.
- * @type {Function}
+ * @type {Function|null}
*/
onStart: null,
/**
* Callback when game exits.
- * @type {Function}
+ * @type {Function|null}
*/
onStop: null,
+//@Public Methods
+
+// @Game play control
/**
* Set frameRate of game.
* @param frameRate
@@ -2106,14 +2418,192 @@ cc.game = /** @lends cc.game# */{
config[CONFIG_KEY.frameRate] = frameRate;
if (self._intervalId)
window.cancelAnimationFrame(self._intervalId);
+ self._intervalId = 0;
self._paused = true;
self._setAnimFrame();
self._runMainLoop();
},
+
+ /**
+ * Run the game frame by frame.
+ */
+ step: function () {
+ cc.director.mainLoop();
+ },
+
+ /**
+ * Pause the game.
+ */
+ pause: function () {
+ if (this._paused) return;
+ this._paused = true;
+ // Pause audio engine
+ if (cc.audioEngine) {
+ cc.audioEngine._pausePlaying();
+ }
+ // Pause main loop
+ if (this._intervalId)
+ window.cancelAnimationFrame(this._intervalId);
+ this._intervalId = 0;
+ },
+
+ /**
+ * Resume the game from pause.
+ */
+ resume: function () {
+ if (!this._paused) return;
+ this._paused = false;
+ // Resume audio engine
+ if (cc.audioEngine) {
+ cc.audioEngine._resumePlaying();
+ }
+ // Resume main loop
+ this._runMainLoop();
+ },
+
+ /**
+ * Check whether the game is paused.
+ */
+ isPaused: function () {
+ return this._paused;
+ },
+
+ /**
+ * Restart game.
+ */
+ restart: function () {
+ cc.director.popToSceneStackLevel(0);
+ // Clean up audio
+ cc.audioEngine && cc.audioEngine.end();
+
+ cc.game.onStart();
+ },
+
+ /**
+ * End game, it will close the game window
+ */
+ end: function () {
+ close();
+ },
+
+// @Game loading
+ /**
+ * Prepare game.
+ * @param cb
+ */
+ prepare: function (cb) {
+ var self = this,
+ config = self.config,
+ CONFIG_KEY = self.CONFIG_KEY;
+
+ // Config loaded
+ if (!this._configLoaded) {
+ this._loadConfig(function () {
+ self.prepare(cb);
+ });
+ return;
+ }
+
+ // Already prepared
+ if (this._prepared) {
+ if (cb) cb();
+ return;
+ }
+ // Prepare called, but not done yet
+ if (this._prepareCalled) {
+ return;
+ }
+ // Prepare never called and engine ready
+ if (cc._engineLoaded) {
+ this._prepareCalled = true;
+
+ this._initRenderer(config[CONFIG_KEY.width], config[CONFIG_KEY.height]);
+
+ /**
+ * cc.view is the shared view object.
+ * @type {cc.EGLView}
+ * @name cc.view
+ * @memberof cc
+ */
+ cc.view = cc.EGLView._getInstance();
+
+ /**
+ * @type {cc.Director}
+ * @name cc.director
+ * @memberof cc
+ */
+ cc.director = cc.Director._getInstance();
+ if (cc.director.setOpenGLView)
+ cc.director.setOpenGLView(cc.view);
+ /**
+ * cc.winSize is the alias object for the size of the current game window.
+ * @type {cc.Size}
+ * @name cc.winSize
+ * @memberof cc
+ */
+ cc.winSize = cc.director.getWinSize();
+
+ this._initEvents();
+
+ this._setAnimFrame();
+ this._runMainLoop();
+
+ // Load game scripts
+ var jsList = config[CONFIG_KEY.jsList];
+ if (jsList) {
+ cc.loader.loadJsWithImg(jsList, function (err) {
+ if (err) throw new Error(err);
+ self._prepared = true;
+ if (cb) cb();
+ });
+ }
+ else {
+ if (cb) cb();
+ }
+
+ return;
+ }
+
+ // Engine not loaded yet
+ cc.initEngine(this.config, function () {
+ self.prepare(cb);
+ });
+ },
+
+ /**
+ * Run game with configuration object and onStart function.
+ * @param {Object|Function} [config] Pass configuration object or onStart function
+ * @param {onStart} [onStart] onStart function to be executed after game initialized
+ */
+ run: function (config, onStart) {
+ if (typeof config === 'function') {
+ cc.game.onStart = config;
+ }
+ else {
+ if (config) {
+ if (typeof config === 'string') {
+ if (!cc.game.config) this._loadConfig();
+ cc.game.config[cc.game.CONFIG_KEY.id] = config;
+ } else {
+ cc.game.config = config;
+ }
+ }
+ if (typeof onStart === 'function') {
+ cc.game.onStart = onStart;
+ }
+ }
+
+ this.prepare(cc.game.onStart && cc.game.onStart.bind(cc.game));
+ },
+
+//@Private Methods
+
+// @Time ticker section
_setAnimFrame: function () {
this._lastTime = new Date();
- this._frameTime = 1000 / cc.game.config[cc.game.CONFIG_KEY.frameRate];
- if((cc.sys.os === cc.sys.OS_IOS && cc.sys.browserType === cc.sys.BROWSER_TYPE_WECHAT) || cc.game.config[cc.game.CONFIG_KEY.frameRate] !== 60) {
+ var frameRate = cc.game.config[cc.game.CONFIG_KEY.frameRate];
+ this._frameTime = 1000 / frameRate;
+ if (frameRate !== 60 && frameRate !== 30) {
window.requestAnimFrame = this._stTime;
window.cancelAnimationFrame = this._ctTime;
}
@@ -2137,7 +2627,7 @@ cc.game = /** @lends cc.game# */{
this._ctTime;
}
},
- _stTime: function(callback){
+ _stTime: function (callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, cc.game._frameTime - (currTime - cc.game._lastTime));
var id = window.setTimeout(function() { callback(); },
@@ -2145,188 +2635,244 @@ cc.game = /** @lends cc.game# */{
cc.game._lastTime = currTime + timeToCall;
return id;
},
- _ctTime: function(id){
+ _ctTime: function (id) {
window.clearTimeout(id);
},
//Run game.
_runMainLoop: function () {
var self = this, callback, config = self.config, CONFIG_KEY = self.CONFIG_KEY,
- director = cc.director;
+ director = cc.director,
+ skip = true, frameRate = config[CONFIG_KEY.frameRate];
director.setDisplayStats(config[CONFIG_KEY.showFPS]);
callback = function () {
if (!self._paused) {
+ if (frameRate === 30) {
+ if (skip = !skip) {
+ self._intervalId = window.requestAnimFrame(callback);
+ return;
+ }
+ }
+
director.mainLoop();
- if(self._intervalId)
- window.cancelAnimationFrame(self._intervalId);
self._intervalId = window.requestAnimFrame(callback);
}
};
- window.requestAnimFrame(callback);
+ self._intervalId = window.requestAnimFrame(callback);
self._paused = false;
},
- /**
- * Restart game.
- */
- restart: function () {
- cc.director.popToSceneStackLevel(0);
- // Clean up audio
- cc.audioEngine && cc.audioEngine.end();
-
- cc.game.onStart();
- },
-
- /**
- * Run game.
- */
- run: function (id) {
- var self = this;
- var _run = function () {
- if (id) {
- self.config[self.CONFIG_KEY.id] = id;
+// @Game loading section
+ _loadConfig: function (cb) {
+ // Load config
+ var config = this.config || document["ccConfig"];
+ // Already loaded or Load from document.ccConfig
+ if (config) {
+ this._initConfig(config);
+ cb && cb();
+ }
+ // Load from project.json
+ else {
+ var cocos_script = document.getElementsByTagName('script');
+ for (var i = 0; i < cocos_script.length; i++) {
+ var _t = cocos_script[i].getAttribute('cocos');
+ if (_t === '' || _t) {
+ break;
+ }
}
- if (!self._prepareCalled) {
- self.prepare(function () {
- self._prepared = true;
- });
+ var self = this;
+ var loaded = function (err, txt) {
+ var data = JSON.parse(txt);
+ self._initConfig(data);
+ cb && cb();
+ };
+ var _src, txt, _resPath;
+ if (i < cocos_script.length) {
+ _src = cocos_script[i].src;
+ if (_src) {
+ _resPath = /(.*)\//.exec(_src)[0];
+ cc.loader.resPath = _resPath;
+ _src = cc.path.join(_resPath, 'project.json');
+ }
+ cc.loader.loadTxt(_src, loaded);
}
- if (cc._supportRender) {
- self._checkPrepare = setInterval(function () {
- if (self._prepared) {
- cc._setup(self.config[self.CONFIG_KEY.id]);
- self._runMainLoop();
- self._eventHide = self._eventHide || new cc.EventCustom(self.EVENT_HIDE);
- self._eventHide.setUserData(self);
- self._eventShow = self._eventShow || new cc.EventCustom(self.EVENT_SHOW);
- self._eventShow.setUserData(self);
- self.onStart();
- clearInterval(self._checkPrepare);
- }
- }, 10);
+ if (!txt) {
+ cc.loader.loadTxt("project.json", loaded);
}
- };
- document.body ?
- _run() :
- cc._addEventListener(window, 'load', function () {
- this.removeEventListener('load', arguments.callee, false);
- _run();
- }, false);
+ }
},
- _initConfig: function () {
- var self = this, CONFIG_KEY = self.CONFIG_KEY;
- var _init = function (cfg) {
- cfg[CONFIG_KEY.engineDir] = cfg[CONFIG_KEY.engineDir] || "frameworks/cocos2d-html5";
- if(cfg[CONFIG_KEY.debugMode] == null)
- cfg[CONFIG_KEY.debugMode] = 0;
- cfg[CONFIG_KEY.frameRate] = cfg[CONFIG_KEY.frameRate] || 60;
- if(cfg[CONFIG_KEY.renderMode] == null)
- cfg[CONFIG_KEY.renderMode] = 1;
- return cfg;
- };
- if (document["ccConfig"]) {
- self.config = _init(document["ccConfig"]);
+ _initConfig: function (config) {
+ var CONFIG_KEY = this.CONFIG_KEY,
+ modules = config[CONFIG_KEY.modules];
+
+ // Configs adjustment
+ config[CONFIG_KEY.showFPS] = typeof config[CONFIG_KEY.showFPS] === 'undefined' ? true : config[CONFIG_KEY.showFPS];
+ config[CONFIG_KEY.engineDir] = config[CONFIG_KEY.engineDir] || "frameworks/cocos2d-html5";
+ if (config[CONFIG_KEY.debugMode] == null)
+ config[CONFIG_KEY.debugMode] = 0;
+ config[CONFIG_KEY.exposeClassName] = !!config[CONFIG_KEY.exposeClassName];
+ config[CONFIG_KEY.frameRate] = config[CONFIG_KEY.frameRate] || 60;
+ if (config[CONFIG_KEY.renderMode] == null)
+ config[CONFIG_KEY.renderMode] = 0;
+ if (config[CONFIG_KEY.registerSystemEvent] == null)
+ config[CONFIG_KEY.registerSystemEvent] = true;
+
+ // Modules adjustment
+ if (modules && modules.indexOf("core") < 0) modules.splice(0, 0, "core");
+ modules && (config[CONFIG_KEY.modules] = modules);
+ this.config = config;
+ this._configLoaded = true;
+ },
+
+ _initRenderer: function (width, height) {
+ // Avoid setup to be called twice.
+ if (this._rendererInitialized) return;
+
+ if (!cc._supportRender) {
+ throw new Error("The renderer doesn't support the renderMode " + this.config[this.CONFIG_KEY.renderMode]);
+ }
+
+ var el = this.config[cc.game.CONFIG_KEY.id],
+ win = window,
+ element = cc.$(el) || cc.$('#' + el),
+ localCanvas, localContainer, localConStyle;
+
+ if (element.tagName === "CANVAS") {
+ width = width || element.width;
+ height = height || element.height;
+
+ //it is already a canvas, we wrap it around with a div
+ this.canvas = cc._canvas = localCanvas = element;
+ this.container = cc.container = localContainer = document.createElement("DIV");
+ if (localCanvas.parentNode)
+ localCanvas.parentNode.insertBefore(localContainer, localCanvas);
} else {
- try {
- var cocos_script = document.getElementsByTagName('script');
- for(var i=0;i -1) {
+ win.onfocus = function(){ onShow() };
+ }
+
+ if ("onpageshow" in window && "onpagehide" in window) {
+ win.addEventListener("pagehide", onHidden, false);
+ win.addEventListener("pageshow", onShow, false);
+ }
+
+ cc.eventManager.addCustomListener(cc.game.EVENT_HIDE, function () {
+ cc.game.pause();
+ });
+ cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () {
+ cc.game.resume();
+ });
}
};
-cc.game._initConfig();
//+++++++++++++++++++++++++something about CCGame end+++++++++++++++++++++++++++++
Function.prototype.bind = Function.prototype.bind || function (oThis) {
diff --git a/CCDebugger.js b/CCDebugger.js
index 767d5f520c..7acfc1cb0d 100644
--- a/CCDebugger.js
+++ b/CCDebugger.js
@@ -68,7 +68,8 @@ cc._LogInfos = {
Node_resumeSchedulerAndActions: "resumeSchedulerAndActions is deprecated, please use resume instead.",
Node_pauseSchedulerAndActions: "pauseSchedulerAndActions is deprecated, please use pause instead.",
Node__arrayMakeObjectsPerformSelector: "Unknown callback function",
- Node_reorderChild: "child must be non-null",
+ Node_reorderChild: "cc.Node.reorderChild(): child must be non-null",
+ Node_reorderChild_2: "cc.Node.reorderChild(): this child is not in children list",
Node_runAction: "cc.Node.runAction(): action must be non-null",
Node_schedule: "callback function must be non-null",
Node_schedule_2: "interval must be positive",
@@ -119,7 +120,6 @@ cc._LogInfos = {
animationCache__parseVersion2_2: "cocos2d: cc.AnimationCache: Animation '%s' refers to frame '%s' which is not currently in the cc.SpriteFrameCache. This frame will not be added to the animation.",
animationCache_addAnimations_2: "cc.AnimationCache.addAnimations(): Invalid texture file name",
- Sprite_reorderChild: "cc.Sprite.reorderChild(): this child is not in children list",
Sprite_ignoreAnchorPointForPosition: "cc.Sprite.ignoreAnchorPointForPosition(): it is invalid in cc.Sprite when using SpriteBatchNode",
Sprite_setDisplayFrameWithAnimationName: "cc.Sprite.setDisplayFrameWithAnimationName(): Frame not found",
Sprite_setDisplayFrameWithAnimationName_2: "cc.Sprite.setDisplayFrameWithAnimationName(): Invalid frame index",
@@ -130,7 +130,6 @@ cc._LogInfos = {
Sprite_initWithSpriteFrameName1: " is null, please check.",
Sprite_initWithFile: "cc.Sprite.initWithFile(): filename should be non-null",
Sprite_setDisplayFrameWithAnimationName_3: "cc.Sprite.setDisplayFrameWithAnimationName(): animationName must be non-null",
- Sprite_reorderChild_2: "cc.Sprite.reorderChild(): child should be non-null",
Sprite_addChild: "cc.Sprite.addChild(): cc.Sprite only supports cc.Sprites as children when using cc.SpriteBatchNode",
Sprite_addChild_2: "cc.Sprite.addChild(): cc.Sprite only supports a sprite using same texture as children when using cc.SpriteBatchNode",
Sprite_addChild_3: "cc.Sprite.addChild(): child should be non-null",
@@ -312,25 +311,23 @@ cc._initDebugSetting = function (mode) {
} else if(console && console.log.apply){//console is null when user doesn't open dev tool on IE9
//log to console
- cc.error = function(){
- return console.error.apply(console, arguments);
- };
- cc.assert = function (cond, msg) {
- if (!cond && msg) {
- for (var i = 2; i < arguments.length; i++)
- msg = msg.replace(/(%s)|(%d)/, cc._formatString(arguments[i]));
- throw msg;
- }
- };
- if(mode !== ccGame.DEBUG_MODE_ERROR)
- cc.warn = function(){
- return console.warn.apply(console, arguments);
- };
- if(mode === ccGame.DEBUG_MODE_INFO)
- cc.log = function(){
- return console.log.apply(console, arguments);
+ cc.error = Function.prototype.bind.call(console.error, console);
+ //If console.assert is not support user throw Error msg on wrong condition
+ if (console.assert) {
+ cc.assert = Function.prototype.bind.call(console.assert, console);
+ } else {
+ cc.assert = function (cond, msg) {
+ if (!cond && msg) {
+ for (var i = 2; i < arguments.length; i++)
+ msg = msg.replace(/(%s)|(%d)/, cc._formatString(arguments[i]));
+ throw new Error(msg);
+ }
};
+ }
+ if (mode !== ccGame.DEBUG_MODE_ERROR)
+ cc.warn = Function.prototype.bind.call(console.warn, console);
+ if (mode === ccGame.DEBUG_MODE_INFO)
+ cc.log = Function.prototype.bind.call(console.log, console);
}
};
-cc._initDebugSetting(cc.game.config[cc.game.CONFIG_KEY.debugMode]);
-//+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
\ No newline at end of file
+//+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 50b7feade2..9cfe4159f7 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,5 +1,123 @@
ChangeLog:
+Cocos2d-x v3.8 @ September.6 2015
+
+ [NEW] spine: Supported Spine runtime 2.3 (Both native and web engine)
+ [NEW] Animate: Added Animate's getCurrentFrameIndex function
+ [NEW] network: Upgrade SocketIO support to v1.x
+
+ [REFINE] web: Avoid re-bake the content when the parent node's position get changed
+ [REFINE] web: Added GameNodeObjectData and GameLayerObjectData in JSON parser
+ [REFINE] web: Updated skeleton animation to the latest version
+ [REFINE] web: Optimized resources automatic loading in JSON parser
+ [REFINE] web: Avoid cc.loader resource loading being terminated while encounter errors
+ [REFINE] web: Throw new Error object instead of error message string
+ [REFINE] web: Move setDepthTest to renderer
+ [REFINE] web: Added BlendFuncFrame parser
+ [REFINE] web: Permitted webp image loading on Chrome
+ [REFINE] web: Suspended the video player when the browser is minimized
+
+ [FIX] web: Fixed a bug that VideoPlayer remove event throw error
+ [FIX] web: Fixed Armature position error in studio JSON parser
+ [FIX] web: Fixed default clearColor error in director
+ [FIX] web: Fixed rotation value parsing error in the timeline parser
+ [FIX] web: Fixed a bug that nested animation may be affected by outer animation
+ [FIX] web: Made LabelAtlas ignoring invalid characters and updating correctly the content size
+ [FIX] web: Fixed a bug that VideoPlayer remove event throw error
+ [FIX] web: Fixed a bug that cc.director.setNotificationNode(null) doesn't take effect
+ [FIX] web: Fixed texture rect update issue while changing sprite frame
+ [FIX] web: Fixed effect issue in ActionGrid and NodeGrid
+ [FIX] web: Fixed logic issue in Menu's _onTouchCancelled function
+ [FIX] web: Fixed MenuItem crash when normal image is null
+ [FIX] web: Fixed incomplete fadeout effects
+ [FIX] web: Fixed issue that return value of cc.screen.fullScreen is not boolean
+ [FIX] web: Fixed a bug that SkeletonNode is not drawing children
+
+ [TEST] web: Rewrote testcase for stencil depth mask in RenderTextureTest
+ [TEST] web: Improved renderTexture stencilDepth test
+ [TEST] web: Fixed abnormal effects in effectsTest
+ [TEST] web: Fixed invisiable testcase of effects
+
+Cocos2d-x v3.7.1 @ August.12 2015
+ [HIGHLIGHT] studio: Added new skeleton animation support and JSON parser for cocos v2.3.2 beta
+
+ [NEW] Node: Added getNodeToParentTransform with selected ancestor
+ [NEW] web: Added cc.director.setClearColor and support transparent background
+ [NEW] web: Added Animate's getCurrentFrameIndex function
+
+ [REFINE] studio: Optimized JSON parser's performance by removing audio play
+ [REFINE] studio: Optimized editor related extension data to a component instead of hosting in _userObject
+ [REFINE] web: Improved color/opacity manipulations in MenuItems
+
+ [FIX] studio: Fixed ccs.Skin construction issue in JSON parser
+ [FIX] web: Fixed an issue that loading process won't trigger callback problem
+ [FIX] web: Fixed a bug where not resetting cc.Audio._ignoreEnded when replaying a sound caused it to stay in a "playing" state
+ [FIX] web: cc.ScrollView and cc.TableView: added check for parent visibility in onTouchBegan method
+ [FIX] web: Fixed TurnPageDown effect
+ [FIX] web: Fixed Cocos Studio parser issue that all elements are missing while the timeline action contains rotation
+
+Cocos2d-x v3.7 Final @ July 20 2015
+ [REFINE] web: Add compatible Uint16Array definition
+
+ [FIX] web: Fixed url check regular expression not supporting localhost issue
+ [FIX] web: Fixed issue that sprite doesn't update texture rect correctly
+
+Cocos2d-x v3.7 RC1 @ July 14 2015
+ [REFINE] Improved localStorage warning when disabled
+
+ [FIX] Fixed a bug that SingleNode's color isn't set
+ [FIX] studio: Fixed a bug of JSON parser that texture address is wrong
+ [FIX] Fixed MenuItems' color/opacity setter issue with child nodes
+ [FIX] Fixed page view's layout issue for JSON parser
+ [FIX] Add ttc loader and prevent the pure digital fonts is invalid
+ [FIX] Fixed Float32Array initialization
+ [FIX] Fixed a bug that layout background is missing
+ [FIX] Fixed a bug that ObjectExtensionData miss setCustomProperty and getCustomProperty function
+
+Cocos2d-x v3.7 RC0 @ July 1 2015
+
+* The json loader of Cocos Studio will automatically load dependencies resources
+* SIMD.js optimization for kazmath functions (from Intel)
+* Deleted the redundant variables defined and log informations in ccui.RichText
+* Allowed timeline animations with only one frame
+* Improved property declaration of cc.Texture2D
+
+* Bug fixes:
+ 1. Fixed positionType error of particle system in timeline parser
+ 2. Fixed setAnimationName issue while the property is undefined in timeline parser
+ 3. Fixed `cc.TMXObjectGroup#objectNamed` not returning the result bug
+ 4. Fixed TransitionSlideX callback sequence issue
+ 5. Fixed issue in music end event
+ 6. Fixed bug that LayerColor's color will disappear when update transform after being baked
+ 7. Fixed `inverse` function bug of `cc.math.Matrix4`
+ 8. Fixed the webaudio's invalid loop attribute bug for chrome 42
+ 9. Fixed crash when character not found into BMP font
+ 10. Fixed spine's js parser issue by avoid NaN duration
+ 11. Fixed LabelTTF multiline detection
+ 12. Fixed issue in ccui.Widget#getScale
+ 13. Fixed texture is not updated in some cases
+ 14. PlayMusic should not use the search path (timeline 2.x)
+ 15. Fixed bug of loading path of resources
+ 16. Premultiply texture's alpha for png by default to fix Cocos Studio render issues
+ 17. Fixed cache update issue of Layout after bake
+ 18. Fixed isBaked returning undefined issue
+ 19. Made CCProgressTimerCanvasRenderCmd to properly show colorized sprites
+ 20. Fixed attributes being reset issue while baked cache canvas' size changed
+ 21. Fixed texture does not rotate bug of ccui.LoadingBar
+ 22. Fixed color not being set issue in timeline parser
+ 23. Fixed custom easing animation bug
+ 24. Fixed return empty texture2d bug when adding image with same url multiple times
+ 25. Fixed actiontimeline can not step to last frame issue when loop play
+ 26. Fixed the prompt can not be used in iOS wechat 6.2
+ 27. Fixed restoring of sprite's color issue
+ 28. Fixed Uint8Array initialize issue
+ 29. Fixed cc.TextFieldTTF Delegate memory leaks
+ 30. Fixed sorted result is wrong in cc.eventManager (_sortEventListenersOfSceneGraphPriorityDes)
+ 31. Fixed BinaryLoader issue on IE11
+ 32. Fixed the sprite's texture bug when frequently change the color
+ 33. Fixed an issue that action will result in automatic termination
+ 34. Fixed ScrollView initWithViewSize issue
+
Cocos2d-JS v3.6 @ April 29 2015
* Added GAF web runtime to the web engine, the native support will be merged in future version.
@@ -82,7 +200,7 @@ Cocos2d-JS v3.5 @ April 1 2015
8. Fixed a bug of Cocos Studio parser that the background color of `ccui.Layout` can't be parsed correctly.
9. Fixed a bug of `cc.ClippingNode` that it doesn't work when set `inverted` to true in Canvas Mode.
10. Fixed a bug of `ccs.Armature` that its name was modified to animation name when loading from json files.
- 11. Fixed a bug of `ccui.PageView` that it cancel child touch during movment of page view.
+ 11. Fixed a bug of `ccui.PageView` that it cancel child touch during movement of page view.
12. Fixed a bug of `cc.Scheduler` that its parameter `repeat` is invalid in schedule function.
13. Fixed a bug of `cc.Scheduler` that `unschedule` function may fail.
@@ -245,7 +363,7 @@ Cocos2d-JS v3.2 RC0 @ Dec.11, 2014
6. Fixed an issue of `cc.ParticleSystem` that it can't change its texture mode and shape type in Canvas mode.
7. Fixed an issue of `cc.Layer`'s bake function that its position is incorrect when cc.view's scale isn't 1.
8. Fixed an issue of `ccs.ArmatureAnimation`'s `setMovementEventCallFunc` and `setFrameEventCallFunc`.
- 9. Fixed an issue of `console.log` that it isn't a funtion on IE9.
+ 9. Fixed an issue of `console.log` that it isn't a function on IE9.
10. Fixed an issue of `CSLoader` that it will add duplicate resources to sprite frame cache.
11. Fixed an issue of `cc.ProgressTimer` that its setColor is not taking effect.
12. Fixed an issue of `cc.loader` that it will throw an error when loading a remote texture.
diff --git a/README.mdown b/README.mdown
index c41b79bc2c..3b13c27fac 100644
--- a/README.mdown
+++ b/README.mdown
@@ -1,40 +1,26 @@
Cocos2d-html5
==================
-[Cocos2d-html5][1] is a cross-platform 2D game engine written in Javascript, based on [Cocos2d-X][2] and licensed under MIT.
+[Cocos2d-html5][1] is a cross-platform 2D game engine written in JavaScript, based on [Cocos2d-X][2] and licensed under MIT.
It incorporates the same high level api as “Cocos2d JS-binding engine” and compatible with Cocos2d-X.
It currently supports canvas and WebGL renderer.
+-------------
+
+#### Cocos2d-html5 has evolved to [Cocos Creator][11], new generation of Cocos game engine with a full featured editor and content creation friendly workflow. It supports all major platforms allowing games to be quickly released for the web, iOS, Android, Windows, Mac, and various mini-game platforms. A pure JavaScript-developed engine runtime is available on the web and mini-game platforms for better performance and smaller packages. On other native platforms, C++ is used to implement the underlying framework, providing greater operational efficiency. The latest repository is maintained in here [Engine of Cocos Creator][9].
+
+-------------
+
Cross Platform
-------------
* Popular browsers: Chrome 14+, Safari 5.0+, IE9+, Firefox 3.5+.
- * Mobile platforms: coming soon.
+ * Mobile platforms: Mobile browsers,Facebook Instant Games and Mini Games.
* Native App: Same piece of code can run on "Cocos2d JS-Binding Engine" without or with little modification.
Documentation
------------------
* Website: [www.cocos2d-x.org][3]
- * API References: [http://www.cocos2d-x.org/wiki/Reference] [4]
-
-
-Installing from [bower][8] (version >=3.4)
-------------------
-
-```shell
-$ bower install cocos2d-html5
-```
-
-Running the tests (version <3)
-------------------
-
-```shell
-$ git clone git://github.com/cocos2d/cocos2d-html5.git
-$ cd cocos2d-html5
-$ git submodule update --init
-$ python -m SimpleHTTPServer
-```
-... and then open a browser and go to `http://localhost:8000/tests`
-
+ * Cocos Creator download: [Cocos Creator][10]
Contact us
------------------
@@ -49,4 +35,7 @@ Contact us
[5]: http://forum.cocos2d-x.org "http://forum.cocos2d-x.org"
[6]: http://www.twitter.com/cocos2dhtml5 "http://www.twitter.com/cocos2dhtml5"
[7]: http://t.sina.com.cn/cocos2dhtml5 "http://t.sina.com.cn/cocos2dhtml5"
-[8]: http://bower.io "http://bower.io"
\ No newline at end of file
+[8]: http://bower.io "http://bower.io"
+[9]: https://github.com/cocos-creator/engine
+[10]: http://cocos2d-x.org/download
+[11]: https://www.cocos.com/en/products#CocosCreator "https://www.cocos.com"
diff --git a/bower.json b/bower.json
index 5493b6e512..e97d56bb83 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,5 @@
{
"name": "cocos2d-html5",
- "version": "3.4",
"homepage": "http://www.cocos2d-x.org",
"authors": [
"AUTHORS.txt"
@@ -34,4 +33,4 @@
"test",
"tests"
]
-}
\ No newline at end of file
+}
diff --git a/cocos2d/actions/CCAction.js b/cocos2d/actions/CCAction.js
index cce37bbebd..e5487824aa 100644
--- a/cocos2d/actions/CCAction.js
+++ b/cocos2d/actions/CCAction.js
@@ -43,16 +43,16 @@ cc.ACTION_TAG_INVALID = -1;
*/
cc.Action = cc.Class.extend(/** @lends cc.Action# */{
//***********variables*************
- originalTarget:null,
- target:null,
- tag:cc.ACTION_TAG_INVALID,
+ originalTarget: null,
+ target: null,
+ tag: cc.ACTION_TAG_INVALID,
//**************Public Functions***********
/**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
*/
- ctor:function () {
+ ctor: function () {
this.originalTarget = null;
this.target = null;
this.tag = cc.ACTION_TAG_INVALID;
@@ -65,7 +65,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @return {cc.Action}
*/
- copy:function () {
+ copy: function () {
cc.log("copy is deprecated. Please use clone instead.");
return this.clone();
},
@@ -76,7 +76,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @return {cc.Action}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Action();
action.originalTarget = null;
action.target = null;
@@ -89,7 +89,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @return {Boolean}
*/
- isDone:function () {
+ isDone: function () {
return true;
},
@@ -98,7 +98,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
this.originalTarget = target;
this.target = target;
},
@@ -107,7 +107,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
* called after the action has finished. It will set the 'target' to nil.
* IMPORTANT: You should never call "action stop" manually. Instead, use: "target.stopAction(action);"
*/
- stop:function () {
+ stop: function () {
this.target = null;
},
@@ -117,7 +117,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @param {Number} dt
*/
- step:function (dt) {
+ step: function (dt) {
cc.log("[Action step]. override me");
},
@@ -126,7 +126,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
cc.log("[Action update]. override me");
},
@@ -135,7 +135,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @return {cc.Node}
*/
- getTarget:function () {
+ getTarget: function () {
return this.target;
},
@@ -144,7 +144,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @param {cc.Node} target
*/
- setTarget:function (target) {
+ setTarget: function (target) {
this.target = target;
},
@@ -153,7 +153,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
*
* @return {cc.Node}
*/
- getOriginalTarget:function () {
+ getOriginalTarget: function () {
return this.originalTarget;
},
@@ -164,7 +164,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
* The target is 'assigned', it is not 'retained'.
* @param {cc.Node} originalTarget
*/
- setOriginalTarget:function (originalTarget) {
+ setOriginalTarget: function (originalTarget) {
this.originalTarget = originalTarget;
},
@@ -172,7 +172,7 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
* get tag number.
* @return {Number}
*/
- getTag:function () {
+ getTag: function () {
return this.tag;
},
@@ -180,24 +180,24 @@ cc.Action = cc.Class.extend(/** @lends cc.Action# */{
* set tag number.
* @param {Number} tag
*/
- setTag:function (tag) {
+ setTag: function (tag) {
this.tag = tag;
},
/**
- * Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
* and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
* This is a hack, and should be removed once JSB fixes the retain/release bug.
*/
- retain:function () {
+ retain: function () {
},
/**
- * Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
* and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
* This is a hack, and should be removed once JSB fixes the retain/release bug.
*/
- release:function () {
+ release: function () {
}
});
@@ -238,13 +238,13 @@ cc.Action.create = cc.action;
* @extends cc.Action
*/
cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
- //! duration in seconds
- _duration:0,
+ // duration in seconds
+ _duration: 0,
/**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
*/
- ctor:function () {
+ ctor: function () {
cc.Action.prototype.ctor.call(this);
this._duration = 0;
},
@@ -254,7 +254,7 @@ cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
*
* @return {Number}
*/
- getDuration:function () {
+ getDuration: function () {
return this._duration * (this._timesForRepeat || 1);
},
@@ -263,7 +263,7 @@ cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
*
* @param {Number} duration
*/
- setDuration:function (duration) {
+ setDuration: function (duration) {
this._duration = duration;
},
@@ -274,9 +274,9 @@ cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
* - The reversed action will be x of 100 move to 0.
* - Will be rewritten
*
- * @return {Null}
+ * @return {?cc.Action}
*/
- reverse:function () {
+ reverse: function () {
cc.log("cocos2d: FiniteTimeAction#reverse: Implement me");
return null;
},
@@ -287,7 +287,7 @@ cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
*
* @return {cc.FiniteTimeAction}
*/
- clone:function () {
+ clone: function () {
return new cc.FiniteTimeAction();
}
});
@@ -304,20 +304,20 @@ cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
* @param {Number} speed
*/
cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
- _speed:0.0,
- _innerAction:null,
+ _speed: 0.0,
+ _innerAction: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {cc.ActionInterval} action
- * @param {Number} speed
- */
- ctor:function (action, speed) {
+ * @param {cc.ActionInterval} action
+ * @param {Number} speed
+ */
+ ctor: function (action, speed) {
cc.Action.prototype.ctor.call(this);
this._speed = 0;
this._innerAction = null;
- action && this.initWithAction(action, speed);
+ action && this.initWithAction(action, speed);
},
/**
@@ -326,7 +326,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @return {Number}
*/
- getSpeed:function () {
+ getSpeed: function () {
return this._speed;
},
@@ -335,7 +335,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @param {Number} speed
*/
- setSpeed:function (speed) {
+ setSpeed: function (speed) {
this._speed = speed;
},
@@ -346,9 +346,9 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
* @param {Number} speed
* @return {Boolean}
*/
- initWithAction:function (action, speed) {
- if(!action)
- throw "cc.Speed.initWithAction(): action must be non nil";
+ initWithAction: function (action, speed) {
+ if (!action)
+ throw new Error("cc.Speed.initWithAction(): action must be non nil");
this._innerAction = action;
this._speed = speed;
@@ -361,7 +361,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @returns {cc.Speed}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Speed();
action.initWithAction(this._innerAction.clone(), this._speed);
return action;
@@ -372,7 +372,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.Action.prototype.startWithTarget.call(this, target);
this._innerAction.startWithTarget(target);
},
@@ -380,7 +380,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
/**
* Stop the action.
*/
- stop:function () {
+ stop: function () {
this._innerAction.stop();
cc.Action.prototype.stop.call(this);
},
@@ -391,7 +391,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @param {Number} dt
*/
- step:function (dt) {
+ step: function (dt) {
this._innerAction.step(dt * this._speed);
},
@@ -400,7 +400,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @return {Boolean}
*/
- isDone:function () {
+ isDone: function () {
return this._innerAction.isDone();
},
@@ -413,7 +413,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @return {cc.Speed}
*/
- reverse:function () {
+ reverse: function () {
return new cc.Speed(this._innerAction.reverse(), this._speed);
},
@@ -421,7 +421,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
* Set inner Action.
* @param {cc.ActionInterval} action
*/
- setInnerAction:function (action) {
+ setInnerAction: function (action) {
if (this._innerAction !== action) {
this._innerAction = action;
}
@@ -432,7 +432,7 @@ cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
*
* @return {cc.ActionInterval}
*/
- getInnerAction:function () {
+ getInnerAction: function () {
return this._innerAction;
}
});
@@ -492,29 +492,29 @@ cc.Speed.create = cc.speed;
*/
cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
// node to follow
- _followedNode:null,
+ _followedNode: null,
// whether camera should be limited to certain area
- _boundarySet:false,
+ _boundarySet: false,
// if screen size is bigger than the boundary - update not needed
- _boundaryFullyCovered:false,
+ _boundaryFullyCovered: false,
// fast access to the screen dimensions
- _halfScreenSize:null,
- _fullScreenSize:null,
- _worldRect:null,
+ _halfScreenSize: null,
+ _fullScreenSize: null,
+ _worldRect: null,
- leftBoundary:0.0,
- rightBoundary:0.0,
- topBoundary:0.0,
- bottomBoundary:0.0,
+ leftBoundary: 0.0,
+ rightBoundary: 0.0,
+ topBoundary: 0.0,
+ bottomBoundary: 0.0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * creates the action with a set boundary.
- * creates the action with no boundary set.
+ * creates the action with a set boundary.
+ * creates the action with no boundary set.
* @param {cc.Node} followedNode
* @param {cc.Rect} rect
- */
- ctor:function (followedNode, rect) {
+ */
+ ctor: function (followedNode, rect) {
cc.Action.prototype.ctor.call(this);
this._followedNode = null;
this._boundarySet = false;
@@ -529,9 +529,9 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
this.bottomBoundary = 0.0;
this._worldRect = cc.rect(0, 0, 0, 0);
- if(followedNode)
- rect ? this.initWithTarget(followedNode, rect)
- : this.initWithTarget(followedNode);
+ if (followedNode)
+ rect ? this.initWithTarget(followedNode, rect)
+ : this.initWithTarget(followedNode);
},
/**
@@ -540,7 +540,7 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
*
* @return {cc.Follow}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Follow();
var locRect = this._worldRect;
var rect = new cc.Rect(locRect.x, locRect.y, locRect.width, locRect.height);
@@ -553,7 +553,7 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
*
* @return {Boolean}
*/
- isBoundarySet:function () {
+ isBoundarySet: function () {
return this._boundarySet;
},
@@ -562,7 +562,7 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
*
* @param {Boolean} value
*/
- setBoudarySet:function (value) {
+ setBoudarySet: function (value) {
this._boundarySet = value;
},
@@ -573,9 +573,9 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
* @param {cc.Rect} [rect=]
* @return {Boolean}
*/
- initWithTarget:function (followedNode, rect) {
- if(!followedNode)
- throw "cc.Follow.initWithAction(): followedNode must be non nil";
+ initWithTarget: function (followedNode, rect) {
+ if (!followedNode)
+ throw new Error("cc.Follow.initWithAction(): followedNode must be non nil");
var _this = this;
rect = rect || cc.rect(0, 0, 0, 0);
@@ -619,7 +619,7 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
*
* @param {Number} dt
*/
- step:function (dt) {
+ step: function (dt) {
var tempPosX = this._followedNode.x;
var tempPosY = this._followedNode.y;
tempPosX = this._halfScreenSize.x - tempPosX;
@@ -633,7 +633,7 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
if (this._boundaryFullyCovered)
return;
- this.target.setPosition(cc.clampf(tempPosX, this.leftBoundary, this.rightBoundary), cc.clampf(tempPosY, this.bottomBoundary, this.topBoundary));
+ this.target.setPosition(cc.clampf(tempPosX, this.leftBoundary, this.rightBoundary), cc.clampf(tempPosY, this.bottomBoundary, this.topBoundary));
} else {
this.target.setPosition(tempPosX, tempPosY);
}
@@ -644,14 +644,14 @@ cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
*
* @return {Boolean}
*/
- isDone:function () {
+ isDone: function () {
return ( !this._followedNode.running );
},
/**
* Stop the action.
*/
- stop:function () {
+ stop: function () {
this.target = null;
cc.Action.prototype.stop.call(this);
}
diff --git a/cocos2d/actions/CCActionCamera.js b/cocos2d/actions/CCActionCamera.js
deleted file mode 100644
index 0ff5786b71..0000000000
--- a/cocos2d/actions/CCActionCamera.js
+++ /dev/null
@@ -1,293 +0,0 @@
-/****************************************************************************
- Copyright (c) 2008-2010 Ricardo Quesada
- Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
-
- http://www.cocos2d-x.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
-
-/**
- * Base class for cc.Camera actions
- * @class
- * @extends cc.ActionInterval
- */
-cc.ActionCamera = cc.ActionInterval.extend(/** @lends cc.ActionCamera# */{
- _centerXOrig:0,
- _centerYOrig:0,
- _centerZOrig:0,
- _eyeXOrig:0,
- _eyeYOrig:0,
- _eyeZOrig:0,
- _upXOrig:0,
- _upYOrig:0,
- _upZOrig:0,
-
- /**
- * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- */
- ctor:function(){
- var _t = this;
- cc.ActionInterval.prototype.ctor.call(_t);
-
- _t._centerXOrig=0;
- _t._centerYOrig=0;
- _t._centerZOrig=0;
- _t._eyeXOrig=0;
- _t._eyeYOrig=0;
- _t._eyeZOrig=0;
- _t._upXOrig=0;
- _t._upYOrig=0;
- _t._upZOrig=0;
- },
-
- /**
- * called before the action start. It will also set the target.
- *
- * @param {cc.Node} target
- */
- startWithTarget:function (target) {
- var _t = this;
- cc.ActionInterval.prototype.startWithTarget.call(_t, target);
-
- var camera = target.getCamera();
- var centerXYZ = camera.getCenter();
- _t._centerXOrig = centerXYZ.x;
- _t._centerYOrig = centerXYZ.y;
- _t._centerZOrig = centerXYZ.z;
-
- var eyeXYZ = camera.getEye();
- _t._eyeXOrig = eyeXYZ.x;
- _t._eyeYOrig = eyeXYZ.y;
- _t._eyeZOrig = eyeXYZ.z;
-
- var upXYZ = camera.getUp();
- _t._upXOrig = upXYZ.x;
- _t._upYOrig = upXYZ.y;
- _t._upZOrig = upXYZ.z;
- },
-
- /**
- * to copy object with deep copy.
- * returns a new clone of the action
- *
- * @returns {cc.ActionCamera}
- */
- clone:function(){
- return new cc.ActionCamera();
- },
-
- /**
- * returns a reversed action.
- * For example:
- * - The action will be x coordinates of 0 move to 100.
- * - The reversed action will be x of 100 move to 0.
- * - Will be rewritten
- *
- */
- reverse:function () {
- return new cc.ReverseTime(this);
- }
-});
-
-/**
- * Orbits the camera around the center of the screen using spherical coordinates.
- *
- * @param {Number} t time
- * @param {Number} radius
- * @param {Number} deltaRadius
- * @param {Number} angleZ
- * @param {Number} deltaAngleZ
- * @param {Number} angleX
- * @param {Number} deltaAngleX
- *
- * @class
- * @extends cc.ActionCamera
- */
-cc.OrbitCamera = cc.ActionCamera.extend(/** @lends cc.OrbitCamera# */{
- _radius: 0.0,
- _deltaRadius: 0.0,
- _angleZ: 0.0,
- _deltaAngleZ: 0.0,
- _angleX: 0.0,
- _deltaAngleX: 0.0,
- _radZ: 0.0,
- _radDeltaZ: 0.0,
- _radX: 0.0,
- _radDeltaX: 0.0,
-
- /**
- * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * creates a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX.
- * @param {Number} t time
- * @param {Number} radius
- * @param {Number} deltaRadius
- * @param {Number} angleZ
- * @param {Number} deltaAngleZ
- * @param {Number} angleX
- * @param {Number} deltaAngleX
- */
- ctor:function(t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX){
- cc.ActionCamera.prototype.ctor.call(this);
-
- deltaAngleX !== undefined && this.initWithDuration(t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX);
- },
-
- /**
- * initializes a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX
- * @param {Number} t time
- * @param {Number} radius
- * @param {Number} deltaRadius
- * @param {Number} angleZ
- * @param {Number} deltaAngleZ
- * @param {Number} angleX
- * @param {Number} deltaAngleX
- * @return {Boolean}
- */
- initWithDuration:function (t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX) {
- if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
- var _t = this;
- _t._radius = radius;
- _t._deltaRadius = deltaRadius;
- _t._angleZ = angleZ;
- _t._deltaAngleZ = deltaAngleZ;
- _t._angleX = angleX;
- _t._deltaAngleX = deltaAngleX;
-
- _t._radDeltaZ = cc.degreesToRadians(deltaAngleZ);
- _t._radDeltaX = cc.degreesToRadians(deltaAngleX);
- return true;
- }
- return false;
- },
-
- /**
- * positions the camera according to spherical coordinates
- * @return {Object}
- */
- sphericalRadius:function () {
- var newRadius, zenith, azimuth;
- var camera = this.target.getCamera();
- var eyeXYZ = camera.getEye();
- var centerXYZ = camera.getCenter();
-
- var x = eyeXYZ.x - centerXYZ.x, y = eyeXYZ.y - centerXYZ.y, z = eyeXYZ.z - centerXYZ.z;
-
- var r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
- var s = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
- if (s === 0.0)
- s = cc.FLT_EPSILON;
- if (r === 0.0)
- r = cc.FLT_EPSILON;
-
- zenith = Math.acos(z / r);
- if (x < 0)
- azimuth = Math.PI - Math.asin(y / s);
- else
- azimuth = Math.asin(y / s);
- newRadius = r / cc.Camera.getZEye();
- return {newRadius:newRadius, zenith:zenith, azimuth:azimuth};
- },
-
- /**
- * called before the action start. It will also set the target.
- *
- * @param {cc.Node} target
- */
- startWithTarget:function (target) {
- var _t = this;
- cc.ActionInterval.prototype.startWithTarget.call(_t, target);
- var retValue = _t.sphericalRadius();
- if (isNaN(_t._radius))
- _t._radius = retValue.newRadius;
-
- if (isNaN(_t._angleZ))
- _t._angleZ = cc.radiansToDegrees(retValue.zenith);
-
- if (isNaN(_t._angleX))
- _t._angleX = cc.radiansToDegrees(retValue.azimuth);
-
- _t._radZ = cc.degreesToRadians(_t._angleZ);
- _t._radX = cc.degreesToRadians(_t._angleX);
- },
-
- /**
- * to copy object with deep copy.
- * returns a new clone of the action
- *
- * @returns {cc.ActionCamera}
- */
- clone:function(){
- var a = new cc.OrbitCamera(), _t = this;
- a.initWithDuration(_t._duration, _t._radius, _t._deltaRadius, _t._angleZ, _t._deltaAngleZ, _t._angleX, _t._deltaAngleX);
- return a;
- },
-
- /**
- * Called once per frame. Time is the number of seconds of a frame interval.
- *
- * @param {Number} dt
- */
- update:function (dt) {
- dt = this._computeEaseTime(dt);
- var r = (this._radius + this._deltaRadius * dt) * cc.Camera.getZEye();
- var za = this._radZ + this._radDeltaZ * dt;
- var xa = this._radX + this._radDeltaX * dt;
-
- var i = Math.sin(za) * Math.cos(xa) * r + this._centerXOrig;
- var j = Math.sin(za) * Math.sin(xa) * r + this._centerYOrig;
- var k = Math.cos(za) * r + this._centerZOrig;
-
- this.target.getCamera().setEye(i, j, k);
- this.target.setNodeDirty();
- }
-});
-
-/**
- * creates a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX
- * @function
- * @param {Number} t time
- * @param {Number} radius
- * @param {Number} deltaRadius
- * @param {Number} angleZ
- * @param {Number} deltaAngleZ
- * @param {Number} angleX
- * @param {Number} deltaAngleX
- * @return {cc.OrbitCamera}
- */
-cc.orbitCamera = function (t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX) {
- return new cc.OrbitCamera(t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX);
-};
-
-/**
- * Please use cc.orbitCamera instead
- * creates a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX
- * @param {Number} t time
- * @param {Number} radius
- * @param {Number} deltaRadius
- * @param {Number} angleZ
- * @param {Number} deltaAngleZ
- * @param {Number} angleX
- * @param {Number} deltaAngleX
- * @return {cc.OrbitCamera}
- * @static
- * @deprecated since v3.0 please use cc.orbitCamera() instead.
- */
-cc.OrbitCamera.create = cc.orbitCamera;
diff --git a/cocos2d/actions/CCActionCatmullRom.js b/cocos2d/actions/CCActionCatmullRom.js
index 4ab0dfd7fc..a17dca4ccc 100644
--- a/cocos2d/actions/CCActionCatmullRom.js
+++ b/cocos2d/actions/CCActionCatmullRom.js
@@ -44,9 +44,10 @@
* @param {cc.Point} p3
* @param {Number} tension
* @param {Number} t
+ * @param {cc.Point} [out]
* @return {cc.Point}
*/
-cc.cardinalSplineAt = function (p0, p1, p2, p3, tension, t) {
+cc.cardinalSplineAt = function (p0, p1, p2, p3, tension, t, out) {
var t2 = t * t;
var t3 = t2 * t;
@@ -62,7 +63,13 @@ cc.cardinalSplineAt = function (p0, p1, p2, p3, tension, t) {
var x = (p0.x * b1 + p1.x * b2 + p2.x * b3 + p3.x * b4);
var y = (p0.y * b1 + p1.y * b2 + p2.y * b3 + p3.y * b4);
- return cc.p(x, y);
+ if (out !== undefined) {
+ out.x = x;
+ out.y = y;
+ }
+ else {
+ return cc.p(x, y);
+ }
};
/**
@@ -175,7 +182,7 @@ cc.CardinalSplineTo = cc.ActionInterval.extend(/** @lends cc.CardinalSplineTo# *
*/
initWithDuration:function (duration, points, tension) {
if(!points || points.length === 0)
- throw "Invalid configuration. It must at least have one control point";
+ throw new Error("Invalid configuration. It must at least have one control point");
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this.setPoints(points);
diff --git a/cocos2d/actions/CCActionEase.js b/cocos2d/actions/CCActionEase.js
index ca8b0a6cb0..f6ddef0ce0 100644
--- a/cocos2d/actions/CCActionEase.js
+++ b/cocos2d/actions/CCActionEase.js
@@ -56,7 +56,7 @@ cc.ActionEase = cc.ActionInterval.extend(/** @lends cc.ActionEase# */{
*/
initWithAction:function (action) {
if(!action)
- throw "cc.ActionEase.initWithAction(): action must be non nil";
+ throw new Error("cc.ActionEase.initWithAction(): action must be non nil");
if (this.initWithDuration(action.getDuration())) {
this._inner = action;
@@ -1140,7 +1140,7 @@ cc.EaseElastic = cc.ActionEase.extend(/** @lends cc.EaseElastic# */{
/**
* Create a action. Opposite with the original motion trajectory.
* Will be overwrite.
- * @return {null}
+ * @return {?cc.Action}
*/
reverse:function () {
cc.log("cc.EaseElastic.reverse(): it should be overridden in subclass.");
@@ -1770,7 +1770,7 @@ cc.easeBounceOut = function(){
/**
* cc.EaseBounceInOut action.
- * Eased bounce effect at the begining and ending.
+ * Eased bounce effect at the beginning and ending.
* @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
* @class
* @extends cc.EaseBounce
@@ -1823,7 +1823,7 @@ cc.EaseBounceInOut = cc.EaseBounce.extend(/** @lends cc.EaseBounceInOut# */{
/**
* Creates the action.
- * Eased bounce effect at the begining and ending.
+ * Eased bounce effect at the beginning and ending.
* @static
* @deprecated since v3.0 Please use action.easing(cc.easeBounceInOut())
* @param {cc.ActionInterval} action
@@ -1857,7 +1857,7 @@ cc._easeBounceInOutObj = {
/**
* Creates the action easing object.
- * Eased bounce effect at the begining and ending.
+ * Eased bounce effect at the beginning and ending.
* @function
* @return {Object}
* @example
@@ -2050,7 +2050,7 @@ cc.easeBackOut = function(){
/**
* cc.EaseBackInOut action.
- * Begining of cc.EaseBackIn. Ending of cc.EaseBackOut.
+ * Beginning of cc.EaseBackIn. Ending of cc.EaseBackOut.
* @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
* @class
* @extends cc.ActionEase
@@ -2104,7 +2104,7 @@ cc.EaseBackInOut = cc.ActionEase.extend(/** @lends cc.EaseBackInOut# */{
/**
* Creates the action.
- * Begining of cc.EaseBackIn. Ending of cc.EaseBackOut.
+ * Beginning of cc.EaseBackIn. Ending of cc.EaseBackOut.
* @static
* @param {cc.ActionInterval} action
* @return {cc.EaseBackInOut}
@@ -2139,7 +2139,7 @@ cc._easeBackInOutObj = {
/**
* Creates the action easing object.
- * Begining of cc.EaseBackIn. Ending of cc.EaseBackOut.
+ * Beginning of cc.EaseBackIn. Ending of cc.EaseBackOut.
* @function
* @return {Object}
* @example
@@ -3678,4 +3678,3 @@ cc._easeCubicActionInOut = {
cc.easeCubicActionInOut = function(){
return cc._easeCubicActionInOut;
};
-
diff --git a/cocos2d/actions/CCActionInstant.js b/cocos2d/actions/CCActionInstant.js
index 55f3c09be0..f1e73f91ac 100644
--- a/cocos2d/actions/CCActionInstant.js
+++ b/cocos2d/actions/CCActionInstant.js
@@ -630,11 +630,10 @@ cc.Place.create = cc.place;
*/
cc.CallFunc = cc.ActionInstant.extend(/** @lends cc.CallFunc# */{
_selectorTarget:null,
- _callFunc:null,
_function:null,
_data:null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
* Creates a CallFunc action with the callback.
* @param {function} selector
@@ -644,11 +643,7 @@ cc.CallFunc = cc.ActionInstant.extend(/** @lends cc.CallFunc# */{
ctor:function(selector, selectorTarget, data){
cc.FiniteTimeAction.prototype.ctor.call(this);
- if(selector !== undefined){
- if(selectorTarget === undefined)
- this.initWithFunction(selector);
- else this.initWithFunction(selector, selectorTarget, data);
- }
+ this.initWithFunction(selector, selectorTarget, data);
},
/**
@@ -659,13 +654,15 @@ cc.CallFunc = cc.ActionInstant.extend(/** @lends cc.CallFunc# */{
* @return {Boolean}
*/
initWithFunction:function (selector, selectorTarget, data) {
- if (selectorTarget) {
- this._data = data;
- this._callFunc = selector;
+ if (selector) {
+ this._function = selector;
+ }
+ if (selectorTarget) {
this._selectorTarget = selectorTarget;
- }
- else if (selector)
- this._function = selector;
+ }
+ if (data !== undefined) {
+ this._data = data;
+ }
return true;
},
@@ -673,10 +670,9 @@ cc.CallFunc = cc.ActionInstant.extend(/** @lends cc.CallFunc# */{
* execute the function.
*/
execute:function () {
- if (this._callFunc != null) //CallFunc, N, ND
- this._callFunc.call(this._selectorTarget, this.target, this._data);
- else if(this._function)
- this._function.call(null, this.target);
+ if (this._function) {
+ this._function.call(this._selectorTarget, this.target, this._data);
+ }
},
/**
@@ -715,12 +711,8 @@ cc.CallFunc = cc.ActionInstant.extend(/** @lends cc.CallFunc# */{
* @return {cc.CallFunc}
*/
clone:function(){
- var action = new cc.CallFunc();
- if(this._selectorTarget){
- action.initWithFunction(this._callFunc, this._selectorTarget, this._data)
- }else if(this._function){
- action.initWithFunction(this._function);
- }
+ var action = new cc.CallFunc();
+ action.initWithFunction(this._function, this._selectorTarget, this._data);
return action;
}
});
diff --git a/cocos2d/actions/CCActionInterval.js b/cocos2d/actions/CCActionInterval.js
index 67e1b853e1..905d72b0a2 100644
--- a/cocos2d/actions/CCActionInterval.js
+++ b/cocos2d/actions/CCActionInterval.js
@@ -44,20 +44,20 @@
* var actionInterval = new cc.ActionInterval(3);
*/
cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
- _elapsed:0,
- _firstTick:false,
+ _elapsed: 0,
+ _firstTick: false,
_easeList: null,
- _timesForRepeat:1,
+ _timesForRepeat: 1,
_repeatForever: false,
_repeatMethod: false,//Compatible with repeat class, Discard after can be deleted
_speed: 1,
_speedMethod: false,//Compatible with speed class, Discard after can be deleted
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} d duration in seconds
- */
- ctor:function (d) {
+ * @param {Number} d duration in seconds
+ */
+ ctor: function (d) {
this._speed = 1;
this._timesForRepeat = 1;
this._repeatForever = false;
@@ -65,14 +65,14 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
this._repeatMethod = false;//Compatible with repeat class, Discard after can be deleted
this._speedMethod = false;//Compatible with repeat class, Discard after can be deleted
cc.FiniteTimeAction.prototype.ctor.call(this);
- d !== undefined && this.initWithDuration(d);
+ d !== undefined && this.initWithDuration(d);
},
/**
* How many seconds had elapsed since the actions started to run.
* @return {Number}
*/
- getElapsed:function () {
+ getElapsed: function () {
return this._elapsed;
},
@@ -81,7 +81,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @param {Number} d duration in seconds
* @return {Boolean}
*/
- initWithDuration:function (d) {
+ initWithDuration: function (d) {
this._duration = (d === 0) ? cc.FLT_EPSILON : d;
// prevent division by 0
// This comparison could be in step:, but it might decrease the performance
@@ -95,7 +95,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* Returns true if the action has finished.
* @return {Boolean}
*/
- isDone:function () {
+ isDone: function () {
return (this._elapsed >= this._duration);
},
@@ -104,7 +104,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @param {cc.Action} action
* @private
*/
- _cloneDecoration: function(action){
+ _cloneDecoration: function (action) {
action._repeatForever = this._repeatForever;
action._speed = this._speed;
action._timesForRepeat = this._timesForRepeat;
@@ -113,10 +113,10 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
action._repeatMethod = this._repeatMethod;
},
- _reverseEaseList: function(action){
- if(this._easeList){
+ _reverseEaseList: function (action) {
+ if (this._easeList) {
action._easeList = [];
- for(var i=0; i 0 ? t : 0);
//Compatible with repeat class, Discard after can be deleted (this._repeatMethod)
- if(this._repeatMethod && this._timesForRepeat > 1 && this.isDone()){
- if(!this._repeatForever){
+ if (this._repeatMethod && this._timesForRepeat > 1 && this.isDone()) {
+ if (!this._repeatForever) {
this._timesForRepeat--;
}
//var diff = locInnerAction.getElapsed() - locInnerAction._duration;
@@ -198,7 +198,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* Start this action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.Action.prototype.startWithTarget.call(this, target);
this._elapsed = 0;
this._firstTick = true;
@@ -208,9 +208,9 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* returns a reversed action.
* Will be overwrite.
*
- * @return {null}
+ * @return {?cc.Action}
*/
- reverse:function () {
+ reverse: function () {
cc.log("cc.IntervalAction: reverse not implemented.");
return null;
},
@@ -220,7 +220,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @warning It should be overridden in subclass.
* @param {Number} amp
*/
- setAmplitudeRate:function (amp) {
+ setAmplitudeRate: function (amp) {
// Abstract class needs implementation
cc.log("cc.ActionInterval.setAmplitudeRate(): it should be overridden in subclass.");
},
@@ -230,7 +230,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @warning It should be overridden in subclass.
* @return {Number} 0
*/
- getAmplitudeRate:function () {
+ getAmplitudeRate: function () {
// Abstract class needs implementation
cc.log("cc.ActionInterval.getAmplitudeRate(): it should be overridden in subclass.");
return 0;
@@ -244,8 +244,8 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @param speed
* @returns {cc.Action}
*/
- speed: function(speed){
- if(speed <= 0){
+ speed: function (speed) {
+ if (speed <= 0) {
cc.log("The speed parameter error");
return this;
}
@@ -259,7 +259,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* Get this action speed.
* @return {Number}
*/
- getSpeed: function(){
+ getSpeed: function () {
return this._speed;
},
@@ -268,7 +268,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @param {Number} speed
* @returns {cc.ActionInterval}
*/
- setSpeed: function(speed){
+ setSpeed: function (speed) {
this._speed = speed;
return this;
},
@@ -279,9 +279,9 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* @param times
* @returns {cc.ActionInterval}
*/
- repeat: function(times){
+ repeat: function (times) {
times = Math.round(times);
- if(isNaN(times) || times < 1){
+ if (isNaN(times) || times < 1) {
cc.log("The repeat parameter error");
return this;
}
@@ -295,7 +295,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
* To repeat the an action for a limited number of times use the Repeat action.
* @returns {cc.ActionInterval}
*/
- repeatForever: function(){
+ repeatForever: function () {
this._repeatMethod = true;//Compatible with repeat class, Discard after can be deleted
this._timesForRepeat = this.MAX_VALUE;
this._repeatForever = true;
@@ -339,23 +339,23 @@ cc.ActionInterval.create = cc.actionInterval;
* var seq = new cc.Sequence(actArray);
*/
cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
- _actions:null,
- _split:null,
- _last:0,
+ _actions: null,
+ _split: null,
+ _last: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
* Create an array of sequenceable actions.
- * @param {Array|cc.FiniteTimeAction} tempArray
- */
- ctor:function (tempArray) {
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ */
+ ctor: function (tempArray) {
cc.ActionInterval.prototype.ctor.call(this);
this._actions = [];
- var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
- var last = paramArray.length - 1;
- if ((last >= 0) && (paramArray[last] == null))
- cc.log("parameters should not be ending with null in Javascript");
+ var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
+ var last = paramArray.length - 1;
+ if ((last >= 0) && (paramArray[last] == null))
+ cc.log("parameters should not be ending with null in Javascript");
if (last >= 0) {
var prev = paramArray[0], action1;
@@ -375,9 +375,9 @@ cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
* @param {cc.FiniteTimeAction} actionTwo
* @return {Boolean}
*/
- initWithTwoActions:function (actionOne, actionTwo) {
- if(!actionOne || !actionTwo)
- throw "cc.Sequence.initWithTwoActions(): arguments must all be non nil";
+ initWithTwoActions: function (actionOne, actionTwo) {
+ if (!actionOne || !actionTwo)
+ throw new Error("cc.Sequence.initWithTwoActions(): arguments must all be non nil");
var d = actionOne._duration + actionTwo._duration;
this.initWithDuration(d);
@@ -391,7 +391,7 @@ cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
* returns a new clone of the action
* @returns {cc.Sequence}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Sequence();
this._cloneDecoration(action);
action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone());
@@ -402,7 +402,7 @@ cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._split = this._actions[0]._duration / this._duration;
this._last = -1;
@@ -411,7 +411,7 @@ cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
/**
* stop the action.
*/
- stop:function () {
+ stop: function () {
// Issue #1305
if (this._last !== -1)
this._actions[this._last].stop();
@@ -422,7 +422,7 @@ cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
var new_t, found = 0;
var locSplit = this._split, locActions = this._actions, locLast = this._last, actionFound;
@@ -475,7 +475,7 @@ cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
* Returns a reversed action.
* @return {cc.Sequence}
*/
- reverse:function () {
+ reverse: function () {
var action = cc.Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse());
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -502,19 +502,19 @@ cc.sequence = function (/*Multiple Arguments*/tempArray) {
cc.log("parameters should not be ending with null in Javascript");
var result, current, i, repeat;
- while(paramArray && paramArray.length > 0){
+ while (paramArray && paramArray.length > 0) {
current = Array.prototype.shift.call(paramArray);
repeat = current._timesForRepeat || 1;
current._repeatMethod = false;
current._timesForRepeat = 1;
i = 0;
- if(!result){
+ if (!result) {
result = current;
i = 1;
}
- for(i; i
- * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30).
- * @param {cc.FiniteTimeAction} action
- * @param {Number} times
- */
+ * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30).
+ * @param {cc.FiniteTimeAction} action
+ * @param {Number} times
+ */
ctor: function (action, times) {
cc.ActionInterval.prototype.ctor.call(this);
- times !== undefined && this.initWithAction(action, times);
+ times !== undefined && this.initWithAction(action, times);
},
/**
@@ -578,13 +578,13 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* @param {Number} times
* @return {Boolean}
*/
- initWithAction:function (action, times) {
+ initWithAction: function (action, times) {
var duration = action._duration * times;
if (this.initWithDuration(duration)) {
this._times = times;
this._innerAction = action;
- if (action instanceof cc.ActionInstant){
+ if (action instanceof cc.ActionInstant) {
this._actionInstant = true;
this._times -= 1;
}
@@ -598,7 +598,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* returns a new clone of the action
* @returns {cc.Repeat}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Repeat();
this._cloneDecoration(action);
action.initWithAction(this._innerAction.clone(), this._times);
@@ -609,7 +609,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
this._total = 0;
this._nextDt = this._innerAction._duration / this._duration;
cc.ActionInterval.prototype.startWithTarget.call(this, target);
@@ -619,7 +619,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
/**
* stop the action
*/
- stop:function () {
+ stop: function () {
this._innerAction.stop();
cc.Action.prototype.stop.call(this);
},
@@ -628,7 +628,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
var locInnerAction = this._innerAction;
var locDuration = this._duration;
@@ -668,7 +668,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* Return true if the action has finished.
* @return {Boolean}
*/
- isDone:function () {
+ isDone: function () {
return this._total === this._times;
},
@@ -676,7 +676,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* returns a reversed action.
* @return {cc.Repeat}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.Repeat(this._innerAction.reverse(), this._times);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -687,7 +687,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* Set inner Action.
* @param {cc.FiniteTimeAction} action
*/
- setInnerAction:function (action) {
+ setInnerAction: function (action) {
if (this._innerAction !== action) {
this._innerAction = action;
}
@@ -697,7 +697,7 @@ cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
* Get inner Action.
* @return {cc.FiniteTimeAction}
*/
- getInnerAction:function () {
+ getInnerAction: function () {
return this._innerAction;
}
});
@@ -738,27 +738,27 @@ cc.Repeat.create = cc.repeat;
* var rep = new cc.RepeatForever(cc.sequence(jump2, jump1), 5);
*/
cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
- _innerAction:null, //CCActionInterval
+ _innerAction: null, //CCActionInterval
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * Create a acton which repeat forever.
- * @param {cc.FiniteTimeAction} action
- */
- ctor:function (action) {
+ * Create a acton which repeat forever.
+ * @param {cc.FiniteTimeAction} action
+ */
+ ctor: function (action) {
cc.ActionInterval.prototype.ctor.call(this);
this._innerAction = null;
- action && this.initWithAction(action);
+ action && this.initWithAction(action);
},
/**
* @param {cc.ActionInterval} action
* @return {Boolean}
*/
- initWithAction:function (action) {
- if(!action)
- throw "cc.RepeatForever.initWithAction(): action must be non null";
+ initWithAction: function (action) {
+ if (!action)
+ throw new Error("cc.RepeatForever.initWithAction(): action must be non null");
this._innerAction = action;
return true;
@@ -768,7 +768,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* returns a new clone of the action
* @returns {cc.RepeatForever}
*/
- clone:function () {
+ clone: function () {
var action = new cc.RepeatForever();
this._cloneDecoration(action);
action.initWithAction(this._innerAction.clone());
@@ -779,7 +779,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._innerAction.startWithTarget(target);
},
@@ -789,7 +789,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* DON'T override unless you know what you are doing.
* @param dt delta time in seconds
*/
- step:function (dt) {
+ step: function (dt) {
var locInnerAction = this._innerAction;
locInnerAction.step(dt);
if (locInnerAction.isDone()) {
@@ -806,7 +806,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* Return true if the action has finished.
* @return {Boolean}
*/
- isDone:function () {
+ isDone: function () {
return false;
},
@@ -814,7 +814,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* Returns a reversed action.
* @return {cc.RepeatForever}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.RepeatForever(this._innerAction.reverse());
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -825,7 +825,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* Set inner action.
* @param {cc.ActionInterval} action
*/
- setInnerAction:function (action) {
+ setInnerAction: function (action) {
if (this._innerAction !== action) {
this._innerAction = action;
}
@@ -835,7 +835,7 @@ cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
* Get inner action.
* @return {cc.ActionInterval}
*/
- getInnerAction:function () {
+ getInnerAction: function () {
return this._innerAction;
}
});
@@ -872,26 +872,35 @@ cc.RepeatForever.create = cc.repeatForever;
* @extends cc.ActionInterval
*/
cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
- _one:null,
- _two:null,
+ _one: null,
+ _two: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Array|cc.FiniteTimeAction} tempArray
- */
- ctor:function (tempArray) {
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ */
+ ctor: function (tempArray) {
cc.ActionInterval.prototype.ctor.call(this);
this._one = null;
this._two = null;
- var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
- var last = paramArray.length - 1;
- if ((last >= 0) && (paramArray[last] == null))
- cc.log("parameters should not be ending with null in Javascript");
+ var i, paramArray, last;
+ if (tempArray instanceof Array) {
+ paramArray = tempArray;
+ }
+ else {
+ paramArray = new Array(arguments.length);
+ for (i = 0; i < arguments.length; ++i) {
+ paramArray[i] = arguments[i];
+ }
+ }
+ last = paramArray.length - 1;
+ if ((last >= 0) && (paramArray[last] == null))
+ cc.log("parameters should not be ending with null in Javascript");
if (last >= 0) {
var prev = paramArray[0], action1;
- for (var i = 1; i < last; i++) {
+ for (i = 1; i < last; i++) {
if (paramArray[i]) {
action1 = prev;
prev = cc.Spawn._actionOneTwo(action1, paramArray[i]);
@@ -906,9 +915,9 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* @param {cc.FiniteTimeAction} action2
* @return {Boolean}
*/
- initWithTwoActions:function (action1, action2) {
- if(!action1 || !action2)
- throw "cc.Spawn.initWithTwoActions(): arguments must all be non null" ;
+ initWithTwoActions: function (action1, action2) {
+ if (!action1 || !action2)
+ throw new Error("cc.Spawn.initWithTwoActions(): arguments must all be non null");
var ret = false;
@@ -934,7 +943,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* returns a new clone of the action
* @returns {cc.Spawn}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Spawn();
this._cloneDecoration(action);
action.initWithTwoActions(this._one.clone(), this._two.clone());
@@ -945,7 +954,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._one.startWithTarget(target);
this._two.startWithTarget(target);
@@ -954,7 +963,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
/**
* Stop the action
*/
- stop:function () {
+ stop: function () {
this._one.stop();
this._two.stop();
cc.Action.prototype.stop.call(this);
@@ -964,7 +973,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this._one)
this._one.update(dt);
@@ -976,7 +985,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* Returns a reversed action.
* @return {cc.Spawn}
*/
- reverse:function () {
+ reverse: function () {
var action = cc.Spawn._actionOneTwo(this._one.reverse(), this._two.reverse());
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -988,7 +997,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* Create a spawn action which runs several actions in parallel.
* @function
* @param {Array|cc.FiniteTimeAction}tempArray
- * @return {cc.FiniteTimeAction}
+ * @return {cc.Spawn}
* @example
* // example
* var action = cc.spawn(cc.jumpBy(2, cc.p(300, 0), 50, 4), cc.rotateBy(2, 720));
@@ -1013,7 +1022,7 @@ cc.spawn = function (/*Multiple Arguments*/tempArray) {
* @static
* @deprecated since v3.0 Please use cc.spawn instead.
* @param {Array|cc.FiniteTimeAction}tempArray
- * @return {cc.FiniteTimeAction}
+ * @return {cc.Spawn}
*/
cc.Spawn.create = cc.spawn;
@@ -1043,25 +1052,25 @@ cc.Spawn._actionOneTwo = function (action1, action2) {
* var rotateTo = new cc.RotateTo(2, 61.0);
*/
cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
- _dstAngleX:0,
- _startAngleX:0,
- _diffAngleX:0,
+ _dstAngleX: 0,
+ _startAngleX: 0,
+ _diffAngleX: 0,
- _dstAngleY:0,
- _startAngleY:0,
- _diffAngleY:0,
+ _dstAngleY: 0,
+ _startAngleY: 0,
+ _diffAngleY: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * Creates a RotateTo action with x and y rotation angles.
- * @param {Number} duration duration in seconds
- * @param {Number} deltaAngleX deltaAngleX in degrees.
- * @param {Number} [deltaAngleY] deltaAngleY in degrees.
- */
- ctor:function (duration, deltaAngleX, deltaAngleY) {
+ * Creates a RotateTo action with x and y rotation angles.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees.
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees.
+ */
+ ctor: function (duration, deltaAngleX, deltaAngleY) {
cc.ActionInterval.prototype.ctor.call(this);
- deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY);
+ deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY);
},
/**
@@ -1071,10 +1080,10 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
* @param {Number} deltaAngleY
* @return {Boolean}
*/
- initWithDuration:function (duration, deltaAngleX, deltaAngleY) {
+ initWithDuration: function (duration, deltaAngleX, deltaAngleY) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._dstAngleX = deltaAngleX || 0;
- this._dstAngleY = deltaAngleY || this._dstAngleX;
+ this._dstAngleY = deltaAngleY !== undefined ? deltaAngleY : this._dstAngleX;
return true;
}
return false;
@@ -1084,7 +1093,7 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
* returns a new clone of the action
* @returns {cc.RotateTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.RotateTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._dstAngleX, this._dstAngleY);
@@ -1095,7 +1104,7 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
// Calculate X
@@ -1121,8 +1130,9 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
/**
* RotateTo reverse not implemented.
* Will be overridden.
+ * @returns {cc.Action}
*/
- reverse:function () {
+ reverse: function () {
cc.log("cc.RotateTo.reverse(): it should be overridden in subclass.");
},
@@ -1130,7 +1140,7 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
this.target.rotationX = this._startAngleX + this._diffAngleX * dt;
@@ -1181,21 +1191,21 @@ cc.RotateTo.create = cc.rotateTo;
* var actionBy = new cc.RotateBy(2, 360);
*/
cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
- _angleX:0,
- _startAngleX:0,
- _angleY:0,
- _startAngleY:0,
+ _angleX: 0,
+ _startAngleX: 0,
+ _angleY: 0,
+ _startAngleY: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration duration in seconds
- * @param {Number} deltaAngleX deltaAngleX in degrees
- * @param {Number} [deltaAngleY] deltaAngleY in degrees
- */
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees
+ */
ctor: function (duration, deltaAngleX, deltaAngleY) {
cc.ActionInterval.prototype.ctor.call(this);
- deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY);
+ deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY);
},
/**
@@ -1205,7 +1215,7 @@ cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
* @param {Number} [deltaAngleY=] deltaAngleY in degrees
* @return {Boolean}
*/
- initWithDuration:function (duration, deltaAngleX, deltaAngleY) {
+ initWithDuration: function (duration, deltaAngleX, deltaAngleY) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._angleX = deltaAngleX || 0;
this._angleY = deltaAngleY || this._angleX;
@@ -1218,7 +1228,7 @@ cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
* returns a new clone of the action
* @returns {cc.RotateBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.RotateBy();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._angleX, this._angleY);
@@ -1229,7 +1239,7 @@ cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._startAngleX = target.rotationX;
this._startAngleY = target.rotationY;
@@ -1239,7 +1249,7 @@ cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
this.target.rotationX = this._startAngleX + this._angleX * dt;
@@ -1251,7 +1261,7 @@ cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
* Returns a reversed action.
* @return {cc.RotateBy}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.RotateBy(this._duration, -this._angleX, -this._angleY);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -1301,27 +1311,27 @@ cc.RotateBy.create = cc.rotateBy;
* @param {cc.Point|Number} deltaPos
* @param {Number} [deltaY]
* @example
- * var actionTo = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
*/
cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
- _positionDelta:null,
- _startPosition:null,
- _previousPosition:null,
+ _positionDelta: null,
+ _startPosition: null,
+ _previousPosition: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration duration in seconds
- * @param {cc.Point|Number} deltaPos
- * @param {Number} [deltaY]
- */
- ctor:function (duration, deltaPos, deltaY) {
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} deltaPos
+ * @param {Number} [deltaY]
+ */
+ ctor: function (duration, deltaPos, deltaY) {
cc.ActionInterval.prototype.ctor.call(this);
this._positionDelta = cc.p(0, 0);
this._startPosition = cc.p(0, 0);
this._previousPosition = cc.p(0, 0);
- deltaPos !== undefined && this.initWithDuration(duration, deltaPos, deltaY);
+ deltaPos !== undefined && this.initWithDuration(duration, deltaPos, deltaY);
},
/**
@@ -1331,12 +1341,12 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* @param {Number} [y]
* @return {Boolean}
*/
- initWithDuration:function (duration, position, y) {
+ initWithDuration: function (duration, position, y) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
- if(position.x !== undefined) {
- y = position.y;
- position = position.x;
- }
+ if (position.x !== undefined) {
+ y = position.y;
+ position = position.x;
+ }
this._positionDelta.x = position;
this._positionDelta.y = y;
@@ -1349,7 +1359,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* returns a new clone of the action
* @returns {cc.MoveBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.MoveBy();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._positionDelta);
@@ -1360,7 +1370,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
var locPosX = target.getPositionX();
var locPosY = target.getPositionY();
@@ -1374,7 +1384,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
var x = this._positionDelta.x * dt;
@@ -1389,9 +1399,9 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
x = x + locStartPosition.x;
y = y + locStartPosition.y;
- locPreviousPosition.x = x;
- locPreviousPosition.y = y;
- this.target.setPosition(x, y);
+ locPreviousPosition.x = x;
+ locPreviousPosition.y = y;
+ this.target.setPosition(x, y);
} else {
this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
}
@@ -1402,7 +1412,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* MoveTo reverse is not implemented
* @return {cc.MoveBy}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.MoveBy(this._duration, cc.p(-this._positionDelta.x, -this._positionDelta.y));
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -1420,7 +1430,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* @return {cc.MoveBy}
* @example
* // example
- * var actionTo = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
*/
cc.moveBy = function (duration, deltaPos, deltaY) {
return new cc.MoveBy(duration, deltaPos, deltaY);
@@ -1448,22 +1458,22 @@ cc.MoveBy.create = cc.moveBy;
* @param {cc.Point|Number} position
* @param {Number} y
* @example
- * var actionBy = new cc.MoveTo(2, cc.p(80, 80));
+ * var actionTo = new cc.MoveTo(2, cc.p(80, 80));
*/
cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
- _endPosition:null,
+ _endPosition: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration duration in seconds
- * @param {cc.Point|Number} position
- * @param {Number} y
- */
- ctor:function (duration, position, y) {
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} position
+ * @param {Number} y
+ */
+ ctor: function (duration, position, y) {
cc.MoveBy.prototype.ctor.call(this);
this._endPosition = cc.p(0, 0);
- position !== undefined && this.initWithDuration(duration, position, y);
+ position !== undefined && this.initWithDuration(duration, position, y);
},
/**
@@ -1473,12 +1483,12 @@ cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
* @param {Number} y
* @return {Boolean}
*/
- initWithDuration:function (duration, position, y) {
+ initWithDuration: function (duration, position, y) {
if (cc.MoveBy.prototype.initWithDuration.call(this, duration, position, y)) {
- if(position.x !== undefined) {
- y = position.y;
- position = position.x;
- }
+ if (position.x !== undefined) {
+ y = position.y;
+ position = position.x;
+ }
this._endPosition.x = position;
this._endPosition.y = y;
@@ -1491,7 +1501,7 @@ cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
* returns a new clone of the action
* @returns {cc.MoveTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.MoveTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._endPosition);
@@ -1502,7 +1512,7 @@ cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.MoveBy.prototype.startWithTarget.call(this, target);
this._positionDelta.x = this._endPosition.x - target.getPositionX();
this._positionDelta.y = this._endPosition.y - target.getPositionY();
@@ -1514,12 +1524,12 @@ cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
* Moving to the specified coordinates.
* @function
* @param {Number} duration duration in seconds
- * @param {cc.Point} position
+ * @param {cc.Point|Number} position
* @param {Number} y
- * @return {cc.MoveBy}
+ * @return {cc.MoveTo}
* @example
* // example
- * var actionBy = cc.moveTo(2, cc.p(80, 80));
+ * var actionTo = cc.moveTo(2, cc.p(80, 80));
*/
cc.moveTo = function (duration, position, y) {
return new cc.MoveTo(duration, position, y);
@@ -1530,9 +1540,9 @@ cc.moveTo = function (duration, position, y) {
* @static
* @deprecated since v3.0 Please use cc.moveTo instead.
* @param {Number} duration duration in seconds
- * @param {cc.Point} position
+ * @param {cc.Point|Number} position
* @param {Number} y
- * @return {cc.MoveBy}
+ * @return {cc.MoveTo}
*/
cc.MoveTo.create = cc.moveTo;
@@ -1547,25 +1557,25 @@ cc.MoveTo.create = cc.moveTo;
* var actionTo = new cc.SkewTo(2, 37.2, -37.2);
*/
cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{
- _skewX:0,
- _skewY:0,
- _startSkewX:0,
- _startSkewY:0,
- _endSkewX:0,
- _endSkewY:0,
- _deltaX:0,
- _deltaY:0,
-
- /**
+ _skewX: 0,
+ _skewY: 0,
+ _startSkewX: 0,
+ _startSkewY: 0,
+ _endSkewX: 0,
+ _endSkewY: 0,
+ _deltaX: 0,
+ _deltaY: 0,
+
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} t time in seconds
- * @param {Number} sx
- * @param {Number} sy
- */
+ * @param {Number} t time in seconds
+ * @param {Number} sx
+ * @param {Number} sy
+ */
ctor: function (t, sx, sy) {
cc.ActionInterval.prototype.ctor.call(this);
- sy !== undefined && this.initWithDuration(t, sx, sy);
+ sy !== undefined && this.initWithDuration(t, sx, sy);
},
/**
@@ -1575,7 +1585,7 @@ cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{
* @param {Number} sy
* @return {Boolean}
*/
- initWithDuration:function (t, sx, sy) {
+ initWithDuration: function (t, sx, sy) {
var ret = false;
if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
this._endSkewX = sx;
@@ -1589,7 +1599,7 @@ cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{
* returns a new clone of the action
* @returns {cc.SkewTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.SkewTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._endSkewX, this._endSkewY);
@@ -1600,7 +1610,7 @@ cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._startSkewX = target.skewX % 180;
@@ -1622,7 +1632,7 @@ cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
this.target.skewX = this._startSkewX + this._deltaX * dt;
this.target.skewY = this._startSkewY + this._deltaY * dt;
@@ -1668,16 +1678,16 @@ cc.SkewTo.create = cc.skewTo;
*/
cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} t time in seconds
- * @param {Number} sx skew in degrees for X axis
- * @param {Number} sy skew in degrees for Y axis
- */
- ctor: function(t, sx, sy) {
- cc.SkewTo.prototype.ctor.call(this);
- sy !== undefined && this.initWithDuration(t, sx, sy);
- },
+ * @param {Number} t time in seconds
+ * @param {Number} sx skew in degrees for X axis
+ * @param {Number} sy skew in degrees for Y axis
+ */
+ ctor: function (t, sx, sy) {
+ cc.SkewTo.prototype.ctor.call(this);
+ sy !== undefined && this.initWithDuration(t, sx, sy);
+ },
/**
* Initializes the action.
@@ -1686,7 +1696,7 @@ cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{
* @param {Number} deltaSkewY skew in degrees for Y axis
* @return {Boolean}
*/
- initWithDuration:function (t, deltaSkewX, deltaSkewY) {
+ initWithDuration: function (t, deltaSkewX, deltaSkewY) {
var ret = false;
if (cc.SkewTo.prototype.initWithDuration.call(this, t, deltaSkewX, deltaSkewY)) {
this._skewX = deltaSkewX;
@@ -1700,7 +1710,7 @@ cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{
* returns a new clone of the action
* @returns {cc.SkewBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.SkewBy();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._skewX, this._skewY);
@@ -1711,7 +1721,7 @@ cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{
* Start the action width target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.SkewTo.prototype.startWithTarget.call(this, target);
this._deltaX = this._skewX;
this._deltaY = this._skewY;
@@ -1723,7 +1733,7 @@ cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{
* Returns a reversed action.
* @return {cc.SkewBy}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.SkewBy(this._duration, -this._skewX, -this._skewY);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -1775,27 +1785,27 @@ cc.SkewBy.create = cc.skewBy;
* var actionBy = new cc.JumpBy(2, 300, 0, 50, 4);
*/
cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
- _startPosition:null,
- _delta:null,
- _height:0,
- _jumps:0,
- _previousPosition:null,
+ _startPosition: null,
+ _delta: null,
+ _height: 0,
+ _jumps: 0,
+ _previousPosition: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration
- * @param {cc.Point|Number} position
- * @param {Number} [y]
- * @param {Number} height
- * @param {Number} jumps
- */
- ctor:function (duration, position, y, height, jumps) {
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ */
+ ctor: function (duration, position, y, height, jumps) {
cc.ActionInterval.prototype.ctor.call(this);
this._startPosition = cc.p(0, 0);
this._previousPosition = cc.p(0, 0);
this._delta = cc.p(0, 0);
- height !== undefined && this.initWithDuration(duration, position, y, height, jumps);
+ height !== undefined && this.initWithDuration(duration, position, y, height, jumps);
},
/**
* Initializes the action.
@@ -1809,14 +1819,14 @@ cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
* actionBy.initWithDuration(2, cc.p(300, 0), 50, 4);
* actionBy.initWithDuration(2, 300, 0, 50, 4);
*/
- initWithDuration:function (duration, position, y, height, jumps) {
+ initWithDuration: function (duration, position, y, height, jumps) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
- if (jumps === undefined) {
- jumps = height;
- height = y;
- y = position.y;
- position = position.x;
- }
+ if (jumps === undefined) {
+ jumps = height;
+ height = y;
+ y = position.y;
+ position = position.x;
+ }
this._delta.x = position;
this._delta.y = y;
this._height = height;
@@ -1830,7 +1840,7 @@ cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
* returns a new clone of the action
* @returns {cc.JumpBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.JumpBy();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._delta, this._height, this._jumps);
@@ -1841,7 +1851,7 @@ cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
var locPosX = target.getPositionX();
var locPosY = target.getPositionY();
@@ -1855,7 +1865,7 @@ cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
var frac = dt * this._jumps % 1.0;
@@ -1873,9 +1883,9 @@ cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
x = x + locStartPosition.x;
y = y + locStartPosition.y;
- locPreviousPosition.x = x;
- locPreviousPosition.y = y;
- this.target.setPosition(x, y);
+ locPreviousPosition.x = x;
+ locPreviousPosition.y = y;
+ this.target.setPosition(x, y);
} else {
this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
}
@@ -1886,7 +1896,7 @@ cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
* Returns a reversed action.
* @return {cc.JumpBy}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.JumpBy(this._duration, cc.p(-this._delta.x, -this._delta.y), this._height, this._jumps);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -1942,7 +1952,7 @@ cc.JumpBy.create = cc.jumpBy;
* var actionTo = new cc.JumpTo(2, 300, 0, 50, 4);
*/
cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{
- _endPosition:null,
+ _endPosition: null,
/**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
@@ -1952,7 +1962,7 @@ cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{
* @param {Number} height
* @param {Number} jumps
*/
- ctor:function (duration, position, y, height, jumps) {
+ ctor: function (duration, position, y, height, jumps) {
cc.JumpBy.prototype.ctor.call(this);
this._endPosition = cc.p(0, 0);
@@ -1970,7 +1980,7 @@ cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{
* actionTo.initWithDuration(2, cc.p(300, 0), 50, 4);
* actionTo.initWithDuration(2, 300, 0, 50, 4);
*/
- initWithDuration:function (duration, position, y, height, jumps) {
+ initWithDuration: function (duration, position, y, height, jumps) {
if (cc.JumpBy.prototype.initWithDuration.call(this, duration, position, y, height, jumps)) {
if (jumps === undefined) {
y = position.y;
@@ -1986,7 +1996,7 @@ cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.JumpBy.prototype.startWithTarget.call(this, target);
this._delta.x = this._endPosition.x - this._startPosition.x;
this._delta.y = this._endPosition.y - this._startPosition.y;
@@ -1996,7 +2006,7 @@ cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{
* returns a new clone of the action
* @returns {cc.JumpTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.JumpTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._endPosition, this._height, this._jumps);
@@ -2048,9 +2058,9 @@ cc.JumpTo.create = cc.jumpTo;
*/
cc.bezierAt = function (a, b, c, d, t) {
return (Math.pow(1 - t, 3) * a +
- 3 * t * (Math.pow(1 - t, 2)) * b +
- 3 * Math.pow(t, 2) * (1 - t) * c +
- Math.pow(t, 3) * d );
+ 3 * t * (Math.pow(1 - t, 2)) * b +
+ 3 * Math.pow(t, 2) * (1 - t) * c +
+ Math.pow(t, 3) * d );
};
/** An action that moves the target with a cubic Bezier curve by a certain distance.
@@ -2064,22 +2074,22 @@ cc.bezierAt = function (a, b, c, d, t) {
* var bezierForward = new cc.BezierBy(3, bezier);
*/
cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
- _config:null,
- _startPosition:null,
- _previousPosition:null,
+ _config: null,
+ _startPosition: null,
+ _previousPosition: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} t time in seconds
- * @param {Array} c Array of points
- */
- ctor:function (t, c) {
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ */
+ ctor: function (t, c) {
cc.ActionInterval.prototype.ctor.call(this);
this._config = [];
this._startPosition = cc.p(0, 0);
this._previousPosition = cc.p(0, 0);
- c && this.initWithDuration(t, c);
+ c && this.initWithDuration(t, c);
},
/**
@@ -2088,7 +2098,7 @@ cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
* @param {Array} c Array of points
* @return {Boolean}
*/
- initWithDuration:function (t, c) {
+ initWithDuration: function (t, c) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
this._config = c;
return true;
@@ -2100,7 +2110,7 @@ cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
* returns a new clone of the action
* @returns {cc.BezierBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.BezierBy();
this._cloneDecoration(action);
var newConfigs = [];
@@ -2116,7 +2126,7 @@ cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
var locPosX = target.getPositionX();
var locPosY = target.getPositionY();
@@ -2130,7 +2140,7 @@ cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
var locConfig = this._config;
@@ -2157,9 +2167,9 @@ cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
x = x + locStartPosition.x;
y = y + locStartPosition.y;
- locPreviousPosition.x = x;
- locPreviousPosition.y = y;
- this.target.setPosition(x, y);
+ locPreviousPosition.x = x;
+ locPreviousPosition.y = y;
+ this.target.setPosition(x, y);
} else {
this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
}
@@ -2170,12 +2180,12 @@ cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
* Returns a reversed action.
* @return {cc.BezierBy}
*/
- reverse:function () {
+ reverse: function () {
var locConfig = this._config;
var r = [
cc.pAdd(locConfig[1], cc.pNeg(locConfig[2])),
cc.pAdd(locConfig[0], cc.pNeg(locConfig[2])),
- cc.pNeg(locConfig[2]) ];
+ cc.pNeg(locConfig[2])];
var action = new cc.BezierBy(this._duration, r);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -2221,18 +2231,18 @@ cc.BezierBy.create = cc.bezierBy;
* var bezierTo = new cc.BezierTo(2, bezier);
*/
cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{
- _toConfig:null,
+ _toConfig: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} t
- * @param {Array} c array of points
- * var bezierTo = new cc.BezierTo(2, bezier);
- */
- ctor:function (t, c) {
+ * @param {Number} t
+ * @param {Array} c array of points
+ * var bezierTo = new cc.BezierTo(2, bezier);
+ */
+ ctor: function (t, c) {
cc.BezierBy.prototype.ctor.call(this);
this._toConfig = [];
- c && this.initWithDuration(t, c);
+ c && this.initWithDuration(t, c);
},
/**
@@ -2241,7 +2251,7 @@ cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{
* @param {Array} c Array of points
* @return {Boolean}
*/
- initWithDuration:function (t, c) {
+ initWithDuration: function (t, c) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
this._toConfig = c;
return true;
@@ -2253,7 +2263,7 @@ cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{
* returns a new clone of the action
* @returns {cc.BezierTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.BezierTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._toConfig);
@@ -2264,7 +2274,7 @@ cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.BezierBy.prototype.startWithTarget.call(this, target);
var locStartPos = this._startPosition;
var locToConfig = this._toConfig;
@@ -2315,24 +2325,24 @@ cc.BezierTo.create = cc.bezierTo;
* var actionTo = new cc.ScaleTo(2, 0.5, 2);
*/
cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{
- _scaleX:1,
- _scaleY:1,
- _startScaleX:1,
- _startScaleY:1,
- _endScaleX:0,
- _endScaleY:0,
- _deltaX:0,
- _deltaY:0,
-
- /**
+ _scaleX: 1,
+ _scaleY: 1,
+ _startScaleX: 1,
+ _startScaleY: 1,
+ _endScaleX: 0,
+ _endScaleY: 0,
+ _deltaX: 0,
+ _deltaY: 0,
+
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration
- * @param {Number} sx scale parameter in X
- * @param {Number} [sy] scale parameter in Y, if Null equal to sx
- */
- ctor:function (duration, sx, sy) {
+ * @param {Number} duration
+ * @param {Number} sx scale parameter in X
+ * @param {Number} [sy] scale parameter in Y, if Null equal to sx
+ */
+ ctor: function (duration, sx, sy) {
cc.ActionInterval.prototype.ctor.call(this);
- sx !== undefined && this.initWithDuration(duration, sx, sy);
+ sx !== undefined && this.initWithDuration(duration, sx, sy);
},
/**
@@ -2342,7 +2352,7 @@ cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{
* @param {Number} [sy=]
* @return {Boolean}
*/
- initWithDuration:function (duration, sx, sy) { //function overload here
+ initWithDuration: function (duration, sx, sy) { //function overload here
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._endScaleX = sx;
this._endScaleY = (sy != null) ? sy : sx;
@@ -2355,7 +2365,7 @@ cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{
* returns a new clone of the action
* @returns {cc.ScaleTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.ScaleTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._endScaleX, this._endScaleY);
@@ -2366,7 +2376,7 @@ cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._startScaleX = target.scaleX;
this._startScaleY = target.scaleY;
@@ -2378,11 +2388,11 @@ cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
this.target.scaleX = this._startScaleX + this._deltaX * dt;
- this.target.scaleY = this._startScaleY + this._deltaY * dt;
+ this.target.scaleY = this._startScaleY + this._deltaY * dt;
}
}
});
@@ -2427,7 +2437,7 @@ cc.ScaleBy = cc.ScaleTo.extend(/** @lends cc.ScaleBy# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ScaleTo.prototype.startWithTarget.call(this, target);
this._deltaX = this._startScaleX * this._endScaleX - this._startScaleX;
this._deltaY = this._startScaleY * this._endScaleY - this._startScaleY;
@@ -2437,7 +2447,7 @@ cc.ScaleBy = cc.ScaleTo.extend(/** @lends cc.ScaleBy# */{
* Returns a reversed action.
* @return {cc.ScaleBy}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.ScaleBy(this._duration, 1 / this._endScaleX, 1 / this._endScaleY);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -2448,7 +2458,7 @@ cc.ScaleBy = cc.ScaleTo.extend(/** @lends cc.ScaleBy# */{
* returns a new clone of the action
* @returns {cc.ScaleBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.ScaleBy();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._endScaleX, this._endScaleY);
@@ -2495,17 +2505,17 @@ cc.ScaleBy.create = cc.scaleBy;
* var action = new cc.Blink(2, 10);
*/
cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
- _times:0,
- _originalState:false,
+ _times: 0,
+ _originalState: false,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
* @param {Number} duration duration in seconds
- * @param {Number} blinks blinks in times
- */
- ctor:function (duration, blinks) {
+ * @param {Number} blinks blinks in times
+ */
+ ctor: function (duration, blinks) {
cc.ActionInterval.prototype.ctor.call(this);
- blinks !== undefined && this.initWithDuration(duration, blinks);
+ blinks !== undefined && this.initWithDuration(duration, blinks);
},
/**
@@ -2514,7 +2524,7 @@ cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
* @param {Number} blinks blinks in times
* @return {Boolean}
*/
- initWithDuration:function (duration, blinks) {
+ initWithDuration: function (duration, blinks) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._times = blinks;
return true;
@@ -2526,7 +2536,7 @@ cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
* returns a new clone of the action
* @returns {cc.Blink}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Blink();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._times);
@@ -2537,7 +2547,7 @@ cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt time in seconds
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target && !this.isDone()) {
var slice = 1.0 / this._times;
@@ -2550,7 +2560,7 @@ cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._originalState = target.visible;
},
@@ -2558,7 +2568,7 @@ cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
/**
* stop the action
*/
- stop:function () {
+ stop: function () {
this.target.visible = this._originalState;
cc.ActionInterval.prototype.stop.call(this);
},
@@ -2567,7 +2577,7 @@ cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
* Returns a reversed action.
* @return {cc.Blink}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.Blink(this._duration, this._times);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -2608,17 +2618,17 @@ cc.Blink.create = cc.blink;
* var action = new cc.FadeTo(1.0, 0);
*/
cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{
- _toOpacity:0,
- _fromOpacity:0,
+ _toOpacity: 0,
+ _fromOpacity: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration
- * @param {Number} opacity 0-255, 0 is transparent
- */
- ctor:function (duration, opacity) {
+ * @param {Number} duration
+ * @param {Number} opacity 0-255, 0 is transparent
+ */
+ ctor: function (duration, opacity) {
cc.ActionInterval.prototype.ctor.call(this);
- opacity !== undefined && this.initWithDuration(duration, opacity);
+ opacity !== undefined && this.initWithDuration(duration, opacity);
},
/**
@@ -2627,7 +2637,7 @@ cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{
* @param {Number} opacity
* @return {Boolean}
*/
- initWithDuration:function (duration, opacity) {
+ initWithDuration: function (duration, opacity) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._toOpacity = opacity;
return true;
@@ -2639,7 +2649,7 @@ cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{
* returns a new clone of the action
* @returns {cc.FadeTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.FadeTo();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._toOpacity);
@@ -2650,7 +2660,7 @@ cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} time time in seconds
*/
- update:function (time) {
+ update: function (time) {
time = this._computeEaseTime(time);
var fromOpacity = this._fromOpacity !== undefined ? this._fromOpacity : 255;
this.target.opacity = fromOpacity + (this._toOpacity - fromOpacity) * time;
@@ -2660,7 +2670,7 @@ cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{
* Start this action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._fromOpacity = target.opacity;
}
@@ -2703,7 +2713,7 @@ cc.FadeIn = cc.FadeTo.extend(/** @lends cc.FadeIn# */{
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
* @param {Number} duration duration in seconds
*/
- ctor:function (duration) {
+ ctor: function (duration) {
cc.FadeTo.prototype.ctor.call(this);
if (duration == null)
duration = 0;
@@ -2714,7 +2724,7 @@ cc.FadeIn = cc.FadeTo.extend(/** @lends cc.FadeIn# */{
* Returns a reversed action.
* @return {cc.FadeOut}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.FadeOut();
action.initWithDuration(this._duration, 0);
this._cloneDecoration(action);
@@ -2726,7 +2736,7 @@ cc.FadeIn = cc.FadeTo.extend(/** @lends cc.FadeIn# */{
* returns a new clone of the action
* @returns {cc.FadeIn}
*/
- clone:function () {
+ clone: function () {
var action = new cc.FadeIn();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._toOpacity);
@@ -2737,8 +2747,8 @@ cc.FadeIn = cc.FadeTo.extend(/** @lends cc.FadeIn# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
- if(this._reverseAction)
+ startWithTarget: function (target) {
+ if (this._reverseAction)
this._toOpacity = this._reverseAction._fromOpacity;
cc.FadeTo.prototype.startWithTarget.call(this, target);
}
@@ -2779,7 +2789,7 @@ cc.FadeOut = cc.FadeTo.extend(/** @lends cc.FadeOut# */{
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
* @param {Number} duration duration in seconds
*/
- ctor:function (duration) {
+ ctor: function (duration) {
cc.FadeTo.prototype.ctor.call(this);
if (duration == null)
duration = 0;
@@ -2790,7 +2800,7 @@ cc.FadeOut = cc.FadeTo.extend(/** @lends cc.FadeOut# */{
* Returns a reversed action.
* @return {cc.FadeIn}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.FadeIn();
action._reverseAction = this;
action.initWithDuration(this._duration, 255);
@@ -2803,7 +2813,7 @@ cc.FadeOut = cc.FadeTo.extend(/** @lends cc.FadeOut# */{
* returns a new clone of the action
* @returns {cc.FadeOut}
*/
- clone:function () {
+ clone: function () {
var action = new cc.FadeOut();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._toOpacity);
@@ -2845,22 +2855,22 @@ cc.FadeOut.create = cc.fadeOut;
* var action = new cc.TintTo(2, 255, 0, 255);
*/
cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{
- _to:null,
- _from:null,
+ _to: null,
+ _from: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration
- * @param {Number} red 0-255
- * @param {Number} green 0-255
- * @param {Number} blue 0-255
- */
- ctor:function (duration, red, green, blue) {
+ * @param {Number} duration
+ * @param {Number} red 0-255
+ * @param {Number} green 0-255
+ * @param {Number} blue 0-255
+ */
+ ctor: function (duration, red, green, blue) {
cc.ActionInterval.prototype.ctor.call(this);
this._to = cc.color(0, 0, 0);
this._from = cc.color(0, 0, 0);
- blue !== undefined && this.initWithDuration(duration, red, green, blue);
+ blue !== undefined && this.initWithDuration(duration, red, green, blue);
},
/**
@@ -2871,7 +2881,7 @@ cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{
* @param {Number} blue 0-255
* @return {Boolean}
*/
- initWithDuration:function (duration, red, green, blue) {
+ initWithDuration: function (duration, red, green, blue) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._to = cc.color(red, green, blue);
return true;
@@ -2883,7 +2893,7 @@ cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{
* returns a new clone of the action
* @returns {cc.TintTo}
*/
- clone:function () {
+ clone: function () {
var action = new cc.TintTo();
this._cloneDecoration(action);
var locTo = this._to;
@@ -2895,7 +2905,7 @@ cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._from = this.target.color;
@@ -2905,13 +2915,16 @@ cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt time in seconds
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
var locFrom = this._from, locTo = this._to;
if (locFrom) {
- this.target.color = cc.color(locFrom.r + (locTo.r - locFrom.r) * dt,
- locFrom.g + (locTo.g - locFrom.g) * dt,
- locFrom.b + (locTo.b - locFrom.b) * dt);
+ this.target.setColor(
+ cc.color(
+ locFrom.r + (locTo.r - locFrom.r) * dt,
+ locFrom.g + (locTo.g - locFrom.g) * dt,
+ locFrom.b + (locTo.b - locFrom.b) * dt)
+ );
}
}
});
@@ -2957,24 +2970,24 @@ cc.TintTo.create = cc.tintTo;
* var action = new cc.TintBy(2, -127, -255, -127);
*/
cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
- _deltaR:0,
- _deltaG:0,
- _deltaB:0,
+ _deltaR: 0,
+ _deltaG: 0,
+ _deltaB: 0,
- _fromR:0,
- _fromG:0,
- _fromB:0,
+ _fromR: 0,
+ _fromG: 0,
+ _fromB: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {Number} duration duration in seconds
- * @param {Number} deltaRed
- * @param {Number} deltaGreen
- * @param {Number} deltaBlue
- */
- ctor:function (duration, deltaRed, deltaGreen, deltaBlue) {
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaRed
+ * @param {Number} deltaGreen
+ * @param {Number} deltaBlue
+ */
+ ctor: function (duration, deltaRed, deltaGreen, deltaBlue) {
cc.ActionInterval.prototype.ctor.call(this);
- deltaBlue !== undefined && this.initWithDuration(duration, deltaRed, deltaGreen, deltaBlue);
+ deltaBlue !== undefined && this.initWithDuration(duration, deltaRed, deltaGreen, deltaBlue);
},
/**
@@ -2985,7 +2998,7 @@ cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
* @param {Number} deltaBlue 0-255
* @return {Boolean}
*/
- initWithDuration:function (duration, deltaRed, deltaGreen, deltaBlue) {
+ initWithDuration: function (duration, deltaRed, deltaGreen, deltaBlue) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._deltaR = deltaRed;
this._deltaG = deltaGreen;
@@ -2999,7 +3012,7 @@ cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
* returns a new clone of the action
* @returns {cc.TintBy}
*/
- clone:function () {
+ clone: function () {
var action = new cc.TintBy();
this._cloneDecoration(action);
action.initWithDuration(this._duration, this._deltaR, this._deltaG, this._deltaB);
@@ -3010,7 +3023,7 @@ cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
var color = target.color;
@@ -3024,12 +3037,12 @@ cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt time in seconds
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
this.target.color = cc.color(this._fromR + this._deltaR * dt,
- this._fromG + this._deltaG * dt,
- this._fromB + this._deltaB * dt);
+ this._fromG + this._deltaG * dt,
+ this._fromB + this._deltaB * dt);
},
@@ -3037,7 +3050,7 @@ cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
* Returns a reversed action.
* @return {cc.TintBy}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.TintBy(this._duration, -this._deltaR, -this._deltaG, -this._deltaB);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -3085,13 +3098,14 @@ cc.DelayTime = cc.ActionInterval.extend(/** @lends cc.DelayTime# */{
* Will be overwrite.
* @param {Number} dt time in seconds
*/
- update:function (dt) {},
+ update: function (dt) {
+ },
/**
* Returns a reversed action.
* @return {cc.DelayTime}
*/
- reverse:function () {
+ reverse: function () {
var action = new cc.DelayTime(this._duration);
this._cloneDecoration(action);
this._reverseEaseList(action);
@@ -3102,7 +3116,7 @@ cc.DelayTime = cc.ActionInterval.extend(/** @lends cc.DelayTime# */{
* returns a new clone of the action
* @returns {cc.DelayTime}
*/
- clone:function () {
+ clone: function () {
var action = new cc.DelayTime();
this._cloneDecoration(action);
action.initWithDuration(this._duration);
@@ -3146,28 +3160,28 @@ cc.DelayTime.create = cc.delayTime;
* var reverse = new cc.ReverseTime(this);
*/
cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{
- _other:null,
+ _other: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * @param {cc.FiniteTimeAction} action
- */
- ctor:function (action) {
+ * @param {cc.FiniteTimeAction} action
+ */
+ ctor: function (action) {
cc.ActionInterval.prototype.ctor.call(this);
this._other = null;
- action && this.initWithAction(action);
+ action && this.initWithAction(action);
},
/**
* @param {cc.FiniteTimeAction} action
* @return {Boolean}
*/
- initWithAction:function (action) {
- if(!action)
- throw "cc.ReverseTime.initWithAction(): action must be non null";
- if(action === this._other)
- throw "cc.ReverseTime.initWithAction(): the action was already passed in.";
+ initWithAction: function (action) {
+ if (!action)
+ throw new Error("cc.ReverseTime.initWithAction(): action must be non null");
+ if (action === this._other)
+ throw new Error("cc.ReverseTime.initWithAction(): the action was already passed in.");
if (cc.ActionInterval.prototype.initWithDuration.call(this, action._duration)) {
// Don't leak if action is reused
@@ -3181,7 +3195,7 @@ cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{
* returns a new clone of the action
* @returns {cc.ReverseTime}
*/
- clone:function () {
+ clone: function () {
var action = new cc.ReverseTime();
this._cloneDecoration(action);
action.initWithAction(this._other.clone());
@@ -3192,7 +3206,7 @@ cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._other.startWithTarget(target);
},
@@ -3201,7 +3215,7 @@ cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt time in seconds
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
if (this._other)
this._other.update(1 - dt);
@@ -3211,14 +3225,14 @@ cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{
* Returns a reversed action.
* @return {cc.ActionInterval}
*/
- reverse:function () {
+ reverse: function () {
return this._other.clone();
},
/**
* Stop the action
*/
- stop:function () {
+ stop: function () {
this._other.stop();
cc.Action.prototype.stop.call(this);
}
@@ -3256,45 +3270,54 @@ cc.ReverseTime.create = cc.reverseTime;
* var anim = new cc.Animate(dance_grey);
*/
cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
- _animation:null,
- _nextFrame:0,
- _origFrame:null,
- _executedLoops:0,
- _splitTimes:null,
+ _animation: null,
+ _nextFrame: 0,
+ _origFrame: null,
+ _executedLoops: 0,
+ _splitTimes: null,
+ _currFrameIndex: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * create the animate with animation.
- * @param {cc.Animation} animation
- */
- ctor:function (animation) {
+ * create the animate with animation.
+ * @param {cc.Animation} animation
+ */
+ ctor: function (animation) {
cc.ActionInterval.prototype.ctor.call(this);
this._splitTimes = [];
- animation && this.initWithAnimation(animation);
+ animation && this.initWithAnimation(animation);
},
/**
* @return {cc.Animation}
*/
- getAnimation:function () {
+ getAnimation: function () {
return this._animation;
},
/**
* @param {cc.Animation} animation
*/
- setAnimation:function (animation) {
+ setAnimation: function (animation) {
this._animation = animation;
},
+ /**
+ * Gets the index of sprite frame currently displayed.
+ * @return {Number}
+ */
+ getCurrentFrameIndex: function () {
+ return this._currFrameIndex;
+ },
+
/**
* @param {cc.Animation} animation
* @return {Boolean}
*/
- initWithAnimation:function (animation) {
- if(!animation)
- throw "cc.Animate.initWithAnimation(): animation must be non-NULL";
+ initWithAnimation: function (animation) {
+ if (!animation)
+ throw new Error("cc.Animate.initWithAnimation(): animation must be non-NULL");
var singleDuration = animation.getDuration();
if (this.initWithDuration(singleDuration * animation.getLoops())) {
this._nextFrame = 0;
@@ -3326,7 +3349,7 @@ cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
* returns a new clone of the action
* @returns {cc.Animate}
*/
- clone:function () {
+ clone: function () {
var action = new cc.Animate();
this._cloneDecoration(action);
action.initWithAnimation(this._animation.clone());
@@ -3337,10 +3360,10 @@ cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
* Start the action with target.
* @param {cc.Sprite} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
if (this._animation.getRestoreOriginalFrame())
- this._origFrame = target.displayFrame();
+ this._origFrame = target.getSpriteFrame();
this._nextFrame = 0;
this._executedLoops = 0;
},
@@ -3349,7 +3372,7 @@ cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
// if t==1, ignore. Animation should finish with t==1
if (dt < 1.0) {
@@ -3370,7 +3393,8 @@ cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
var numberOfFrames = frames.length, locSplitTimes = this._splitTimes;
for (var i = this._nextFrame; i < numberOfFrames; i++) {
if (locSplitTimes[i] <= dt) {
- this.target.setSpriteFrame(frames[i].getSpriteFrame());
+ _currFrameIndex = i;
+ this.target.setSpriteFrame(frames[_currFrameIndex].getSpriteFrame());
this._nextFrame = i + 1;
} else {
// Issue 1438. Could be more than one frame per tick, due to low frame rate or frame delta < 1/FPS
@@ -3383,7 +3407,7 @@ cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
* Returns a reversed action.
* @return {cc.Animate}
*/
- reverse:function () {
+ reverse: function () {
var locAnimation = this._animation;
var oldArray = locAnimation.getFrames();
var newArray = [];
@@ -3408,7 +3432,7 @@ cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
/**
* stop the action
*/
- stop:function () {
+ stop: function () {
if (this._animation.getRestoreOriginalFrame() && this.target)
this.target.setSpriteFrame(this._origFrame);
cc.Action.prototype.stop.call(this);
@@ -3449,18 +3473,18 @@ cc.Animate.create = cc.animate;
* @param {cc.FiniteTimeAction} action
*/
cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
- _action:null,
- _forcedTarget:null,
+ _action: null,
+ _forcedTarget: null,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * Create an action with the specified action and forced target.
- * @param {cc.Node} target
- * @param {cc.FiniteTimeAction} action
- */
+ * Create an action with the specified action and forced target.
+ * @param {cc.Node} target
+ * @param {cc.FiniteTimeAction} action
+ */
ctor: function (target, action) {
cc.ActionInterval.prototype.ctor.call(this);
- action && this.initWithTarget(target, action);
+ action && this.initWithTarget(target, action);
},
/**
@@ -3469,7 +3493,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
* @param {cc.FiniteTimeAction} action
* @return {Boolean}
*/
- initWithTarget:function (target, action) {
+ initWithTarget: function (target, action) {
if (this.initWithDuration(action._duration)) {
this._forcedTarget = target;
this._action = action;
@@ -3482,7 +3506,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
* returns a new clone of the action
* @returns {cc.TargetedAction}
*/
- clone:function () {
+ clone: function () {
var action = new cc.TargetedAction();
this._cloneDecoration(action);
action.initWithTarget(this._forcedTarget, this._action.clone());
@@ -3493,7 +3517,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
* Start the action with target.
* @param {cc.Node} target
*/
- startWithTarget:function (target) {
+ startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._action.startWithTarget(this._forcedTarget);
},
@@ -3501,7 +3525,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
/**
* stop the action
*/
- stop:function () {
+ stop: function () {
this._action.stop();
},
@@ -3509,7 +3533,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
* Called once per frame. Time is the number of seconds of a frame interval.
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
dt = this._computeEaseTime(dt);
this._action.update(dt);
},
@@ -3518,7 +3542,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
* return the target that the action will be forced to run with
* @return {cc.Node}
*/
- getForcedTarget:function () {
+ getForcedTarget: function () {
return this._forcedTarget;
},
@@ -3526,7 +3550,7 @@ cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
* set the target that the action will be forced to run with
* @param {cc.Node} forcedTarget
*/
- setForcedTarget:function (forcedTarget) {
+ setForcedTarget: function (forcedTarget) {
if (this._forcedTarget !== forcedTarget)
this._forcedTarget = forcedTarget;
}
diff --git a/cocos2d/actions/CCActionTween.js b/cocos2d/actions/CCActionTween.js
index 12490a4146..daa6c368d1 100644
--- a/cocos2d/actions/CCActionTween.js
+++ b/cocos2d/actions/CCActionTween.js
@@ -36,7 +36,8 @@ cc.ActionTweenDelegate = cc.Class.extend(/** @lends cc.ActionTweenDelegate */{
* @param value
* @param key
*/
- updateTweenAction:function(value, key){}
+ updateTweenAction: function (value, key) {
+ }
});
/**
@@ -60,24 +61,24 @@ cc.ActionTweenDelegate = cc.Class.extend(/** @lends cc.ActionTweenDelegate */{
* @param {Number} to
*/
cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
- key:"",
- from:0,
- to:0,
- delta:0,
+ key: "",
+ from: 0,
+ to: 0,
+ delta: 0,
- /**
+ /**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * Creates an initializes the action with the property name (key), and the from and to parameters.
- * @param {Number} duration
- * @param {String} key
- * @param {Number} from
- * @param {Number} to
- */
- ctor:function(duration, key, from, to){
+ * Creates an initializes the action with the property name (key), and the from and to parameters.
+ * @param {Number} duration
+ * @param {String} key
+ * @param {Number} from
+ * @param {Number} to
+ */
+ ctor: function (duration, key, from, to) {
cc.ActionInterval.prototype.ctor.call(this);
this.key = "";
- to !== undefined && this.initWithDuration(duration, key, from, to);
+ to !== undefined && this.initWithDuration(duration, key, from, to);
},
/**
@@ -88,7 +89,7 @@ cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
* @param {Number} to
* @return {Boolean}
*/
- initWithDuration:function (duration, key, from, to) {
+ initWithDuration: function (duration, key, from, to) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this.key = key;
this.to = to;
@@ -102,9 +103,9 @@ cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
* Start this tween with target.
* @param {cc.ActionTweenDelegate} target
*/
- startWithTarget:function (target) {
- if(!target || !target.updateTweenAction)
- throw "cc.ActionTween.startWithTarget(): target must be non-null, and target must implement updateTweenAction function";
+ startWithTarget: function (target) {
+ if (!target || !target.updateTweenAction)
+ throw new Error("cc.ActionTween.startWithTarget(): target must be non-null, and target must implement updateTweenAction function");
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this.delta = this.to - this.from;
},
@@ -114,7 +115,7 @@ cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
*
* @param {Number} dt
*/
- update:function (dt) {
+ update: function (dt) {
this.target.updateTweenAction(this.to - this.delta * (1 - dt), this.key);
},
@@ -122,7 +123,7 @@ cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
* returns a reversed action.
* @return {cc.ActionTween}
*/
- reverse:function () {
+ reverse: function () {
return new cc.ActionTween(this.duration, this.key, this.to, this.from);
},
@@ -132,7 +133,7 @@ cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
*
* @return {cc.ActionTween}
*/
- clone:function(){
+ clone: function () {
var action = new cc.ActionTween();
action.initWithDuration(this._duration, this.key, this.from, this.to);
return action;
@@ -163,4 +164,4 @@ cc.actionTween = function (duration, key, from, to) {
* @param {Number} to
* @return {cc.ActionTween}
*/
-cc.ActionTween.create = cc.actionTween;
\ No newline at end of file
+cc.ActionTween.create = cc.actionTween;
diff --git a/cocos2d/actions3d/CCActionGrid.js b/cocos2d/actions3d/CCActionGrid.js
index 38b5c8a37f..61b90a1454 100644
--- a/cocos2d/actions3d/CCActionGrid.js
+++ b/cocos2d/actions3d/CCActionGrid.js
@@ -41,20 +41,22 @@ cc.GridAction = cc.ActionInterval.extend(/** @lends cc.GridAction# */{
* @param {cc.Size} gridSize
*/
ctor:function(duration, gridSize){
- cc._checkWebGLRenderMode();
+ cc.sys._checkWebGLRenderMode();
cc.ActionInterval.prototype.ctor.call(this);
this._gridSize = cc.size(0,0);
- gridSize && this.initWithDuration(duration, gridSize);
+ gridSize && this.initWithDuration(duration, gridSize);
},
- _cacheTargetAsGridNode: function(){},
+ _cacheTargetAsGridNode:function (target) {
+ this._gridNodeTarget = target;
+ },
/**
* to copy object with deep copy.
* returns a clone of action.
*
- * @return {cc.Action}
+ * @return {cc.ActionInterval}
*/
clone:function(){
var action = new cc.GridAction();
@@ -71,9 +73,11 @@ cc.GridAction = cc.ActionInterval.extend(/** @lends cc.GridAction# */{
startWithTarget:function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
cc.renderer.childrenOrderDirty = true;
+ this._cacheTargetAsGridNode(target);
+
var newGrid = this.getGrid();
- var t = this.target;
- var targetGrid = t.grid;
+
+ var targetGrid = this._gridNodeTarget.getGrid();
if (targetGrid && targetGrid.getReuseGrid() > 0) {
var locGridSize = targetGrid.getGridSize();
if (targetGrid.isActive() && (locGridSize.width === this._gridSize.width) && (locGridSize.height === this._gridSize.height))
@@ -81,8 +85,8 @@ cc.GridAction = cc.ActionInterval.extend(/** @lends cc.GridAction# */{
} else {
if (targetGrid && targetGrid.isActive())
targetGrid.setActive(false);
- t.grid = newGrid;
- t.grid.setActive(true);
+ this._gridNodeTarget.setGrid(newGrid);
+ this._gridNodeTarget.getGrid().setActive(true);
}
},
@@ -154,7 +158,15 @@ cc.Grid3DAction = cc.GridAction.extend(/** @lends cc.Grid3DAction# */{
* @return {cc.Grid3D}
*/
getGrid:function () {
- return new cc.Grid3D(this._gridSize);
+ return new cc.Grid3D(this._gridSize, undefined, undefined, this._gridNodeTarget.getGridRect());
+ },
+
+ /**
+ * get rect of the grid
+ * @return {cc.Rect} rect
+ */
+ getGridRect:function () {
+ return this._gridNodeTarget.getGridRect();
},
/**
@@ -187,7 +199,7 @@ cc.Grid3DAction = cc.GridAction.extend(/** @lends cc.Grid3DAction# */{
},
/**
- * returns the non-transformed vertex than belongs to certain position in the grid
+ * returns the non-transformed vertex that belongs to certain position in the grid
* @param {cc.Point} position
* @return {cc.Vertex3F}
*/
@@ -285,7 +297,7 @@ cc.TiledGrid3DAction = cc.GridAction.extend(/** @lends cc.TiledGrid3DAction# */{
* @return {cc.TiledGrid3D}
*/
getGrid:function () {
- return new cc.TiledGrid3D(this._gridSize);
+ return new cc.TiledGrid3D(this._gridSize, undefined, undefined, this._gridNodeTarget.getGridRect());
}
});
diff --git a/cocos2d/actions3d/CCActionPageTurn3D.js b/cocos2d/actions3d/CCActionPageTurn3D.js
index a28f0d4852..ae7313b2dd 100644
--- a/cocos2d/actions3d/CCActionPageTurn3D.js
+++ b/cocos2d/actions3d/CCActionPageTurn3D.js
@@ -37,7 +37,7 @@
*/
cc.PageTurn3D = cc.Grid3DAction.extend(/** @lends cc.PageTurn3D# */{
getGrid: function(){
- var result = new cc.Grid3D(this._gridSize);
+ var result = new cc.Grid3D(this._gridSize, undefined, undefined, this._gridNodeTarget.getGridRect());
result.setNeedDepthTestForBlit(true);
return result;
},
@@ -57,8 +57,9 @@ cc.PageTurn3D = cc.Grid3DAction.extend(/** @lends cc.PageTurn3D# */{
var deltaAy = (tt * tt * 500);
var ay = -100 - deltaAy;
- var deltaTheta = -Math.PI / 2 * Math.sqrt(time);
- var theta = /*0.01f */ +Math.PI / 2 + deltaTheta;
+ var deltaTheta = Math.sqrt(time);
+ var theta = deltaTheta>0.5?Math.PI/2 *deltaTheta : Math.PI/2*(1-deltaTheta);
+ var rotateByYAxis = (2-time)*Math.PI;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
@@ -72,6 +73,7 @@ cc.PageTurn3D = cc.Grid3DAction.extend(/** @lends cc.PageTurn3D# */{
// Get original vertex
var p = this.getOriginalVertex(locVer);
+ p.x -= this.getGridRect().x;
var R = Math.sqrt((p.x * p.x) + ((p.y - ay) * (p.y - ay)));
var r = R * sinTheta;
var alpha = Math.asin(p.x / R);
@@ -89,14 +91,17 @@ cc.PageTurn3D = cc.Grid3DAction.extend(/** @lends cc.PageTurn3D# */{
// We scale z here to avoid the animation being
// too much bigger than the screen due to perspectve transform
- p.z = (r * ( 1 - cosBeta ) * cosTheta) / 7;// "100" didn't work for
-
+ p.z = (r * ( 1 - cosBeta ) * cosTheta);// "100" didn't work for
+ p.x = p.z * Math.sin(rotateByYAxis) + p.x * Math.cos(rotateByYAxis);
+ p.z = p.z * Math.cos(rotateByYAxis) - p.x * Math.cos(rotateByYAxis);
+ p.z/= 7;
// Stop z coord from dropping beneath underlying page in a transition
// issue #751
if (p.z < 0.5)
p.z = 0.5;
// Set new coords
+ p.x+= this.getGridRect().x;
this.setVertex(locVer, p);
}
}
diff --git a/cocos2d/actions3d/CCActionTiledGrid.js b/cocos2d/actions3d/CCActionTiledGrid.js
index dae3d8daa2..67dffc5aa4 100644
--- a/cocos2d/actions3d/CCActionTiledGrid.js
+++ b/cocos2d/actions3d/CCActionTiledGrid.js
@@ -451,15 +451,16 @@ cc.ShuffleTiles.create = cc.shuffleTiles;
cc.FadeOutTRTiles = cc.TiledGrid3DAction.extend(/** @lends cc.FadeOutTRTiles# */{
/**
* Test function
- * @param {cc.Size} pos
+ * @param {cc.Point} pos
* @param {Number} time
*/
testFunc:function (pos, time) {
var locX = this._gridSize.width * time;
var locY = this._gridSize.height * time;
+ if (locX === this._gridSize.width && locY === this._gridSize.height) return 0.0;
if ((locX + locY) === 0.0)
return 1.0;
- return Math.pow((pos.width + pos.height) / (locX + locY), 6);
+ return Math.pow((pos.x + pos.y) / (locX + locY), 6);
},
/**
@@ -508,14 +509,12 @@ cc.FadeOutTRTiles = cc.TiledGrid3DAction.extend(/** @lends cc.FadeOutTRTiles# */
*/
update:function (dt) {
var locGridSize = this._gridSize;
- var locPos = cc.p(0, 0), locSize = cc.size(0, 0), distance;
+ var locPos = cc.p(0, 0), distance;
for (var i = 0; i < locGridSize.width; ++i) {
for (var j = 0; j < locGridSize.height; ++j) {
locPos.x = i;
locPos.y = j;
- locSize.width = i;
- locSize.height = j;
- distance = this.testFunc(locSize, dt);
+ distance = this.testFunc(locPos, dt);
if (distance === 0)
this.turnOffTile(locPos);
else if (distance < 1)
@@ -560,16 +559,18 @@ cc.FadeOutTRTiles.create = cc.fadeOutTRTiles;
cc.FadeOutBLTiles = cc.FadeOutTRTiles.extend(/** @lends cc.FadeOutBLTiles# */{
/**
* Test function
- * @param {cc.Size} pos
+ * @param {cc.Point} pos
* @param {Number} time
*/
testFunc:function (pos, time) {
var locX = this._gridSize.width * (1.0 - time);
var locY = this._gridSize.height * (1.0 - time);
- if ((pos.width + pos.height) === 0)
+ if ((locX + locY) === 0)
+ return 0.0;
+ if ((pos.x + pos.y) === 0)
return 1.0;
- return Math.pow((locX + locY) / (pos.width + pos.height), 6);
+ return Math.pow((locX + locY) / (pos.x + pos.y), 6);
}
});
@@ -604,11 +605,16 @@ cc.FadeOutBLTiles.create = cc.fadeOutBLTiles;
* @extends cc.FadeOutTRTiles
*/
cc.FadeOutUpTiles = cc.FadeOutTRTiles.extend(/** @lends cc.FadeOutUpTiles# */{
+ /**
+ * Test function
+ * @param {cc.Point} pos
+ * @param {Number} time
+ */
testFunc:function (pos, time) {
var locY = this._gridSize.height * time;
- if (locY === 0.0)
- return 1.0;
- return Math.pow(pos.height / locY, 6);
+ if( locY === this._gridSize.height) return 0.0;
+ if (locY === 0.0) return 1.0;
+ return Math.pow(pos.y / locY, 6);
},
transformTile:function (pos, distance) {
@@ -655,11 +661,16 @@ cc.FadeOutUpTiles.create = cc.fadeOutUpTiles;
* @extends cc.FadeOutUpTiles
*/
cc.FadeOutDownTiles = cc.FadeOutUpTiles.extend(/** @lends cc.FadeOutDownTiles# */{
+ /**
+ * Test function
+ * @param {cc.Point} pos
+ * @param {Number} time
+ */
testFunc:function (pos, time) {
var locY = this._gridSize.height * (1.0 - time);
- if (pos.height === 0)
- return 1.0;
- return Math.pow(locY / pos.height, 6);
+ if( locY === 0.0 ) return 0.0;
+ if (pos.y === 0) return 1.0;
+ return Math.pow(locY / pos.y, 6);
}
});
diff --git a/cocos2d/audio/CCAudio.js b/cocos2d/audio/CCAudio.js
index e3890afd59..7762bf4d02 100644
--- a/cocos2d/audio/CCAudio.js
+++ b/cocos2d/audio/CCAudio.js
@@ -27,132 +27,53 @@
/**
* Audio support in the browser
*
- * multichannel : Multiple audio while playing - If it doesn't, you can only play background music
- * webAudio : Support for WebAudio - Support W3C WebAudio standards, all of the audio can be played
- * auto : Supports auto-play audio - if Don‘t support it, On a touch detecting background music canvas, and then replay
- * replay : The first music will fail, must be replay after touchstart
- * emptied : Whether to use the emptied event to replace load callback
- * delay : delay created the context object - only webAudio
+ * MULTI_CHANNEL : Multiple audio while playing - If it doesn't, you can only play background music
+ * WEB_AUDIO : Support for WebAudio - Support W3C WebAudio standards, all of the audio can be played
+ * AUTOPLAY : Supports auto-play audio - if Don‘t support it, On a touch detecting background music canvas, and then replay
+ * REPLAY_AFTER_TOUCH : The first music will fail, must be replay after touchstart
+ * USE_EMPTIED_EVENT : Whether to use the emptied event to replace load callback
+ * DELAY_CREATE_CTX : delay created the context object - only webAudio
+ * NEED_MANUAL_LOOP : loop attribute failure, need to perform loop manually
*
* May be modifications for a few browser version
*/
-(function(){
+(function () {
var DEBUG = false;
var sys = cc.sys;
+ var version = sys.browserVersion;
- var supportTable = {
- "common" : {multichannel: true , webAudio: cc.sys._supportWebAudio , auto: true }
- };
- supportTable[sys.BROWSER_TYPE_IE] = {multichannel: true , webAudio: cc.sys._supportWebAudio , auto: true, emptied: true};
- // ANDROID //
- supportTable[sys.BROWSER_TYPE_ANDROID] = {multichannel: false, webAudio: false, auto: false};
- supportTable[sys.BROWSER_TYPE_CHROME] = {multichannel: true , webAudio: true , auto: false};
- supportTable[sys.BROWSER_TYPE_FIREFOX] = {multichannel: true , webAudio: true , auto: true , delay: true};
- supportTable[sys.BROWSER_TYPE_UC] = {multichannel: true , webAudio: false, auto: false};
- supportTable[sys.BROWSER_TYPE_QQ] = {multichannel: false, webAudio: false, auto: true };
- supportTable[sys.BROWSER_TYPE_OUPENG] = {multichannel: false, webAudio: false, auto: false, replay: true , emptied: true };
- supportTable[sys.BROWSER_TYPE_WECHAT] = {multichannel: false, webAudio: false, auto: false, replay: true , emptied: true };
- supportTable[sys.BROWSER_TYPE_360] = {multichannel: false, webAudio: false, auto: true };
- supportTable[sys.BROWSER_TYPE_MIUI] = {multichannel: false, webAudio: false, auto: true };
- supportTable[sys.BROWSER_TYPE_LIEBAO] = {multichannel: false, webAudio: false, auto: false, replay: true , emptied: true };
- supportTable[sys.BROWSER_TYPE_SOUGOU] = {multichannel: false, webAudio: false, auto: false, replay: true , emptied: true };
- //"Baidu" browser can automatically play
- //But because it may be play failed, so need to replay and auto
- supportTable[sys.BROWSER_TYPE_BAIDU] = {multichannel: false, webAudio: false, auto: false, replay: true , emptied: true };
- supportTable[sys.BROWSER_TYPE_BAIDU_APP]= {multichannel: false, webAudio: false, auto: false, replay: true , emptied: true };
-
- // APPLE //
- supportTable[sys.BROWSER_TYPE_SAFARI] = {multichannel: true , webAudio: true , auto: false, webAudioCallback: function(realUrl){
- document.createElement("audio").src = realUrl;
- }};
-
- /* Determine the browser version number */
- var version, tmp;
- try{
- var ua = navigator.userAgent.toLowerCase();
- switch(sys.browserType){
- case sys.BROWSER_TYPE_IE:
- tmp = ua.match(/(msie |rv:)([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_FIREFOX:
- tmp = ua.match(/(firefox\/|rv:)([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_CHROME:
- tmp = ua.match(/chrome\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_BAIDU:
- tmp = ua.match(/baidubrowser\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_UC:
- tmp = ua.match(/ucbrowser\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_QQ:
- tmp = ua.match(/qqbrowser\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_OUPENG:
- tmp = ua.match(/oupeng\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_WECHAT:
- tmp = ua.match(/micromessenger\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_SAFARI:
- tmp = ua.match(/safari\/([\d.]+)/);
- break;
- case sys.BROWSER_TYPE_MIUI:
- tmp = ua.match(/miuibrowser\/([\d.]+)/);
- break;
- }
- version = tmp ? tmp[1] : "";
- }catch(e){
- console.log(e);
+ // check if browser supports Web Audio
+ // check Web Audio's context
+ var supportWebAudio = !!(window.AudioContext || window.webkitAudioContext || window.mozAudioContext);
+
+ var support = {ONLY_ONE: false, WEB_AUDIO: supportWebAudio, DELAY_CREATE_CTX: false, ONE_SOURCE: false};
+
+ if (sys.browserType === sys.BROWSER_TYPE_FIREFOX) {
+ support.DELAY_CREATE_CTX = true;
+ support.USE_LOADER_EVENT = 'canplay';
}
- ///////////////////////////
- // Browser compatibility//
- ///////////////////////////
- if(version){
- switch(sys.browserType){
- case sys.BROWSER_TYPE_CHROME:
- if(parseInt(version) < 30){
- supportTable[sys.BROWSER_TYPE_CHROME] = {multichannel: false , webAudio: true , auto: false};
- }
- break;
- case sys.BROWSER_TYPE_MIUI:
- version = version.match(/\d+/g);
- if(version[0] < 2 || (version[0] === 2 && version[1] === 0 && version[2] <= 1)){
- supportTable[sys.BROWSER_TYPE_MIUI].auto = false;
- }
- break;
- }
+ if (sys.os === sys.OS_IOS) {
+ support.USE_LOADER_EVENT = 'loadedmetadata';
}
- if(cc.sys.isMobile){
- if(cc.sys.os !== cc.sys.OS_IOS)
- cc.__audioSupport = supportTable[sys.browserType] || supportTable["common"];
- else
- cc.__audioSupport = supportTable[sys.BROWSER_TYPE_SAFARI];
- }else{
- switch(sys.browserType){
- case sys.BROWSER_TYPE_IE:
- cc.__audioSupport = supportTable[sys.BROWSER_TYPE_IE];
- break;
- case sys.BROWSER_TYPE_FIREFOX:
- cc.__audioSupport = supportTable[sys.BROWSER_TYPE_FIREFOX];
- break;
- default:
- cc.__audioSupport = supportTable["common"];
- }
+ if (sys.os === sys.OS_ANDROID) {
+ if (sys.browserType === sys.BROWSER_TYPE_UC) {
+ support.ONE_SOURCE = true;
+ }
}
- if(DEBUG){
- setTimeout(function(){
+ window.__audioSupport = support;
+
+ if (DEBUG) {
+ setTimeout(function () {
cc.log("browse type: " + sys.browserType);
cc.log("browse version: " + version);
- cc.log("multichannel: " + cc.__audioSupport.multichannel);
- cc.log("webAudio: " + cc.__audioSupport.webAudio);
- cc.log("auto: " + cc.__audioSupport.auto);
+ cc.log("MULTI_CHANNEL: " + window.__audioSupport.MULTI_CHANNEL);
+ cc.log("WEB_AUDIO: " + window.__audioSupport.WEB_AUDIO);
+ cc.log("AUTOPLAY: " + window.__audioSupport.AUTOPLAY);
}, 0);
}
@@ -162,313 +83,259 @@
* Encapsulate DOM and webAudio
*/
cc.Audio = cc.Class.extend({
- //TODO Maybe loader shift in will be better
- volume: 1,
- loop: false,
+ interruptPlay: false,
src: null,
- _touch: false,
-
- _playing: false,
- _AUDIO_TYPE: "AUDIO",
- _pause: false,
-
- //Web Audio
- _buffer: null,
- _currentSource: null,
- _startTime: null,
- _currentTime: null,
- _context: null,
- _volume: null,
-
- _ignoreEnded: false,
-
- //DOM Audio
_element: null,
+ _AUDIO_TYPE: "AUDIO",
- ctor: function(context, volume, url){
- context && (this._context = context);
- volume && (this._volume = volume);
- if(context && volume){
- this._AUDIO_TYPE = "WEBAUDIO";
- }
+ ctor: function (url) {
this.src = url;
},
- _setBufferCallback: null,
- setBuffer: function(buffer){
- if(!buffer) return;
- var playing = this._playing;
+ setBuffer: function (buffer) {
this._AUDIO_TYPE = "WEBAUDIO";
-
- if(this._buffer && this._buffer !== buffer && this.getPlaying())
- this.stop();
-
- this._buffer = buffer;
- if(playing)
- this.play();
-
- this._volume["gain"].value = this.volume;
- this._setBufferCallback && this._setBufferCallback(buffer);
+ this._element = new cc.Audio.WebAudio(buffer);
},
- _setElementCallback: null,
- setElement: function(element){
- if(!element) return;
- var playing = this._playing;
+ setElement: function (element) {
this._AUDIO_TYPE = "AUDIO";
-
- if(this._element && this._element !== element && this.getPlaying())
- this.stop();
-
this._element = element;
- if(playing)
- this.play();
- element.volume = this.volume;
- element.loop = this.loop;
- this._setElementCallback && this._setElementCallback(element);
- },
-
- play: function(offset, loop){
- this._playing = true;
- this.loop = loop === undefined ? this.loop : loop;
- if(this._AUDIO_TYPE === "AUDIO"){
- this._playOfAudio(offset);
- }else{
- this._playOfWebAudio(offset);
- }
- },
-
- getPlaying: function(){
- if(!this._playing){
- return this._playing;
- }
- if(this._AUDIO_TYPE === "AUDIO"){
- var audio = this._element;
- if(!audio || this._pause){
- this._playing = false;
- return false;
- }else if(audio.ended){
- this._playing = false;
- return false;
- }else
- return true;
- }else{
- var sourceNode = this._currentSource;
- if(!sourceNode)
- return true;
- if(sourceNode["playbackState"] == null)
- return this._playing;
- else
- return this._currentTime + this._context.currentTime - this._startTime < this._currentSource.buffer.duration;
- }
+ // Prevent partial browser from playing after the end does not reset the paused tag
+ // Will cause the player to judge the status of the error
+ element.addEventListener('ended', function () {
+ if (!element.loop) {
+ element.paused = true;
+ }
+ });
},
- _playOfWebAudio: function(offset){
- var cs = this._currentSource;
- if(!this._buffer){
+ play: function (offset, loop) {
+ if (!this._element) {
+ this.interruptPlay = false;
return;
}
- if(!this._pause && cs){
- if(this._context.currentTime === 0 || this._currentTime + this._context.currentTime - this._startTime > this._currentSource.buffer.duration)
- this._stopOfWebAudio();
- else
- return;
- }
- var audio = this._context["createBufferSource"]();
- audio.buffer = this._buffer;
- audio["connect"](this._volume);
- audio.loop = this.loop;
- this._startTime = this._context.currentTime;
- this._currentTime = offset || 0;
-
- /*
- * Safari on iOS 6 only supports noteOn(), noteGrainOn(), and noteOff() now.(iOS 6.1.3)
- * The latest version of chrome has supported start() and stop()
- * start() & stop() are specified in the latest specification (written on 04/26/2013)
- * Reference: https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
- * noteOn(), noteGrainOn(), and noteOff() are specified in Draft 13 version (03/13/2012)
- * Reference: http://www.w3.org/2011/audio/drafts/2WD/Overview.html
- */
- if(audio.start){
- audio.start(0, offset || 0);
- }else if(audio["noteGrainOn"]){
- var duration = audio.buffer.duration;
- if (this.loop) {
- /*
- * On Safari on iOS 6, if loop == true, the passed in @param duration will be the duration from now on.
- * In other words, the sound will keep playing the rest of the music all the time.
- * On latest chrome desktop version, the passed in duration will only be the duration in this cycle.
- * Now that latest chrome would have start() method, it is prepared for iOS here.
- */
- audio["noteGrainOn"](0, offset, duration);
- } else {
- audio["noteGrainOn"](0, offset, duration - offset);
- }
- }else {
- // if only noteOn() is supported, resuming sound will NOT work
- audio["noteOn"](0);
+ this._element.loop = loop;
+ this._element.play();
+ if (this._AUDIO_TYPE === 'AUDIO' && this._element.paused) {
+ this.stop();
+ cc.Audio.touchPlayList.push({ loop: loop, offset: offset, audio: this._element });
}
- this._currentSource = audio;
- var self = this;
- audio["onended"] = function(){
- if(self._ignoreEnded){
- self._ignoreEnded = false;
- }else{
- self._playing = false;
- }
- };
- },
- _playOfAudio: function(){
- var audio = this._element;
- if(audio){
- audio.loop = this.loop;
- audio.play();
+ if (cc.Audio.bindTouch === false) {
+ cc.Audio.bindTouch = true;
+ // Listen to the touchstart body event and play the audio when necessary.
+ cc.game.canvas.addEventListener('touchstart', cc.Audio.touchStart);
}
},
- stop: function(){
- this._playing = false;
- if(this._AUDIO_TYPE === "AUDIO"){
- this._stopOfAudio();
- }else{
- this._stopOfWebAudio();
- }
+ getPlaying: function () {
+ if (!this._element) return true;
+ return !this._element.paused;
},
- _stopOfWebAudio: function(){
- var audio = this._currentSource;
- this._ignoreEnded = true;
- if(audio){
- audio.stop(0);
- this._currentSource = null;
+ stop: function () {
+ if (!this._element) {
+ this.interruptPlay = true;
+ return;
+ }
+ this._element.pause();
+ try {
+ this._element.currentTime = 0;
+ } catch (err) {
}
},
- _stopOfAudio: function(){
- var audio = this._element;
- if(audio){
- audio.pause();
- if (audio.duration && audio.duration !== Infinity)
- audio.currentTime = 0;
+ pause: function () {
+ if (!this._element) {
+ this.interruptPlay = true;
+ return;
}
+ this._element.pause();
},
- pause: function(){
- if(this.getPlaying() === false)
+ resume: function () {
+ if (!this._element) {
+ this.interruptPlay = false;
return;
- this._playing = false;
- this._pause = true;
- if(this._AUDIO_TYPE === "AUDIO"){
- this._pauseOfAudio();
- }else{
- this._pauseOfWebAudio();
}
+ this._element.play();
},
- _pauseOfWebAudio: function(){
- this._currentTime += this._context.currentTime - this._startTime;
- var audio = this._currentSource;
- if(audio){
- audio.stop(0);
- }
+ setVolume: function (volume) {
+ if (!this._element) return;
+ this._element.volume = volume;
},
- _pauseOfAudio: function(){
- var audio = this._element;
- if(audio){
- audio.pause();
- }
+ getVolume: function () {
+ if (!this._element) return;
+ return this._element.volume;
},
- resume: function(){
- if(this._pause){
- if(this._AUDIO_TYPE === "AUDIO"){
- this._resumeOfAudio();
- }else{
- this._resumeOfWebAudio();
+ cloneNode: function () {
+ var audio = new cc.Audio(this.src);
+ if (this._AUDIO_TYPE === "AUDIO") {
+ var elem = document.createElement("audio");
+ var sources = elem.getElementsByTagName('source');
+ for (var i = 0; i < sources.length; i++) {
+ elem.appendChild(sources[i]);
}
- this._pause = false;
- this._playing = true;
+ elem.src = this.src;
+ audio.setElement(elem);
+ } else {
+ audio.setBuffer(this._element.buffer);
}
- },
+ return audio;
+ }
+});
- _resumeOfWebAudio: function(){
- var audio = this._currentSource;
- if(audio){
- this._startTime = this._context.currentTime;
- var offset = this._currentTime % audio.buffer.duration;
- this._playOfWebAudio(offset);
- }
+cc.Audio.touchPlayList = [
+ //{ offset: 0, audio: audio }
+];
+
+cc.Audio.bindTouch = false;
+cc.Audio.touchStart = function () {
+ var list = cc.Audio.touchPlayList;
+ var item = null;
+ while (item = list.pop()) {
+ item.audio.loop = !!item.loop;
+ item.audio.play(item.offset);
+ }
+};
+
+cc.Audio.WebAudio = function (buffer) {
+ this.buffer = buffer;
+ this.context = cc.Audio._context;
+
+ var volume = this.context['createGain']();
+ volume['gain'].value = 1;
+ volume['connect'](this.context['destination']);
+ this._volume = volume;
+
+ this._loop = false;
+
+ // The time stamp on the audio time axis when the recording begins to play.
+ this._startTime = -1;
+ // Record the currently playing Source
+ this._currentSource = null;
+ // Record the time has been played
+ this.playedLength = 0;
+
+ this._currextTimer = null;
+};
+
+cc.Audio.WebAudio.prototype = {
+ constructor: cc.Audio.WebAudio,
+
+ get paused() {
+ // If the current audio is a loop, then paused is false
+ if (this._currentSource && this._currentSource.loop)
+ return false;
+
+ // StartTime does not have value, as the default -1, it does not begin to play
+ if (this._startTime === -1)
+ return true;
+
+ // currentTime - startTime > durationTime
+ return this.context.currentTime - this._startTime > this.buffer.duration;
+ },
+ set paused(bool) {
},
- _resumeOfAudio: function(){
- var audio = this._element;
- if(audio){
- audio.play();
- }
+ get loop() {
+ return this._loop;
+ },
+ set loop(bool) {
+ return this._loop = bool;
},
- setVolume: function(volume){
- if(volume > 1) volume = 1;
- if(volume < 0) volume = 0;
- this.volume = volume;
- if(this._AUDIO_TYPE === "AUDIO"){
- if(this._element){
- this._element.volume = volume;
- }
- }else{
- if(this._volume){
- this._volume["gain"].value = volume;
- }
- }
+ get volume() {
+ return this._volume['gain'].value;
+ },
+ set volume(num) {
+ return this._volume['gain'].value = num;
},
- getVolume: function(){
- return this.volume;
+ get currentTime() {
+ return this.playedLength;
+ },
+ set currentTime(num) {
+ return this.playedLength = num;
},
- cloneNode: function(){
- var audio, self;
- if(this._AUDIO_TYPE === "AUDIO"){
- audio = new cc.Audio();
+ play: function (offset) {
- var elem = document.createElement("audio");
- elem.src = this.src;
- audio.setElement(elem);
- }else{
- var volume = this._context["createGain"]();
- volume["gain"].value = 1;
- volume["connect"](this._context["destination"]);
- audio = new cc.Audio(this._context, volume, this.src);
- if(this._buffer){
- audio.setBuffer(this._buffer);
- }else{
- self = this;
- this._setBufferCallback = function(buffer){
- audio.setBuffer(buffer);
- self._setBufferCallback = null;
- };
- }
+ // If repeat play, you need to stop before an audio
+ if (this._currentSource && !this.paused) {
+ this._currentSource.stop(0);
+ this.playedLength = 0;
}
- audio._AUDIO_TYPE = this._AUDIO_TYPE;
- return audio;
- }
-});
+ var audio = this.context["createBufferSource"]();
+ audio.buffer = this.buffer;
+ audio["connect"](this._volume);
+ audio.loop = this._loop;
+
+ this._startTime = this.context.currentTime;
+ offset = offset || this.playedLength;
-(function(polyfill){
+ var duration = this.buffer.duration;
+ if (!this._loop) {
+ if (audio.start)
+ audio.start(0, offset, duration - offset);
+ else if (audio["notoGrainOn"])
+ audio["noteGrainOn"](0, offset, duration - offset);
+ else
+ audio["noteOn"](0, offset, duration - offset);
+ } else {
+ if (audio.start)
+ audio.start(0);
+ else if (audio["notoGrainOn"])
+ audio["noteGrainOn"](0);
+ else
+ audio["noteOn"](0);
+ }
- var SWA = polyfill.webAudio,
- SWB = polyfill.multichannel,
- SWC = polyfill.auto;
+ this._currentSource = audio;
+
+ // If the current audio context time stamp is 0
+ // There may be a need to touch events before you can actually start playing audio
+ // So here to add a timer to determine whether the real start playing audio, if not, then the incoming touchPlay queue
+ if (this.context.currentTime === 0) {
+ var self = this;
+ clearTimeout(this._currextTimer);
+ this._currextTimer = setTimeout(function () {
+ if (self.context.currentTime === 0) {
+ cc.Audio.touchPlayList.push({
+ offset: offset,
+ audio: self
+ });
+ }
+ }, 10);
+ }
+ },
+ pause: function () {
+ // Record the time the current has been played
+ this.playedLength = this.context.currentTime - this._startTime;
+ //If the duration of playedLendth exceeds the audio, you should take the remainder
+ this.playedLength %= this.buffer.duration;
+ var audio = this._currentSource;
+ this._currentSource = null;
+ this._startTime = -1;
+ if (audio)
+ audio.stop(0);
+ }
+};
+
+(function (polyfill) {
+
+ var SWA = polyfill.WEB_AUDIO, SWB = polyfill.ONLY_ONE;
var support = [];
- (function(){
+ (function () {
var audio = document.createElement("audio");
- if(audio.canPlayType) {
+ if (audio.canPlayType) {
var ogg = audio.canPlayType('audio/ogg; codecs="vorbis"');
if (ogg && ogg !== "") support.push(".ogg");
var mp3 = audio.canPlayType("audio/mpeg");
@@ -481,158 +348,161 @@ cc.Audio = cc.Class.extend({
if (m4a && m4a !== "") support.push(".m4a");
}
})();
- try{
- if(SWA){
+ try {
+ if (SWA) {
var context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
- if(polyfill.delay)
- setTimeout(function(){ context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)(); }, 0);
+ cc.Audio._context = context;
+ // check context integrity
+ if (
+ !context["createBufferSource"] ||
+ !context["createGain"] ||
+ !context["destination"] ||
+ !context["decodeAudioData"]
+ ) {
+ throw 'context is incomplete';
+ }
+ if (polyfill.DELAY_CREATE_CTX)
+ setTimeout(function () {
+ context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
+ cc.Audio._context = context;
+ }, 0);
}
- }catch(error){
+ } catch (error) {
SWA = false;
- cc.log("browser don't support webAudio");
+ cc.log("browser don't support web audio");
}
var loader = {
cache: {},
- load: function(realUrl, url, res, cb){
+ useWebAudio: true,
+
+ loadBuffer: function (url, cb) {
+ if (!SWA) return; // WebAudio Buffer
+
+ var request = cc.loader.getXMLHttpRequest();
+ request.open("GET", url, true);
+ request.responseType = "arraybuffer";
- if(support.length === 0)
+ // Our asynchronous callback
+ request.onload = function () {
+ if (request._timeoutId >= 0) {
+ clearTimeout(request._timeoutId);
+ }
+ context["decodeAudioData"](request.response, function (buffer) {
+ //success
+ cb(null, buffer);
+ //audio.setBuffer(buffer);
+ }, function () {
+ //error
+ cb('decode error - ' + url);
+ });
+ };
+
+ request.onerror = function () {
+ cb('request error - ' + url);
+ };
+ if (request.ontimeout === undefined) {
+ request._timeoutId = setTimeout(function () {
+ request.ontimeout();
+ }, request.timeout);
+ }
+ request.ontimeout = function () {
+ cb('request timeout - ' + url);
+ };
+
+ request.send();
+ },
+
+ load: function (realUrl, url, res, cb) {
+
+ if (support.length === 0)
return cb("can not support audio!");
- var i;
+ var audio = cc.loader.getRes(url);
+ if (audio)
+ return cb(null, audio);
+
+ if (cc.loader.audioPath)
+ realUrl = cc.path.join(cc.loader.audioPath, realUrl);
var extname = cc.path.extname(realUrl);
var typeList = [extname];
- for(i=0; itrue if the background music is playing, otherwise false
*/
- willPlayMusic: function(){return false;},
+ willPlayMusic: function () {
+ return false;
+ },
/**
* Play music.
@@ -661,16 +535,23 @@ cc.Audio = cc.Class.extend({
*/
playMusic: function(url, loop){
var bgMusic = this._currMusic;
- if(bgMusic && bgMusic.src !== url && bgMusic.getPlaying()){
+ if (bgMusic && bgMusic.getPlaying()) {
bgMusic.stop();
}
- var audio = loader.cache[url];
- if(!audio){
- cc.loader.load(url);
- audio = loader.cache[url];
+ var musicVolume = this._musicVolume;
+ var audio = cc.loader.getRes(url);
+ if (!audio) {
+ cc.loader.load(url, function () {
+ if (!audio.getPlaying() && !audio.interruptPlay) {
+ audio.setVolume(musicVolume);
+ audio.play(0, loop || false);
+ }
+ });
+ audio = cc.loader.getRes(url);
}
- audio.play(0, loop);
- audio.setVolume(this._musicVolume);
+ audio.setVolume(musicVolume);
+ audio.play(0, loop || false);
+
this._currMusic = audio;
},
@@ -683,8 +564,15 @@ cc.Audio = cc.Class.extend({
*/
stopMusic: function(releaseData){
var audio = this._currMusic;
- if(audio){
+ if (audio) {
+ var list = cc.Audio.touchPlayList;
+ for (var i=list.length-1; i>=0; --i) {
+ if (this[i] && this[i].audio === audio._element)
+ list.splice(i, 1);
+ }
+
audio.stop();
+ this._currMusic = null;
if (releaseData)
cc.loader.release(audio.src);
}
@@ -696,9 +584,9 @@ cc.Audio = cc.Class.extend({
* //example
* cc.audioEngine.pauseMusic();
*/
- pauseMusic: function(){
+ pauseMusic: function () {
var audio = this._currMusic;
- if(audio)
+ if (audio)
audio.pause();
},
@@ -708,9 +596,9 @@ cc.Audio = cc.Class.extend({
* //example
* cc.audioEngine.resumeMusic();
*/
- resumeMusic: function(){
+ resumeMusic: function () {
var audio = this._currMusic;
- if(audio)
+ if (audio)
audio.resume();
},
@@ -720,9 +608,9 @@ cc.Audio = cc.Class.extend({
* //example
* cc.audioEngine.rewindMusic();
*/
- rewindMusic: function(){
+ rewindMusic: function () {
var audio = this._currMusic;
- if(audio){
+ if (audio) {
audio.stop();
audio.play();
}
@@ -735,7 +623,7 @@ cc.Audio = cc.Class.extend({
* //example
* var volume = cc.audioEngine.getMusicVolume();
*/
- getMusicVolume: function(){
+ getMusicVolume: function () {
return this._musicVolume;
},
@@ -746,15 +634,15 @@ cc.Audio = cc.Class.extend({
* //example
* cc.audioEngine.setMusicVolume(0.5);
*/
- setMusicVolume: function(volume){
+ setMusicVolume: function (volume) {
volume = volume - 0;
- if(isNaN(volume)) volume = 1;
- if(volume > 1) volume = 1;
- if(volume < 0) volume = 0;
+ if (isNaN(volume)) volume = 1;
+ if (volume > 1) volume = 1;
+ if (volume < 0) volume = 0;
this._musicVolume = volume;
var audio = this._currMusic;
- if(audio){
+ if (audio) {
audio.setVolume(volume);
}
},
@@ -771,17 +659,17 @@ cc.Audio = cc.Class.extend({
* cc.log("music is not playing");
* }
*/
- isMusicPlaying: function(){
+ isMusicPlaying: function () {
var audio = this._currMusic;
- if(audio){
+ if (audio) {
return audio.getPlaying();
- }else{
+ } else {
return false;
}
},
_audioPool: {},
- _maxAudioInstance: 5,
+ _maxAudioInstance: 10,
_effectVolume: 1,
/**
* Play sound effect.
@@ -792,45 +680,76 @@ cc.Audio = cc.Class.extend({
* //example
* var soundId = cc.audioEngine.playEffect(path);
*/
- playEffect: function(url, loop){
- //If the browser just support playing single audio
- if(!SWB){
- //Must be forced to shut down
- //Because playing multichannel audio will be stuck in chrome 28 (android)
+ playEffect: function (url, loop) {
+
+ if (SWB && this._currMusic && this._currMusic.getPlaying()) {
+ cc.log('Browser is only allowed to play one audio');
return null;
}
var effectList = this._audioPool[url];
- if(!effectList){
+ if (!effectList) {
effectList = this._audioPool[url] = [];
}
- var i;
-
- for(i=0; i this._maxAudioInstance) {
+ var first = effectList.shift();
+ first.stop();
+ effectList.push(first);
+ i = effectList.length - 1;
+ // cc.log("Error: %s greater than %d", url, this._maxAudioInstance);
+ }
+
+ var audio;
+ if (effectList[i]) {
audio = effectList[i];
audio.setVolume(this._effectVolume);
- audio.play(0, loop);
- }else if(!SWA && i > this._maxAudioInstance){
- cc.log("Error: %s greater than %d", url, this._maxAudioInstance);
- }else{
- var audio = loader.cache[url];
- if(!audio){
- cc.loader.load(url);
- audio = loader.cache[url];
+ audio.play(0, loop || false);
+ return audio;
+ }
+
+ audio = cc.loader.getRes(url);
+
+ if (audio && SWA && audio._AUDIO_TYPE === 'AUDIO') {
+ cc.loader.release(url);
+ audio = null;
+ }
+
+ if (audio) {
+
+ if (SWA && audio._AUDIO_TYPE === 'AUDIO') {
+ loader.loadBuffer(url, function (error, buffer) {
+ audio.setBuffer(buffer);
+ audio.setVolume(cc.audioEngine._effectVolume);
+ if (!audio.getPlaying())
+ audio.play(0, loop || false);
+ });
+ } else {
+ audio = audio.cloneNode();
+ audio.setVolume(this._effectVolume);
+ audio.play(0, loop || false);
+ effectList.push(audio);
+ return audio;
}
+
+ }
+
+ var cache = loader.useWebAudio;
+ loader.useWebAudio = true;
+ cc.loader.load(url, function (audio) {
+ audio = cc.loader.getRes(url);
audio = audio.cloneNode();
- audio.setVolume(this._effectVolume);
- audio.loop = loop || false;
- audio.play();
+ audio.setVolume(cc.audioEngine._effectVolume);
+ audio.play(0, loop || false);
effectList.push(audio);
- }
+ });
+ loader.useWebAudio = cache;
return audio;
},
@@ -842,19 +761,19 @@ cc.Audio = cc.Class.extend({
* //example
* cc.audioEngine.setEffectsVolume(0.5);
*/
- setEffectsVolume: function(volume){
+ setEffectsVolume: function (volume) {
volume = volume - 0;
- if(isNaN(volume)) volume = 1;
- if(volume > 1) volume = 1;
- if(volume < 0) volume = 0;
+ if (isNaN(volume)) volume = 1;
+ if (volume > 1) volume = 1;
+ if (volume < 0) volume = 0;
this._effectVolume = volume;
var audioPool = this._audioPool;
- for(var p in audioPool){
+ for (var p in audioPool) {
var audioList = audioPool[p];
- if(Array.isArray(audioList))
- for(var i=0; i
* Event callback that is invoked every time when node enters the 'stage'.
@@ -90,7 +82,8 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
*/
onEnter: function () {
cc.Node.prototype.onEnter.call(this);
- this._stencil.onEnter();
+ if (this._stencil)
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onEnter);
},
/**
@@ -103,7 +96,8 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
*/
onEnterTransitionDidFinish: function () {
cc.Node.prototype.onEnterTransitionDidFinish.call(this);
- this._stencil.onEnterTransitionDidFinish();
+ if (this._stencil)
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
},
/**
@@ -115,7 +109,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
* @function
*/
onExitTransitionDidStart: function () {
- this._stencil.onExitTransitionDidStart();
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
cc.Node.prototype.onExitTransitionDidStart.call(this);
},
@@ -129,10 +123,29 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
* @function
*/
onExit: function () {
- this._stencil.onExit();
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onExit);
cc.Node.prototype.onExit.call(this);
},
+ visit: function (parent) {
+ this._renderCmd.clippingVisit(parent && parent._renderCmd);
+ },
+
+ _visitChildren: function () {
+ var renderer = cc.renderer;
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ var children = this._children, child;
+ for (var i = 0, len = children.length; i < len; i++) {
+ child = children[i];
+ if (child && child._visible) {
+ child.visit(this);
+ }
+ }
+ this._renderCmd._dirtyFlag = 0;
+ },
+
/**
*
* The alpha threshold.
@@ -143,7 +156,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
* @return {Number}
*/
getAlphaThreshold: function () {
- return this.alphaThreshold;
+ return this._alphaThreshold;
},
/**
@@ -151,7 +164,11 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
* @param {Number} alphaThreshold
*/
setAlphaThreshold: function (alphaThreshold) {
- this.alphaThreshold = alphaThreshold;
+ if (alphaThreshold === 1 && alphaThreshold !== this._alphaThreshold) {
+ // should reset program used by _stencil
+ this._renderCmd.resetProgramByStencil();
+ }
+ this._alphaThreshold = alphaThreshold;
},
/**
@@ -189,13 +206,15 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
* @param {cc.Node} stencil
*/
setStencil: function (stencil) {
- if(this._stencil === stencil)
+ if (this._stencil === stencil)
return;
+ if (stencil)
+ this._originStencilProgram = stencil.getShaderProgram();
this._renderCmd.setStencil(stencil);
},
- _createRenderCmd: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.ClippingNode.CanvasRenderCmd(this);
else
return new cc.ClippingNode.WebGLRenderCmd(this);
@@ -205,9 +224,13 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
var _p = cc.ClippingNode.prototype;
// Extended properties
-cc.defineGetterSetter(_p, "stencil", _p.getStencil, _p.setStencil);
/** @expose */
_p.stencil;
+cc.defineGetterSetter(_p, "stencil", _p.getStencil, _p.setStencil);
+/** @expose */
+_p.alphaThreshold;
+cc.defineGetterSetter(_p, "alphaThreshold", _p.getAlphaThreshold, _p.setAlphaThreshold);
+
/**
* Creates and initializes a clipping node with an other node as its stencil.
diff --git a/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js
index 9a0a0d8d2d..de4989921e 100644
--- a/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js
+++ b/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js
@@ -23,9 +23,9 @@
****************************************************************************/
//-------------------------- ClippingNode's canvas render cmd --------------------------------
-(function(){
- cc.ClippingNode.CanvasRenderCmd = function(renderable){
- cc.Node.CanvasRenderCmd.call(this, renderable);
+(function () {
+ cc.ClippingNode.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
this._needDraw = false;
this._godhelpme = false;
@@ -38,10 +38,15 @@
var proto = cc.ClippingNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
proto.constructor = cc.ClippingNode.CanvasRenderCmd;
- proto.initStencilBits = function(){};
+ proto.resetProgramByStencil = function () {
+
+ };
+
+ proto.initStencilBits = function () {
+ };
- proto.setStencil = function(stencil){
- if(stencil == null)
+ proto.setStencil = function (stencil) {
+ if (stencil == null)
return;
this._node._stencil = stencil;
@@ -49,40 +54,29 @@
// For shape stencil, rewrite the draw of stencil ,only init the clip path and draw nothing.
//else
if (stencil instanceof cc.DrawNode) {
- if(stencil._buffer){
- for(var i=0; i 0; j--)
+ context.lineTo(vertices[j].x, -vertices[j].y);
+ }
}
- context.closePath();
context.clip();
}
};
@@ -158,11 +159,13 @@
}
};
- proto.transform = function(parentCmd, recursive){
- cc.Node.CanvasRenderCmd.prototype.transform.call(this, parentCmd, recursive);
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
var node = this._node;
- if(node._stencil && node._stencil._renderCmd)
- node._stencil._renderCmd.transform(this, recursive);
+ if (node._stencil && node._stencil._renderCmd) {
+ node._stencil._renderCmd.transform(this, true);
+ node._stencil._dirtyFlag &= ~cc.Node._dirtyFlags.transformDirty;
+ }
};
proto._cangodhelpme = function (godhelpme) {
@@ -171,47 +174,40 @@
return cc.ClippingNode.CanvasRenderCmd.prototype._godhelpme;
};
- proto.visit = function(parentCmd){
+ proto.clippingVisit = function (parentCmd) {
var node = this._node;
- // quick return if not visible
- if (!node._visible)
- return;
-
parentCmd = parentCmd || this.getParentRenderCmd();
- if( parentCmd)
- this._curLevel = parentCmd._curLevel + 1;
- var transformRenderCmd = this;
+ this.visit(parentCmd);
// Composition mode, costy but support texture stencil
this._clipElemType = !(!this._cangodhelpme() && node._stencil instanceof cc.DrawNode);
if (!node._stencil || !node._stencil.visible) {
if (this.inverted)
- cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); // draw everything
+ node._visitChildren(); // draw everything
return;
}
- this._syncStatus(parentCmd);
cc.renderer.pushRenderCommand(this._rendererSaveCmd);
- if(this._clipElemType){
+ if (this._clipElemType) {
// Draw everything first using node visit function
- cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd);
- }else{
- node._stencil.visit(this);
+ node._visitChildren();
+ } else {
+ node._stencil.visit(node);
}
cc.renderer.pushRenderCommand(this._rendererClipCmd);
- if(this._clipElemType){
- node._stencil.visit(transformRenderCmd);
- }else{
- var i, children = node._children;
+ if (this._clipElemType) {
+ node._stencil.visit(node);
+ } else {
// Clip mode doesn't support recursive stencil, so once we used a clip stencil,
// so if it has ClippingNode as a child, the child must uses composition stencil.
this._cangodhelpme(true);
- var len = children.length;
+ var children = node._children;
+ var i, len = children.length;
if (len > 0) {
node.sortAllChildren();
for (i = 0; i < len; i++)
- children[i]._renderCmd.visit(this);
+ children[i].visit(node);
}
this._cangodhelpme(false);
}
@@ -224,4 +220,4 @@
cc.ClippingNode.CanvasRenderCmd._getSharedCache = function () {
return (cc.ClippingNode.CanvasRenderCmd._sharedCache) || (cc.ClippingNode.CanvasRenderCmd._sharedCache = document.createElement("canvas"));
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
index 0e199ff3b7..6d8956a32b 100644
--- a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
+++ b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
@@ -22,25 +22,28 @@
THE SOFTWARE.
****************************************************************************/
+function setProgram (node, program) {
+ node.shaderProgram = program;
+
+ var children = node.children;
+ if (!children)
+ return;
+
+ for (var i = 0; i < children.length; i++)
+ setProgram(children[i], program);
+}
+
// ------------------------------- ClippingNode's WebGL render cmd ------------------------------
-(function(){
- cc.ClippingNode.WebGLRenderCmd = function(renderable){
- cc.Node.WebGLRenderCmd.call(this, renderable);
+(function () {
+ cc.ClippingNode.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
this._needDraw = false;
this._beforeVisitCmd = new cc.CustomRenderCmd(this, this._onBeforeVisit);
this._afterDrawStencilCmd = new cc.CustomRenderCmd(this, this._onAfterDrawStencil);
this._afterVisitCmd = new cc.CustomRenderCmd(this, this._onAfterVisit);
- this._currentStencilFunc = null;
- this._currentStencilRef = null;
- this._currentStencilValueMask = null;
- this._currentStencilFail = null;
- this._currentStencilPassDepthFail = null;
- this._currentStencilPassDepthPass = null;
- this._currentStencilWriteMask = null;
this._currentStencilEnabled = null;
- this._currentDepthWriteMask = null;
this._mask_layer_le = null;
};
@@ -51,7 +54,7 @@
cc.ClippingNode.WebGLRenderCmd._visit_once = null;
cc.ClippingNode.WebGLRenderCmd._layer = -1;
- proto.initStencilBits = function(){
+ proto.initStencilBits = function () {
// get (only once) the number of bits of the stencil buffer
cc.ClippingNode.WebGLRenderCmd._init_once = true;
if (cc.ClippingNode.WebGLRenderCmd._init_once) {
@@ -62,32 +65,30 @@
}
};
- proto.transform = function(parentCmd, recursive){
+ proto.transform = function (parentCmd, recursive) {
var node = this._node;
- cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive);
- if(node._stencil)
- node._stencil._renderCmd.transform(this, recursive);
+ this.originTransform(parentCmd, recursive);
+ if (node._stencil) {
+ node._stencil._renderCmd.transform(this, true);
+ node._stencil._dirtyFlag &= ~cc.Node._dirtyFlags.transformDirty;
+ }
};
- proto.visit = function(parentCmd){
+ proto.clippingVisit = function (parentCmd) {
var node = this._node;
- // quick return if not visible
- if (!node._visible)
- return;
-
- if( node._parent && node._parent._renderCmd)
- this._curLevel = node._parent._renderCmd._curLevel + 1;
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ this.visit(parentCmd);
// if stencil buffer disabled
if (cc.stencilBits < 1) {
- // draw everything, as if there where no stencil
- cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd);
+ // draw everything, as if there were no stencil
+ node._visitChildren();
return;
}
if (!node._stencil || !node._stencil.visible) {
if (node.inverted)
- cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd); // draw everything
+ node._visitChildren(); // draw everything
return;
}
@@ -97,21 +98,15 @@
cc.log("Nesting more than " + cc.stencilBits + "stencils is not supported. Everything will be drawn without stencil for this node and its children.");
cc.ClippingNode.WebGLRenderCmd._visit_once = false;
}
- // draw everything, as if there where no stencil
- cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd);
+ // draw everything, as if there were no stencil
+ node._visitChildren();
return;
}
cc.renderer.pushRenderCommand(this._beforeVisitCmd);
- //optimize performance for javascript
- var currentStack = cc.current_stack;
- currentStack.stack.push(currentStack.top);
- this._syncStatus(parentCmd);
- currentStack.top = this._stackMatrix;
-
- //this._stencil._stackMatrix = this._stackMatrix;
- node._stencil._renderCmd.visit(this);
+ // node._stencil._stackMatrix = node._stackMatrix;
+ node._stencil.visit(node);
cc.renderer.pushRenderCommand(this._afterDrawStencilCmd);
@@ -122,54 +117,33 @@
node.sortAllChildren();
// draw children zOrder < 0
for (var i = 0; i < childLen; i++) {
- locChildren[i]._renderCmd.visit(this);
+ locChildren[i].visit(node);
}
}
cc.renderer.pushRenderCommand(this._afterVisitCmd);
this._dirtyFlag = 0;
- //optimize performance for javascript
- currentStack.top = currentStack.stack.pop();
};
- proto.setStencil = function(stencil){
+ proto.setStencil = function (stencil) {
var node = this._node;
- if(node._stencil)
+ if (node._stencil)
node._stencil._parent = null;
node._stencil = stencil;
- if(node._stencil)
+ if (node._stencil)
node._stencil._parent = node;
};
- proto._drawFullScreenQuadClearStencil = function () {
- // draw a fullscreen solid rectangle to clear the stencil buffer
- var projStack = cc.projection_matrix_stack;
- //cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
- //cc.kmGLPushMatrix();
- //cc.kmGLLoadIdentity();
- projStack.push();
- projStack.top.identity();
-
- //cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- //cc.kmGLPushMatrix();
- //cc.kmGLLoadIdentity();
- var modelViewStack = cc.modelview_matrix_stack;
- modelViewStack.push();
- modelViewStack.top.identity();
-
- cc._drawingUtil.drawSolidRect(cc.p(-1, -1), cc.p(1, 1), cc.color(255, 255, 255, 255));
-
- //cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
- //cc.kmGLPopMatrix();
- projStack.pop();
-
- //cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- //cc.kmGLPopMatrix();
- modelViewStack.pop();
+ proto.resetProgramByStencil = function () {
+ var node = this._node;
+ if (node._stencil) {
+ var program = node._originStencilProgram;
+ setProgram(node._stencil, program);
+ }
};
- proto._onBeforeVisit = function(ctx){
+ proto._onBeforeVisit = function (ctx) {
var gl = ctx || cc._renderContext, node = this._node;
cc.ClippingNode.WebGLRenderCmd._layer++;
@@ -182,57 +156,52 @@
this._mask_layer_le = mask_layer | mask_layer_l;
// manually save the stencil state
this._currentStencilEnabled = gl.isEnabled(gl.STENCIL_TEST);
- this._currentStencilWriteMask = gl.getParameter(gl.STENCIL_WRITEMASK);
- this._currentStencilFunc = gl.getParameter(gl.STENCIL_FUNC);
- this._currentStencilRef = gl.getParameter(gl.STENCIL_REF);
- this._currentStencilValueMask = gl.getParameter(gl.STENCIL_VALUE_MASK);
- this._currentStencilFail = gl.getParameter(gl.STENCIL_FAIL);
- this._currentStencilPassDepthFail = gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL);
- this._currentStencilPassDepthPass = gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
// enable stencil use
gl.enable(gl.STENCIL_TEST);
- gl.stencilMask(mask_layer);
- this._currentDepthWriteMask = gl.getParameter(gl.DEPTH_WRITEMASK);
gl.depthMask(false);
gl.stencilFunc(gl.NEVER, mask_layer, mask_layer);
- gl.stencilOp(!node.inverted ? gl.ZERO : gl.REPLACE, gl.KEEP, gl.KEEP);
-
- this._drawFullScreenQuadClearStencil();
+ gl.stencilOp(gl.REPLACE, gl.KEEP, gl.KEEP);
- gl.stencilFunc(gl.NEVER, mask_layer, mask_layer);
- gl.stencilOp(!node.inverted ? gl.REPLACE : gl.ZERO, gl.KEEP, gl.KEEP);
+ gl.stencilMask(mask_layer);
+ gl.clear(gl.STENCIL_BUFFER_BIT);
if (node.alphaThreshold < 1) { //TODO desktop
var program = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
- var alphaValueLocation = gl.getUniformLocation(program.getProgram(), cc.UNIFORM_ALPHA_TEST_VALUE_S);
// set our alphaThreshold
cc.glUseProgram(program.getProgram());
- program.setUniformLocationWith1f(alphaValueLocation, node.alphaThreshold);
+ program.setUniformLocationWith1f(cc.UNIFORM_ALPHA_TEST_VALUE_S, node.alphaThreshold);
+ program.setUniformLocationWithMatrix4fv(cc.UNIFORM_MVMATRIX_S, cc.renderer.mat4Identity.mat);
cc.setProgram(node._stencil, program);
}
};
- proto._onAfterDrawStencil = function(ctx){
+ proto._onAfterDrawStencil = function (ctx) {
var gl = ctx || cc._renderContext;
- gl.depthMask(this._currentDepthWriteMask);
-
- gl.stencilFunc(gl.EQUAL, this._mask_layer_le, this._mask_layer_le);
+ gl.depthMask(true);
+ gl.stencilFunc(!this._node.inverted ? gl.EQUAL : gl.NOTEQUAL, this._mask_layer_le, this._mask_layer_le);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
};
- proto._onAfterVisit = function(ctx){
+ proto._onAfterVisit = function (ctx) {
var gl = ctx || cc._renderContext;
- gl.stencilFunc(this._currentStencilFunc, this._currentStencilRef, this._currentStencilValueMask);
- gl.stencilOp(this._currentStencilFail, this._currentStencilPassDepthFail, this._currentStencilPassDepthPass);
- gl.stencilMask(this._currentStencilWriteMask);
- if (!this._currentStencilEnabled)
+ cc.ClippingNode.WebGLRenderCmd._layer--;
+
+ if (this._currentStencilEnabled) {
+ var mask_layer = 0x1 << cc.ClippingNode.WebGLRenderCmd._layer;
+ var mask_layer_l = mask_layer - 1;
+ var mask_layer_le = mask_layer | mask_layer_l;
+
+ gl.stencilMask(mask_layer);
+ gl.stencilFunc(gl.EQUAL, mask_layer_le, mask_layer_le);
+ }
+ else {
gl.disable(gl.STENCIL_TEST);
- // we are done using this layer, decrement
- cc.ClippingNode.WebGLRenderCmd._layer--;
- }
+ }
+ };
})();
diff --git a/cocos2d/core/CCActionManager.js b/cocos2d/core/CCActionManager.js
index ac061e3f5a..980be114b4 100644
--- a/cocos2d/core/CCActionManager.js
+++ b/cocos2d/core/CCActionManager.js
@@ -30,27 +30,14 @@
* @example
* var element = new cc.HashElement();
*/
-cc.HashElement = cc.Class.extend(/** @lends cc.HashElement# */{
- actions:null,
- target:null, //ccobject
- actionIndex:0,
- currentAction:null, //CCAction
- currentActionSalvaged:false,
- paused:false,
- hh:null, //ut hash handle
- /**
- * Constructor
- */
- ctor:function () {
- this.actions = [];
- this.target = null;
- this.actionIndex = 0;
- this.currentAction = null; //CCAction
- this.currentActionSalvaged = false;
- this.paused = false;
- this.hh = null; //ut hash handle
- }
-});
+cc.HashElement = function () {
+ this.actions = [];
+ this.target = null;
+ this.actionIndex = 0;
+ this.currentAction = null; //CCAction
+ this.paused = false;
+ this.lock = false;
+};
/**
* cc.ActionManager is a class that can manage actions.
@@ -66,10 +53,7 @@ cc.HashElement = cc.Class.extend(/** @lends cc.HashElement# */{
* var mng = new cc.ActionManager();
*/
cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
- _hashTargets:null,
- _arrayTargets:null,
- _currentTarget:null,
- _currentTargetSalvaged:false,
+ _elementPool: [],
_searchElementByTarget:function (arr, target) {
for (var k = 0; k < arr.length; k++) {
@@ -83,7 +67,26 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
this._hashTargets = {};
this._arrayTargets = [];
this._currentTarget = null;
- this._currentTargetSalvaged = false;
+ },
+
+ _getElement: function (target, paused) {
+ var element = this._elementPool.pop();
+ if (!element) {
+ element = new cc.HashElement();
+ }
+ element.target = target;
+ element.paused = !!paused;
+ return element;
+ },
+
+ _putElement: function (element) {
+ element.actions.length = 0;
+ element.actionIndex = 0;
+ element.currentAction = null;
+ element.paused = false;
+ element.target = null;
+ element.lock = false;
+ this._elementPool.push(element);
},
/** Adds an action with a target.
@@ -96,22 +99,21 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
*/
addAction:function (action, target, paused) {
if(!action)
- throw "cc.ActionManager.addAction(): action must be non-null";
+ throw new Error("cc.ActionManager.addAction(): action must be non-null");
if(!target)
- throw "cc.ActionManager.addAction(): action must be non-null";
+ throw new Error("cc.ActionManager.addAction(): target must be non-null");
//check if the action target already exists
var element = this._hashTargets[target.__instanceId];
- //if doesnt exists, create a hashelement and push in mpTargets
+ //if doesn't exists, create a hashelement and push in mpTargets
if (!element) {
- element = new cc.HashElement();
- element.paused = paused;
- element.target = target;
+ element = this._getElement(target, paused);
this._hashTargets[target.__instanceId] = element;
this._arrayTargets.push(element);
}
- //creates a array for that eleemnt to hold the actions
- this._actionAllocWithHashElement(element);
+ else if (!element.actions) {
+ element.actions = [];
+ }
element.actions.push(action);
action.startWithTarget(target);
@@ -139,15 +141,8 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
return;
var element = this._hashTargets[target.__instanceId];
if (element) {
- if (element.actions.indexOf(element.currentAction) !== -1 && !(element.currentActionSalvaged))
- element.currentActionSalvaged = true;
-
element.actions.length = 0;
- if (this._currentTarget === element && !forceDelete) {
- this._currentTargetSalvaged = true;
- } else {
- this._deleteHashElement(element);
- }
+ this._deleteHashElement(element);
}
},
/** Removes an action given an action reference.
@@ -164,6 +159,9 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
for (var i = 0; i < element.actions.length; i++) {
if (element.actions[i] === action) {
element.actions.splice(i, 1);
+ // update actionIndex in case we are in tick. looping over the actions
+ if (element.actionIndex >= i)
+ element.actionIndex--;
break;
}
}
@@ -274,10 +272,10 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
* @param {Array} targetsToResume
*/
resumeTargets:function(targetsToResume){
- if(!targetsToResume)
+ if (!targetsToResume)
return;
- for(var i = 0 ; i< targetsToResume.length; i++){
+ for (var i = 0; i< targetsToResume.length; i++) {
if(targetsToResume[i])
this.resumeTarget(targetsToResume[i]);
}
@@ -294,9 +292,6 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
_removeActionAtIndex:function (index, element) {
var action = element.actions[index];
- if ((action === element.currentAction) && (!element.currentActionSalvaged))
- element.currentActionSalvaged = true;
-
element.actions.splice(index, 1);
// update actionIndex in case we are in tick. looping over the actions
@@ -304,28 +299,27 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
element.actionIndex--;
if (element.actions.length === 0) {
- if (this._currentTarget === element) {
- this._currentTargetSalvaged = true;
- } else {
- this._deleteHashElement(element);
- }
+ this._deleteHashElement(element);
}
},
_deleteHashElement:function (element) {
- if (element) {
- delete this._hashTargets[element.target.__instanceId];
- cc.arrayRemoveObject(this._arrayTargets, element);
- element.actions = null;
- element.target = null;
- }
- },
-
- _actionAllocWithHashElement:function (element) {
- // 4 actions per Node by default
- if (element.actions == null) {
- element.actions = [];
+ var ret = false;
+ if (element && !element.lock) {
+ if (this._hashTargets[element.target.__instanceId]) {
+ delete this._hashTargets[element.target.__instanceId];
+ var targets = this._arrayTargets;
+ for (var i = 0, l = targets.length; i < l; i++) {
+ if (targets[i] === element) {
+ targets.splice(i, 1);
+ break;
+ }
+ }
+ this._putElement(element);
+ ret = true;
+ }
}
+ return ret;
},
/**
@@ -336,42 +330,31 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
for (var elt = 0; elt < locTargets.length; elt++) {
this._currentTarget = locTargets[elt];
locCurrTarget = this._currentTarget;
- //this._currentTargetSalvaged = false;
- if (!locCurrTarget.paused) {
+ if (!locCurrTarget.paused && locCurrTarget.actions) {
+ locCurrTarget.lock = true;
// The 'actions' CCMutableArray may change while inside this loop.
- for (locCurrTarget.actionIndex = 0;
- locCurrTarget.actionIndex < (locCurrTarget.actions ? locCurrTarget.actions.length : 0);
- locCurrTarget.actionIndex++) {
+ for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
if (!locCurrTarget.currentAction)
continue;
- locCurrTarget.currentActionSalvaged = false;
//use for speed
locCurrTarget.currentAction.step(dt * ( locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1 ) );
- if (locCurrTarget.currentActionSalvaged) {
- // The currentAction told the node to remove it. To prevent the action from
- // accidentally deallocating itself before finishing its step, we retained
- // it. Now that step is done, it's safe to release it.
- locCurrTarget.currentAction = null;//release
- } else if (locCurrTarget.currentAction.isDone()) {
+
+ if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
locCurrTarget.currentAction.stop();
var action = locCurrTarget.currentAction;
- // Make currentAction nil to prevent removeAction from salvaging it.
locCurrTarget.currentAction = null;
this.removeAction(action);
}
locCurrTarget.currentAction = null;
}
+ locCurrTarget.lock = false;
}
-
- // elt, at this moment, is still valid
- // so it is safe to ask this here (issue #490)
-
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
- if (this._currentTargetSalvaged && locCurrTarget.actions.length === 0) {
- this._deleteHashElement(locCurrTarget);
+ if (locCurrTarget.actions.length === 0) {
+ this._deleteHashElement(locCurrTarget) && elt--;
}
}
}
diff --git a/cocos2d/core/CCCamera.js b/cocos2d/core/CCCamera.js
deleted file mode 100644
index ea6c6db8c7..0000000000
--- a/cocos2d/core/CCCamera.js
+++ /dev/null
@@ -1,282 +0,0 @@
-/****************************************************************************
- Copyright (c) 2008-2010 Ricardo Quesada
- Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
-
- http://www.cocos2d-x.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
-
-/**
- *
- * A CCCamera is used in every CCNode.
- * The OpenGL gluLookAt() function is used to locate the camera.
- *
- * If the object is transformed by any of the scale, rotation or position attributes, then they will override the camera.
- *
- * IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both.
- * World coordinates won't work if you use the camera.
- *
- * Limitations:
- * - Some nodes, like CCParallaxNode, CCParticle uses world node coordinates, and they won't work properly if you move them (or any of their ancestors)
- * using the camera.
- *
- * - It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object.
- *
- * - It is recommended to use it ONLY if you are going to create 3D effects. For 2D effecs, use the action CCFollow or position/scale/rotate. *
- *
- */
-cc.Camera = cc.Class.extend({
- _eyeX:null,
- _eyeY:null,
- _eyeZ:null,
-
- _centerX:null,
- _centerY:null,
- _centerZ:null,
-
- _upX:null,
- _upY:null,
- _upZ:null,
-
- _dirty:false,
- _lookupMatrix:null,
- /**
- * constructor of cc.Camera
- */
- ctor:function () {
- this._lookupMatrix = new cc.math.Matrix4();
- this.restore();
- },
-
- /**
- * Description of cc.Camera
- * @return {String}
- */
- description:function () {
- return "";
- },
-
- /**
- * sets the dirty value
- * @param value
- */
- setDirty:function (value) {
- this._dirty = value;
- },
-
- /**
- * get the dirty value
- * @return {Boolean}
- */
- isDirty:function () {
- return this._dirty;
- },
-
- /**
- * sets the camera in the default position
- */
- restore:function () {
- this._eyeX = this._eyeY = 0.0;
- this._eyeZ = cc.Camera.getZEye();
-
- this._centerX = this._centerY = this._centerZ = 0.0;
-
- this._upX = 0.0;
- this._upY = 1.0;
- this._upZ = 0.0;
-
- this._lookupMatrix.identity();
-
- this._dirty = false;
- },
-
- /**
- * Sets the camera using gluLookAt using its eye, center and up_vector
- */
- locate:function () {
- if (this._dirty) {
- var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ),
- center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ),
- up = new cc.math.Vec3(this._upX, this._upY, this._upZ);
- this._lookupMatrix.lookAt(eye, center, up);
- this._dirty = false;
- }
- cc.kmGLMultMatrix( this._lookupMatrix);
- },
-
- _locateForRenderer: function(matrix){
- if (this._dirty) {
- var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ),
- center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ),
- up = new cc.math.Vec3(this._upX, this._upY, this._upZ);
- this._lookupMatrix.lookAt(eye, center, up);
- this._dirty = false;
- }
- matrix.multiply(this._lookupMatrix);
- },
-
- /**
- * sets the eye values in points
- * @param {Number} eyeX
- * @param {Number} eyeY
- * @param {Number} eyeZ
- * @deprecated This function will be deprecated sooner or later please use setEye instead.
- */
- setEyeXYZ:function (eyeX, eyeY, eyeZ) {
- this.setEye(eyeX,eyeY,eyeZ);
- },
-
- /**
- * sets the eye values in points
- * @param {Number} eyeX
- * @param {Number} eyeY
- * @param {Number} eyeZ
- */
- setEye:function (eyeX, eyeY, eyeZ) {
- this._eyeX = eyeX ;
- this._eyeY = eyeY ;
- this._eyeZ = eyeZ ;
-
- this._dirty = true;
- },
-
- /**
- * sets the center values in points
- * @param {Number} centerX
- * @param {Number} centerY
- * @param {Number} centerZ
- * @deprecated This function will be deprecated sooner or later please use setCenter instead.
- */
- setCenterXYZ:function (centerX, centerY, centerZ) {
- this.setCenter(centerX,centerY,centerZ);
- },
-
- /**
- * sets the center values in points
- * @param {Number} centerX
- * @param {Number} centerY
- * @param {Number} centerZ
- */
- setCenter:function (centerX, centerY, centerZ) {
- this._centerX = centerX ;
- this._centerY = centerY ;
- this._centerZ = centerZ ;
-
- this._dirty = true;
- },
-
- /**
- * sets the up values
- * @param {Number} upX
- * @param {Number} upY
- * @param {Number} upZ
- * @deprecated This function will be deprecated sooner or later.
- */
- setUpXYZ:function (upX, upY, upZ) {
- this.setUp(upX, upY, upZ);
- },
-
- /**
- * sets the up values
- * @param {Number} upX
- * @param {Number} upY
- * @param {Number} upZ
- */
- setUp:function (upX, upY, upZ) {
- this._upX = upX;
- this._upY = upY;
- this._upZ = upZ;
-
- this._dirty = true;
- },
-
- /**
- * get the eye vector values in points (return an object like {x:1,y:1,z:1} in HTML5)
- * @param {Number} eyeX
- * @param {Number} eyeY
- * @param {Number} eyeZ
- * @return {Object}
- * @deprecated This function will be deprecated sooner or later, please use getEye instead.
- */
- getEyeXYZ:function (eyeX, eyeY, eyeZ) {
- return {x:this._eyeX , y:this._eyeY , z: this._eyeZ };
- },
-
- /**
- * get the eye vector values in points (return an object like {x:1,y:1,z:1} in HTML5)
- * @return {Object}
- */
- getEye:function () {
- return {x:this._eyeX , y:this._eyeY , z: this._eyeZ };
- },
-
- /**
- * get the center vector values int points (return an object like {x:1,y:1,z:1} in HTML5)
- * @param {Number} centerX
- * @param {Number} centerY
- * @param {Number} centerZ
- * @return {Object}
- * @deprecated This function will be deprecated sooner or later,please use getCenter instead.
- */
- getCenterXYZ:function (centerX, centerY, centerZ) {
- return {x:this._centerX ,y:this._centerY ,z:this._centerZ };
- },
-
- /**
- * get the center vector values int points (return an object like {x:1,y:1,z:1} in HTML5)
- * @return {Object}
- */
- getCenter:function () {
- return {x:this._centerX ,y:this._centerY ,z:this._centerZ };
- },
-
- /**
- * get the up vector values (return an object like {x:1,y:1,z:1} in HTML5)
- * @param {Number} upX
- * @param {Number} upY
- * @param {Number} upZ
- * @return {Object}
- * @deprecated This function will be deprecated sooner or later,please use getUp instead.
- */
- getUpXYZ:function (upX, upY, upZ) {
- return {x:this._upX,y:this._upY,z:this._upZ};
- },
-
- /**
- * get the up vector values (return an object like {x:1,y:1,z:1} in HTML5)
- * @return {Object}
- */
- getUp:function () {
- return {x:this._upX,y:this._upY,z:this._upZ};
- },
-
- _DISALLOW_COPY_AND_ASSIGN:function (CCCamera) {
-
- }
-});
-
-/**
- * returns the Z eye
- * @return {Number}
- */
-cc.Camera.getZEye = function () {
- return cc.FLT_EPSILON;
-};
diff --git a/cocos2d/core/CCConfiguration.js b/cocos2d/core/CCConfiguration.js
index e2be6b7ba8..db58df2449 100644
--- a/cocos2d/core/CCConfiguration.js
+++ b/cocos2d/core/CCConfiguration.js
@@ -231,7 +231,7 @@ cc.configuration = /** @lends cc.configuration# */{
* gathers OpenGL / GPU information
*/
gatherGPUInfo: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return;
if(!this._inited)
@@ -278,7 +278,7 @@ cc.configuration = /** @lends cc.configuration# */{
if(!this._inited)
this._init();
var dict = cc.loader.getRes(url);
- if(!dict) throw "Please load the resource first : " + url;
+ if(!dict) throw new Error("Please load the resource first : " + url);
cc.assert(dict, cc._LogInfos.configuration_loadConfigFile_2, url);
var getDatas = dict["data"];
diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js
index cd84958624..b8a021f43c 100644
--- a/cocos2d/core/CCDirector.js
+++ b/cocos2d/core/CCDirector.js
@@ -26,16 +26,6 @@
cc.g_NumberOfDraws = 0;
-cc.GLToClipTransform = function (transformOut) {
- //var projection = new cc.math.Matrix4();
- //cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, projection);
- cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, transformOut);
-
- var modelview = new cc.math.Matrix4();
- cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, modelview);
-
- transformOut.multiply(modelview);
-};
//----------------------------------------------------------------------------------------------------------------------
/**
@@ -53,6 +43,7 @@ cc.GLToClipTransform = function (transformOut) {
* - setting the OpenGL pixel format (default on is RGB565)
* - setting the OpenGL pixel format (default on is RGB565)
* - setting the OpenGL buffer depth (default one is 0-bit)
+ * - setting the color for clear screen (default one is BLACK)
* - setting the projection (default one is 3D)
* - setting the orientation (default one is Portrait)
*
@@ -82,16 +73,9 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
_animationInterval: 0.0,
_oldAnimationInterval: 0.0,
_projection: 0,
- _accumDt: 0.0,
_contentScaleFactor: 1.0,
- _displayStats: false,
_deltaTime: 0.0,
- _frameRate: 0.0,
-
- _FPSLabel: null,
- _SPFLabel: null,
- _drawsLabel: null,
_winSizeInPoints: null,
@@ -103,7 +87,6 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
_projectionDelegate: null,
_runningScene: null,
- _frames: 0,
_totalFrames: 0,
_secondsPerFrame: 0,
@@ -112,9 +95,9 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
_scheduler: null,
_actionManager: null,
_eventProjectionChanged: null,
- _eventAfterDraw: null,
- _eventAfterVisit: null,
_eventAfterUpdate: null,
+ _eventAfterVisit: null,
+ _eventAfterDraw: null,
ctor: function () {
var self = this;
@@ -133,11 +116,8 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
// projection delegate if "Custom" projection is used
this._projectionDelegate = null;
- //FPS
- this._accumDt = 0;
- this._frameRate = 0;
- this._displayStats = false;//can remove
- this._totalFrames = this._frames = 0;
+ // FPS
+ this._totalFrames = 0;
this._lastUpdate = Date.now();
//Paused?
@@ -154,19 +134,19 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
//scheduler
this._scheduler = new cc.Scheduler();
//action manager
- if(cc.ActionManager){
+ if (cc.ActionManager) {
this._actionManager = new cc.ActionManager();
this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false);
- }else{
+ } else {
this._actionManager = null;
}
- this._eventAfterDraw = new cc.EventCustom(cc.Director.EVENT_AFTER_DRAW);
- this._eventAfterDraw.setUserData(this);
- this._eventAfterVisit = new cc.EventCustom(cc.Director.EVENT_AFTER_VISIT);
- this._eventAfterVisit.setUserData(this);
this._eventAfterUpdate = new cc.EventCustom(cc.Director.EVENT_AFTER_UPDATE);
this._eventAfterUpdate.setUserData(this);
+ this._eventAfterVisit = new cc.EventCustom(cc.Director.EVENT_AFTER_VISIT);
+ this._eventAfterVisit.setUserData(this);
+ this._eventAfterDraw = new cc.EventCustom(cc.Director.EVENT_AFTER_DRAW);
+ this._eventAfterDraw.setUserData(this);
this._eventProjectionChanged = new cc.EventCustom(cc.Director.EVENT_PROJECTION_CHANGED);
this._eventProjectionChanged.setUserData(this);
@@ -201,7 +181,16 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
* @param {cc.Point} uiPoint
* @return {cc.Point}
*/
- convertToGL: null,
+ convertToGL: function (uiPoint) {
+ var docElem = document.documentElement;
+ var view = cc.view;
+ var box = docElem.getBoundingClientRect();
+ box.left += window.pageXOffset - docElem.clientLeft;
+ box.top += window.pageYOffset - docElem.clientTop;
+ var x = view._devicePixelRatio * (uiPoint.x - box.left);
+ var y = view._devicePixelRatio * (box.top + box.height - uiPoint.y);
+ return view._isRotated ? {x: view._viewPortRect.width - y, y: x} : {x: x, y: y};
+ },
/**
* Converts an WebGL coordinate to a view coordinate
@@ -211,13 +200,30 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
* @param {cc.Point} glPoint
* @return {cc.Point}
*/
- convertToUI: null,
+ convertToUI: function (glPoint) {
+ var docElem = document.documentElement;
+ var view = cc.view;
+ var box = docElem.getBoundingClientRect();
+ box.left += window.pageXOffset - docElem.clientLeft;
+ box.top += window.pageYOffset - docElem.clientTop;
+ var uiPoint = {x: 0, y: 0};
+ if (view._isRotated) {
+ uiPoint.x = box.left + glPoint.y / view._devicePixelRatio;
+ uiPoint.y = box.top + box.height - (view._viewPortRect.width - glPoint.x) / view._devicePixelRatio;
+ }
+ else {
+ uiPoint.x = box.left + glPoint.x / view._devicePixelRatio;
+ uiPoint.y = box.top + box.height - glPoint.y / view._devicePixelRatio;
+ }
+ return uiPoint;
+ },
/**
* Draw the scene. This method is called every frame. Don't call it manually.
*/
drawScene: function () {
var renderer = cc.renderer;
+
// calculate "global" dt
this.calculateDeltaTime();
@@ -227,50 +233,43 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
cc.eventManager.dispatchEvent(this._eventAfterUpdate);
}
- this._clear();
-
/* to avoid flickr, nextScene MUST be here: after tick and before draw.
XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
if (this._nextScene) {
this.setNextScene();
}
- if (this._beforeVisitScene)
- this._beforeVisitScene();
-
// draw the scene
if (this._runningScene) {
- if (renderer.childrenOrderDirty === true) {
+ if (renderer.childrenOrderDirty) {
cc.renderer.clearRenderCommands();
+ cc.renderer.assignedZ = 0;
this._runningScene._renderCmd._curLevel = 0; //level start from 0;
this._runningScene.visit();
renderer.resetFlag();
- } else if (renderer.transformDirty() === true)
+ }
+ else if (renderer.transformDirty()) {
renderer.transform();
-
- cc.eventManager.dispatchEvent(this._eventAfterVisit);
+ }
}
+ renderer.clear();
+
// draw the notifications node
if (this._notificationNode)
this._notificationNode.visit();
- if (this._displayStats)
- this._showStats();
-
- if (this._afterVisitScene)
- this._afterVisitScene();
+ cc.eventManager.dispatchEvent(this._eventAfterVisit);
+ cc.g_NumberOfDraws = 0;
renderer.rendering(cc._renderContext);
- cc.eventManager.dispatchEvent(this._eventAfterDraw);
this._totalFrames++;
- if (this._displayStats)
- this._calculateMPF();
- },
+ cc.eventManager.dispatchEvent(this._eventAfterDraw);
+ cc.eventManager.frameUpdateListeners();
- _beforeVisitScene: null,
- _afterVisitScene: null,
+ this._calculateMPF();
+ },
/**
* End the life of director in the next frame
@@ -401,9 +400,9 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
// They are needed in case the director is run again
if (this._runningScene) {
- this._runningScene.onExitTransitionDidStart();
- this._runningScene.onExit();
- this._runningScene.cleanup();
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onExit);
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.cleanup);
}
this._runningScene = null;
@@ -491,7 +490,6 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
setContentScaleFactor: function (scaleFactor) {
if (scaleFactor !== this._contentScaleFactor) {
this._contentScaleFactor = scaleFactor;
- this._createStatsLabel();
}
},
@@ -503,6 +501,13 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
*/
setDepthTest: null,
+ /**
+ * set color for clear screen.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js
+ * @function
+ * @param {cc.Color} clearColor
+ */
+ setClearColor: null,
/**
* Sets the default values based on the CCConfiguration info
*/
@@ -532,14 +537,14 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
if (!newIsTransition) {
var locRunningScene = this._runningScene;
if (locRunningScene) {
- locRunningScene.onExitTransitionDidStart();
- locRunningScene.onExit();
+ locRunningScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ locRunningScene._performRecursive(cc.Node._stateCallbackType.onExit);
}
// issue #709. the root node (scene) should receive the cleanup message too
// otherwise it might be leaked.
if (this._sendCleanupToScene && locRunningScene)
- locRunningScene.cleanup();
+ locRunningScene._performRecursive(cc.Node._stateCallbackType.cleanup);
}
this._runningScene = this._nextScene;
@@ -547,8 +552,8 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
this._nextScene = null;
if ((!runningIsTransition) && (this._runningScene !== null)) {
- this._runningScene.onEnter();
- this._runningScene.onEnterTransitionDidFinish();
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onEnter);
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
}
},
@@ -557,7 +562,17 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
* @param {cc.Node} node
*/
setNotificationNode: function (node) {
+ cc.renderer.childrenOrderDirty = true;
+ if (this._notificationNode) {
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onExit);
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.cleanup);
+ }
this._notificationNode = node;
+ if (!node)
+ return;
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onEnter);
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
},
/**
@@ -623,28 +638,6 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
*/
setAlphaBlending: null,
- _showStats: function () {
- this._frames++;
- this._accumDt += this._deltaTime;
- if (this._FPSLabel && this._SPFLabel && this._drawsLabel) {
- if (this._accumDt > cc.DIRECTOR_FPS_INTERVAL) {
- this._SPFLabel.string = this._secondsPerFrame.toFixed(3);
-
- this._frameRate = this._frames / this._accumDt;
- this._frames = 0;
- this._accumDt = 0;
-
- this._FPSLabel.string = this._frameRate.toFixed(1);
- this._drawsLabel.string = (0 | cc.g_NumberOfDraws).toString();
- }
- this._FPSLabel.visit();
- this._SPFLabel.visit();
- this._drawsLabel.visit();
- } else
- this._createStatsLabel();
- cc.g_NumberOfDraws = 0;
- },
-
/**
* Returns whether or not the replaced scene will receive the cleanup message.
* If the new scene is pushed, then the old scene won't receive the "cleanup" message.
@@ -676,7 +669,7 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
* @return {Boolean}
*/
isDisplayStats: function () {
- return this._displayStats;
+ return cc.profiler ? cc.profiler.isShowingStats() : false;
},
/**
@@ -684,7 +677,9 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
* @param {Boolean} displayStats
*/
setDisplayStats: function (displayStats) {
- this._displayStats = displayStats;
+ if (cc.profiler) {
+ displayStats ? cc.profiler.showStats() : cc.profiler.hideStats();
+ }
},
/**
@@ -741,26 +736,26 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
var locScenesStack = this._scenesStack;
var c = locScenesStack.length;
- if (c === 0) {
+ if (level === 0) {
this.end();
return;
}
- // current level or lower -> nothing
- if (level > c)
+ // stack overflow
+ if (level >= c)
return;
// pop stack until reaching desired level
while (c > level) {
var current = locScenesStack.pop();
if (current.running) {
- current.onExitTransitionDidStart();
- current.onExit();
+ current._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ current._performRecursive(cc.Node._stateCallbackType.onExit);
}
- current.cleanup();
+ current._performRecursive(cc.Node._stateCallbackType.cleanup);
c--;
}
this._nextScene = locScenesStack[locScenesStack.length - 1];
- this._sendCleanupToScene = false;
+ this._sendCleanupToScene = true;
},
/**
@@ -806,8 +801,6 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
return this._deltaTime;
},
- _createStatsLabel: null,
-
_calculateMPF: function () {
var now = Date.now();
this._secondsPerFrame = (now - this._lastUpdate) / 1000;
@@ -826,15 +819,15 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
cc.Director.EVENT_PROJECTION_CHANGED = "director_projection_changed";
/**
- * The event after draw of cc.Director
+ * The event after update of cc.Director
* @constant
* @type {string}
* @example
- * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_DRAW, function(event) {
- * cc.log("after draw event.");
+ * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_UPDATE, function(event) {
+ * cc.log("after update event.");
* });
*/
-cc.Director.EVENT_AFTER_DRAW = "director_after_draw";
+cc.Director.EVENT_AFTER_UPDATE = "director_after_update";
/**
* The event after visit of cc.Director
@@ -848,15 +841,15 @@ cc.Director.EVENT_AFTER_DRAW = "director_after_draw";
cc.Director.EVENT_AFTER_VISIT = "director_after_visit";
/**
- * The event after update of cc.Director
+ * The event after draw of cc.Director
* @constant
* @type {string}
* @example
- * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_UPDATE, function(event) {
- * cc.log("after update event.");
+ * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_DRAW, function(event) {
+ * cc.log("after draw event.");
* });
*/
-cc.Director.EVENT_AFTER_UPDATE = "director_after_update";
+cc.Director.EVENT_AFTER_DRAW = "director_after_draw";
/***************************************************
* implementation of DisplayLinkDirector
@@ -946,79 +939,8 @@ cc.Director.PROJECTION_3D = 1;
cc.Director.PROJECTION_CUSTOM = 3;
/**
- * Constant for default projection of cc.Director, default projection is 3D projection
+ * Constant for default projection of cc.Director, default projection is 2D projection
* @constant
* @type {Number}
*/
cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D;
-
-if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
-
- var _p = cc.Director.prototype;
-
- _p.setProjection = function (projection) {
- this._projection = projection;
- cc.eventManager.dispatchEvent(this._eventProjectionChanged);
- };
-
- _p.setDepthTest = function () {
- };
-
- _p.setOpenGLView = function (openGLView) {
- // set size
- this._winSizeInPoints.width = cc._canvas.width; //this._openGLView.getDesignResolutionSize();
- this._winSizeInPoints.height = cc._canvas.height;
- this._openGLView = openGLView || cc.view;
- if (cc.eventManager)
- cc.eventManager.setEnabled(true);
- };
-
- _p._clear = function () {
- var viewport = this._openGLView.getViewPortRect();
- var context = cc._renderContext.getContext();
- context.setTransform(1,0,0,1, 0, 0);
- context.clearRect(-viewport.x, viewport.y, viewport.width, viewport.height);
- };
-
- _p._createStatsLabel = function () {
- var _t = this;
- var fontSize = 0;
- if (_t._winSizeInPoints.width > _t._winSizeInPoints.height)
- fontSize = 0 | (_t._winSizeInPoints.height / 320 * 24);
- else
- fontSize = 0 | (_t._winSizeInPoints.width / 320 * 24);
-
- _t._FPSLabel = new cc.LabelTTF("000.0", "Arial", fontSize);
- _t._SPFLabel = new cc.LabelTTF("0.000", "Arial", fontSize);
- _t._drawsLabel = new cc.LabelTTF("0000", "Arial", fontSize);
-
- var locStatsPosition = cc.DIRECTOR_STATS_POSITION;
- _t._drawsLabel.setPosition(_t._drawsLabel.width / 2 + locStatsPosition.x, _t._drawsLabel.height * 5 / 2 + locStatsPosition.y);
- _t._SPFLabel.setPosition(_t._SPFLabel.width / 2 + locStatsPosition.x, _t._SPFLabel.height * 3 / 2 + locStatsPosition.y);
- _t._FPSLabel.setPosition(_t._FPSLabel.width / 2 + locStatsPosition.x, _t._FPSLabel.height / 2 + locStatsPosition.y);
- };
-
- _p.getVisibleSize = function () {
- //if (this._openGLView) {
- //return this._openGLView.getVisibleSize();
- //} else {
- return this.getWinSize();
- //}
- };
-
- _p.getVisibleOrigin = function () {
- //if (this._openGLView) {
- //return this._openGLView.getVisibleOrigin();
- //} else {
- return cc.p(0, 0);
- //}
- };
-} else {
- cc.Director._fpsImage = new Image();
- cc._addEventListener(cc.Director._fpsImage, "load", function () {
- cc.Director._fpsImageLoaded = true;
- });
- if (cc._fpsImage) {
- cc.Director._fpsImage.src = cc._fpsImage;
- }
-}
\ No newline at end of file
diff --git a/cocos2d/core/CCDirectorCanvas.js b/cocos2d/core/CCDirectorCanvas.js
new file mode 100644
index 0000000000..12deec5914
--- /dev/null
+++ b/cocos2d/core/CCDirectorCanvas.js
@@ -0,0 +1,82 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ var _p = cc.Director.prototype;
+
+ _p.getProjection = function (projection) {
+ return this._projection;
+ };
+
+ _p.setProjection = function (projection) {
+ this._projection = projection;
+ cc.eventManager.dispatchEvent(this._eventProjectionChanged);
+ };
+
+ _p.setDepthTest = function () {
+ };
+
+ _p.setClearColor = function (clearColor) {
+ cc.renderer._clearColor = clearColor;
+ cc.renderer._clearFillStyle = 'rgb(' + clearColor.r + ',' + clearColor.g + ',' + clearColor.b +')' ;
+ };
+
+ _p.setOpenGLView = function (openGLView) {
+ // set size
+ this._winSizeInPoints.width = cc._canvas.width; //this._openGLView.getDesignResolutionSize();
+ this._winSizeInPoints.height = cc._canvas.height;
+ this._openGLView = openGLView || cc.view;
+ if (cc.eventManager)
+ cc.eventManager.setEnabled(true);
+ };
+
+ _p.getVisibleSize = function () {
+ //if (this._openGLView) {
+ //return this._openGLView.getVisibleSize();
+ //} else {
+ return this.getWinSize();
+ //}
+ };
+
+ _p.getVisibleOrigin = function () {
+ //if (this._openGLView) {
+ //return this._openGLView.getVisibleOrigin();
+ //} else {
+ return cc.p(0, 0);
+ //}
+ };
+ } else {
+ cc.Director._fpsImage = new Image();
+ cc.Director._fpsImage.addEventListener("load", function () {
+ cc.Director._fpsImageLoaded = true;
+ });
+ if (cc._fpsImage) {
+ cc.Director._fpsImage.src = cc._fpsImage;
+ }
+ }
+});
diff --git a/cocos2d/core/CCDirectorWebGL.js b/cocos2d/core/CCDirectorWebGL.js
index bdd9d62fb6..50ae30bdce 100644
--- a/cocos2d/core/CCDirectorWebGL.js
+++ b/cocos2d/core/CCDirectorWebGL.js
@@ -24,297 +24,192 @@
THE SOFTWARE.
****************************************************************************/
-
-if (cc._renderType === cc._RENDER_TYPE_WEBGL) {
- (function () {
-
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ // Do nothing under other render mode
+ if (cc._renderType !== cc.game.RENDER_TYPE_WEBGL) {
+ return;
+ }
+
+ /**
+ * OpenGL projection protocol
+ * @class
+ * @extends cc.Class
+ */
+ cc.DirectorDelegate = cc.Class.extend(/** @lends cc.DirectorDelegate# */{
/**
- * OpenGL projection protocol
- * @class
- * @extends cc.Class
+ * Called by CCDirector when the projection is updated, and "custom" projection is used
*/
- cc.DirectorDelegate = cc.Class.extend(/** @lends cc.DirectorDelegate# */{
- /**
- * Called by CCDirector when the projection is updated, and "custom" projection is used
- */
- updateProjection: function () {
- }
- });
-
- var _p = cc.Director.prototype;
-
- _p.setProjection = function (projection) {
- var _t = this;
- var size = _t._winSizeInPoints;
-
- _t.setViewport();
-
- var view = _t._openGLView,
- ox = view._viewPortRect.x / view._scaleX,
- oy = view._viewPortRect.y / view._scaleY;
-
- switch (projection) {
- case cc.Director.PROJECTION_2D:
- cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
- cc.kmGLLoadIdentity();
- var orthoMatrix = cc.math.Matrix4.createOrthographicProjection(
- -ox,
- size.width - ox,
- -oy,
- size.height - oy,
- -1024, 1024);
- cc.kmGLMultMatrix(orthoMatrix);
- cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- cc.kmGLLoadIdentity();
- break;
- case cc.Director.PROJECTION_3D:
- var zeye = _t.getZEye();
- var matrixPerspective = new cc.math.Matrix4(), matrixLookup = new cc.math.Matrix4();
- cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
- cc.kmGLLoadIdentity();
-
- // issue #1334
- matrixPerspective = cc.math.Matrix4.createPerspectiveProjection(60, size.width / size.height, 0.1, zeye * 2);
-
- cc.kmGLMultMatrix(matrixPerspective);
-
- cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- cc.kmGLLoadIdentity();
- var eye = new cc.math.Vec3(-ox + size.width / 2, -oy + size.height / 2, zeye);
- var center = new cc.math.Vec3( -ox + size.width / 2, -oy + size.height / 2, 0.0);
- var up = new cc.math.Vec3( 0.0, 1.0, 0.0);
- matrixLookup.lookAt(eye, center, up);
- cc.kmGLMultMatrix(matrixLookup);
- break;
- case cc.Director.PROJECTION_CUSTOM:
- if (_t._projectionDelegate)
- _t._projectionDelegate.updateProjection();
- break;
- default:
- cc.log(cc._LogInfos.Director_setProjection);
- break;
- }
- _t._projection = projection;
- cc.eventManager.dispatchEvent(_t._eventProjectionChanged);
- cc.setProjectionMatrixDirty();
- cc.renderer.childrenOrderDirty = true;
- };
-
- _p.setDepthTest = function (on) {
-
- var loc_gl = cc._renderContext;
- if (on) {
- loc_gl.clearDepth(1.0);
- loc_gl.enable(loc_gl.DEPTH_TEST);
- loc_gl.depthFunc(loc_gl.LEQUAL);
- //cc._renderContext.hint(cc._renderContext.PERSPECTIVE_CORRECTION_HINT, cc._renderContext.NICEST);
- } else {
- loc_gl.disable(loc_gl.DEPTH_TEST);
- }
- //cc.checkGLErrorDebug();
- };
-
- _p.setOpenGLView = function (openGLView) {
- var _t = this;
- // set size
- _t._winSizeInPoints.width = cc._canvas.width; //_t._openGLView.getDesignResolutionSize();
- _t._winSizeInPoints.height = cc._canvas.height;
- _t._openGLView = openGLView || cc.view;
-
- // Configuration. Gather GPU info
- var conf = cc.configuration;
- conf.gatherGPUInfo();
- conf.dumpInfo();
-
- // set size
- //_t._winSizeInPoints = _t._openGLView.getDesignResolutionSize();
- //_t._winSizeInPixels = cc.size(_t._winSizeInPoints.width * _t._contentScaleFactor, _t._winSizeInPoints.height * _t._contentScaleFactor);
-
- //if (_t._openGLView != openGLView) {
- // because EAGLView is not kind of CCObject
-
- _t._createStatsLabel();
-
- //if (_t._openGLView)
- _t.setGLDefaultValues();
-
- /* if (_t._contentScaleFactor != 1) {
- _t.updateContentScaleFactor();
- }*/
-
- //}
- if (cc.eventManager)
- cc.eventManager.setEnabled(true);
- };
-
- _p._clear = function () {
- var gl = cc._renderContext;
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- };
-
- _p._beforeVisitScene = function () {
- cc.kmGLPushMatrix();
- };
-
- _p._afterVisitScene = function () {
- cc.kmGLPopMatrix();
- };
-
- _p._createStatsLabel = function () {
- var _t = this;
- if (!cc.LabelAtlas){
- _t._createStatsLabelForCanvas();
- return
- }
-
- if ((cc.Director._fpsImageLoaded == null) || (cc.Director._fpsImageLoaded === false))
- return;
-
- var texture = new cc.Texture2D();
- texture.initWithElement(cc.Director._fpsImage);
- texture.handleLoadedTexture();
-
- /*
- We want to use an image which is stored in the file named ccFPSImage.c
- for any design resolutions and all resource resolutions.
-
- To achieve this,
-
- Firstly, we need to ignore 'contentScaleFactor' in 'CCAtlasNode' and 'CCLabelAtlas'.
- So I added a new method called 'setIgnoreContentScaleFactor' for 'CCAtlasNode',
- this is not exposed to game developers, it's only used for displaying FPS now.
-
- Secondly, the size of this image is 480*320, to display the FPS label with correct size,
- a factor of design resolution ratio of 480x320 is also needed.
- */
- var factor = cc.view.getDesignResolutionSize().height / 320.0;
- if (factor === 0)
- factor = _t._winSizeInPoints.height / 320.0;
-
- var tmpLabel = new cc.LabelAtlas();
- tmpLabel._setIgnoreContentScaleFactor(true);
- tmpLabel.initWithString("00.0", texture, 12, 32, '.');
- tmpLabel.scale = factor;
- _t._FPSLabel = tmpLabel;
-
- tmpLabel = new cc.LabelAtlas();
- tmpLabel._setIgnoreContentScaleFactor(true);
- tmpLabel.initWithString("0.000", texture, 12, 32, '.');
- tmpLabel.scale = factor;
- _t._SPFLabel = tmpLabel;
-
- tmpLabel = new cc.LabelAtlas();
- tmpLabel._setIgnoreContentScaleFactor(true);
- tmpLabel.initWithString("000", texture, 12, 32, '.');
- tmpLabel.scale = factor;
- _t._drawsLabel = tmpLabel;
-
- var locStatsPosition = cc.DIRECTOR_STATS_POSITION;
- _t._drawsLabel.setPosition(locStatsPosition.x, 34 * factor + locStatsPosition.y);
- _t._SPFLabel.setPosition(locStatsPosition.x, 17 * factor + locStatsPosition.y);
- _t._FPSLabel.setPosition(locStatsPosition);
- };
-
- _p._createStatsLabelForCanvas = function () {
- var _t = this;
- //The original _createStatsLabelForCanvas method
- //Because the referenced by a cc.Director.prototype._createStatsLabel
- var fontSize = 0;
- if (_t._winSizeInPoints.width > _t._winSizeInPoints.height)
- fontSize = 0 | (_t._winSizeInPoints.height / 320 * 24);
- else
- fontSize = 0 | (_t._winSizeInPoints.width / 320 * 24);
-
- _t._FPSLabel = new cc.LabelTTF("000.0", "Arial", fontSize);
- _t._SPFLabel = new cc.LabelTTF("0.000", "Arial", fontSize);
- _t._drawsLabel = new cc.LabelTTF("0000", "Arial", fontSize);
-
- var locStatsPosition = cc.DIRECTOR_STATS_POSITION;
- _t._drawsLabel.setPosition(_t._drawsLabel.width / 2 + locStatsPosition.x, _t._drawsLabel.height * 5 / 2 + locStatsPosition.y);
- _t._SPFLabel.setPosition(_t._SPFLabel.width / 2 + locStatsPosition.x, _t._SPFLabel.height * 3 / 2 + locStatsPosition.y);
- _t._FPSLabel.setPosition(_t._FPSLabel.width / 2 + locStatsPosition.x, _t._FPSLabel.height / 2 + locStatsPosition.y);
- };
-
- _p.convertToGL = function (uiPoint) {
- var transform = new cc.math.Matrix4();
- cc.GLToClipTransform(transform);
-
- var transformInv = transform.inverse();
-
- // Calculate z=0 using -> transform*[0, 0, 0, 1]/w
- var zClip = transform.mat[14] / transform.mat[15];
- var glSize = this._openGLView.getDesignResolutionSize();
- var glCoord = new cc.math.Vec3(2.0 * uiPoint.x / glSize.width - 1.0, 1.0 - 2.0 * uiPoint.y / glSize.height, zClip);
- glCoord.transformCoord(transformInv);
- return cc.p(glCoord.x, glCoord.y);
- };
-
- _p.convertToUI = function (glPoint) {
- var transform = new cc.math.Matrix4();
- cc.GLToClipTransform(transform);
-
- var clipCoord = new cc.math.Vec3(glPoint.x, glPoint.y, 0.0);
- // Need to calculate the zero depth from the transform.
- clipCoord.transformCoord(transform);
-
- var glSize = this._openGLView.getDesignResolutionSize();
- return cc.p(glSize.width * (clipCoord.x * 0.5 + 0.5), glSize.height * (-clipCoord.y * 0.5 + 0.5));
- };
-
- _p.getVisibleSize = function () {
- //if (this._openGLView) {
- return this._openGLView.getVisibleSize();
- //} else {
- //return this.getWinSize();
- //}
- };
-
- _p.getVisibleOrigin = function () {
- //if (this._openGLView) {
- return this._openGLView.getVisibleOrigin();
- //} else {
- //return cc.p(0,0);
- //}
- };
-
- _p.getZEye = function () {
- return (this._winSizeInPoints.height / 1.1566 );
- };
-
- _p.setViewport = function () {
- var view = this._openGLView;
- if (view) {
- var locWinSizeInPoints = this._winSizeInPoints;
- view.setViewPortInPoints(-view._viewPortRect.x/view._scaleX, -view._viewPortRect.y/view._scaleY, locWinSizeInPoints.width, locWinSizeInPoints.height);
+ updateProjection: function () {
+ }
+ });
+
+ var _p = cc.Director.prototype;
+
+ var recursiveChild = function(node){
+ if(node && node._renderCmd){
+ node._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ var i, children = node._children;
+ for(i=0; i 0);
this._repeat = repeat;
this._runForever = (this._repeat === cc.REPEAT_FOREVER);
+ return true;
},
-
- trigger: function(){
- return 0;
- },
-
- cancel: function(){
- return 0;
- },
-
/**
- * cc.Timer's Constructor
- * Constructor of cc.Timer
+ * @return {Number} returns interval of timer
*/
- ctor:function () {
- this._scheduler = null;
- this._elapsed = -1;
- this._runForever = false;
- this._useDelay = false;
- this._timesExecuted = 0;
- this._repeat = 0;
- this._delay = 0;
- this._interval = 0;
- },
+ getInterval : function(){return this._interval;},
+ /**
+ * @param {Number} interval set interval in seconds
+ */
+ setInterval : function(interval){this._interval = interval;},
/**
* triggers the timer
@@ -185,66 +237,10 @@ cc.Timer = cc.Class.extend(/** @lends cc.Timer# */{
}
}
- if (!this._runForever && this._timesExecuted > this._repeat)
+ if (this._callback && !this._runForever && this._timesExecuted > this._repeat)
this.cancel();
}
}
- }
-});
-
-cc.TimerTargetSelector = cc.Timer.extend({
- _target: null,
- _selector: null,
-
- ctor: function(){
- this._target = null;
- this._selector = null;
- },
-
- initWithSelector: function(scheduler, selector, target, seconds, repeat, delay){
- this._scheduler = scheduler;
- this._target = target;
- this._selector = selector;
- this.setupTimerWithInterval(seconds, repeat, delay);
- return true;
- },
-
- getSelector: function(){
- return this._selector;
- },
-
- trigger: function(){
- //override
- if (this._target && this._selector){
- this._target.call(this._selector, this._elapsed);
- }
- },
-
- cancel: function(){
- //override
- this._scheduler.unschedule(this._selector, this._target);
- }
-
-});
-
-cc.TimerTargetCallback = cc.Timer.extend({
-
- _target: null,
- _callback: null,
- _key: null,
-
- ctor: function(){
- this._target = null;
- this._callback = null;
- },
-
- initWithCallback: function(scheduler, callback, target, key, seconds, repeat, delay){
- this._scheduler = scheduler;
- this._target = target;
- this._callback = callback;
- this._key = key;
- this.setupTimerWithInterval(seconds, repeat, delay);
- return true;
},
getCallback: function(){
@@ -255,18 +251,37 @@ cc.TimerTargetCallback = cc.Timer.extend({
return this._key;
},
- trigger: function(){
- //override
- if(this._callback)
+ trigger: function () {
+ if (this._target && this._callback){
this._callback.call(this._target, this._elapsed);
+ }
},
- cancel: function(){
+ cancel: function () {
//override
this._scheduler.unschedule(this._callback, this._target);
}
+}, CallbackTimer.prototype);
-});
+var _timers = [];
+CallbackTimer.get = function () {
+ return _timers.pop() || new CallbackTimer();
+};
+CallbackTimer.put = function (timer) {
+ timer._scheduler = null;
+ timer._elapsed = -1;
+ timer._runForever = false;
+ timer._useDelay = false;
+ timer._timesExecuted = 0;
+ timer._repeat = 0;
+ timer._delay = 0;
+ timer._interval = 0;
+ timer._target = null;
+ timer._callback = null;
+ timer._key = null;
+ if (_timers.length < MAX_POOL_SIZE)
+ _timers.push(timer);
+};
/**
*
@@ -344,7 +359,7 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
}
}
- // most of the updates are going to be 0, that's way there
+ // most of the updates are going to be 0, that's why there
// is an special list for updates with priority 0
if (priority === 0){
this._appendIn(this._updates0List, callback, target, paused);
@@ -358,30 +373,38 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
_removeHashElement:function (element) {
delete this._hashForTimers[element.target.__instanceId];
- cc.arrayRemoveObject(this._arrayForTimers, element);
- element.Timer = null;
- element.target = null;
- element = null;
+ var arr = this._arrayForTimers;
+ for (var i = 0, l = arr.length; i < l; i++) {
+ if (arr[i] === element) {
+ arr.splice(i, 1);
+ break;
+ }
+ }
+ HashTimerEntry.put(element);
},
_removeUpdateFromHash:function (entry) {
- var self = this, element = self._hashForUpdates[entry.target.__instanceId];
+ var self = this;
+ var element = self._hashForUpdates[entry.target.__instanceId];
if (element) {
- //list entry
- cc.arrayRemoveObject(element.list, element.entry);
+ // Remove list entry from list
+ var list = element.list, listEntry = element.entry;
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (list[i] === listEntry) {
+ list.splice(i, 1);
+ break;
+ }
+ }
delete self._hashForUpdates[element.target.__instanceId];
- //cc.arrayRemoveObject(self._hashForUpdates, element);
- element.entry = null;
-
- //hash entry
- element.target = null;
+ ListEntry.put(listEntry);
+ HashUpdateEntry.put(element);
}
},
_priorityIn:function (ppList, callback, target, priority, paused) {
var self = this,
- listElement = new cc.ListEntry(null, null, callback, target, priority, paused, false);
+ listElement = ListEntry.get(null, null, callback, target, priority, paused, false);
// empey list ?
if (!ppList) {
@@ -399,17 +422,18 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
}
//update hash entry for quick access
- self._hashForUpdates[target.__instanceId] = new cc.HashUpdateEntry(ppList, listElement, target, null);
+ self._hashForUpdates[target.__instanceId] = HashUpdateEntry.get(ppList, listElement, target, null);
return ppList;
},
_appendIn:function (ppList, callback, target, paused) {
- var self = this, listElement = new cc.ListEntry(null, null, callback, target, 0, paused, false);
+ var self = this,
+ listElement = ListEntry.get(null, null, callback, target, 0, paused, false);
ppList.push(listElement);
//update hash entry for quicker access
- self._hashForUpdates[target.__instanceId] = new cc.HashUpdateEntry(ppList, listElement, target, null, null);
+ self._hashForUpdates[target.__instanceId] = HashUpdateEntry.get(ppList, listElement, target, null, null);
},
//-----------------------public method-------------------------
@@ -546,51 +570,43 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
this.schedule(callback_fn, target, interval, repeat, delay, paused, target.__instanceId + "");
},
- schedule: function(callback, target, interval, repeat, delay, paused, key){
+ schedule: function (callback, target, interval, repeat, delay, paused, key) {
var isSelector = false;
- if(typeof callback !== "function"){
- var selector = callback;
+ if (typeof callback !== "function") {
+ var tmp = callback;
+ callback = target;
+ target = tmp;
isSelector = true;
}
-
- if(isSelector === false){
- //callback, target, interval, repeat, delay, paused, key
- //callback, target, interval, paused, key
- if(arguments.length === 5){
- key = delay;
- paused = repeat;
- delay = 0;
- repeat = cc.REPEAT_FOREVER;
- }
- }else{
- //selector, target, interval, repeat, delay, paused
- //selector, target, interval, paused
- if(arguments.length === 4){
- paused = repeat;
- repeat = cc.REPEAT_FOREVER;
- delay = 0;
- }
+ //callback, target, interval, repeat, delay, paused, key
+ //callback, target, interval, paused, key
+ if(arguments.length === 4 || arguments.length === 5){
+ key = delay;
+ paused = repeat;
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ }
+ if (key === undefined) {
+ key = target.__instanceId + "";
}
cc.assert(target, cc._LogInfos.Scheduler_scheduleCallbackForTarget_3);
- if(isSelector === false)
- cc.assert(key, "key should not be empty!");
var element = this._hashForTimers[target.__instanceId];
- if(!element){
+ if (!element) {
// Is this the 1st element ? Then set the pause level to all the callback_fns of this target
- element = new cc.HashTimerEntry(null, target, 0, null, null, paused, null);
+ element = HashTimerEntry.get(null, target, 0, null, null, paused);
this._arrayForTimers.push(element);
this._hashForTimers[target.__instanceId] = element;
- }else{
+ } else {
cc.assert(element.paused === paused, "");
}
var timer, i;
if (element.timers == null) {
element.timers = [];
- } else if(isSelector === false) {
+ } else {
for (i = 0; i < element.timers.length; i++) {
timer = element.timers[i];
if (callback === timer._callback) {
@@ -599,27 +615,11 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
return;
}
}
- }else{
- for (i = 0; i < element.timers.length; ++i){
- timer =element.timers[i];
- if (timer && selector === timer.getSelector()){
- cc.log("CCScheduler#scheduleSelector. Selector already scheduled. Updating interval from: %.4f to %.4f", timer.getInterval(), interval);
- timer.setInterval(interval);
- return;
- }
- }
- //ccArrayEnsureExtraCapacity(element->timers, 1);
}
- if(isSelector === false){
- timer = new cc.TimerTargetCallback();
- timer.initWithCallback(this, callback, target, key, interval, repeat, delay);
- element.timers.push(timer);
- }else{
- timer = new cc.TimerTargetSelector();
- timer.initWithSelector(this, selector, target, interval, repeat, delay);
- element.timers.push(timer);
- }
+ timer = CallbackTimer.get();
+ timer.initWithCallback(this, callback, target, interval, repeat, delay, key);
+ element.timers.push(timer);
},
scheduleUpdate: function(target, priority, paused){
@@ -629,18 +629,16 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
},
_getUnscheduleMark: function(key, timer){
- //key, callback, selector
+ //key, callback
switch (typeof key){
case "number":
case "string":
- return key === timer.getKey();
+ return key === timer._key;
case "function":
return key === timer._callback;
- default:
- return key === timer.getSelector();
}
},
- unschedule: function(key, target){
+ unschedule: function (key, target) {
//key, target
//selector, target
//callback, target - This is in order to increase compatibility
@@ -659,6 +657,7 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
element.currentTimerSalvaged = true;
}
timers.splice(i, 1);
+ CallbackTimer.put(timer);
//update timerIndex in case we are in tick;, looping over the actions
if (element.timerIndex >= i) {
element.timerIndex--;
@@ -677,37 +676,40 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
}
},
- unscheduleUpdate: function(target){
- if (target == null)
+ unscheduleUpdate: function (target) {
+ if (!target)
return;
var element = this._hashForUpdates[target.__instanceId];
- if (element){
- if (this._updateHashLocked){
+ if (element) {
+ if (this._updateHashLocked) {
element.entry.markedForDeletion = true;
- }else{
+ } else {
this._removeUpdateFromHash(element.entry);
}
}
},
- unscheduleAllForTarget: function(target){
+ unscheduleAllForTarget: function (target) {
// explicit nullptr handling
- if (target == null){
+ if (!target){
return;
}
// Custom Selectors
var element = this._hashForTimers[target.__instanceId];
- if (element){
- if (element.timers.indexOf(element.currentTimer) > -1
- && (! element.currentTimerSalvaged)){
+ if (element) {
+ var timers = element.timers;
+ if (timers.indexOf(element.currentTimer) > -1 &&
+ (!element.currentTimerSalvaged)) {
element.currentTimerSalvaged = true;
}
- // ccArrayRemoveAllObjects(element.timers);
- element.timers.length = 0;
+ for (var i = 0, l = timers.length; i < l; i++) {
+ CallbackTimer.put(timers[i]);
+ }
+ timers.length = 0;
if (this._currentTarget === element){
this._currentTargetSalvaged = true;
@@ -727,7 +729,7 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
unscheduleAllWithMinPriority: function(minPriority){
// Custom Selectors
var i, element, arr = this._arrayForTimers;
- for(i=0; i=0; i--){
element = arr[i];
this.unscheduleAllForTarget(element.target);
}
@@ -767,26 +769,27 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
}
},
- isScheduled: function(key, target){
+ isScheduled: function(callback, target){
//key, target
//selector, target
- cc.assert(key, "Argument key must not be empty");
+ cc.assert(callback, "Argument callback must not be empty");
cc.assert(target, "Argument target must be non-nullptr");
- var element = this._hashForUpdates[target.__instanceId];
+ var element = this._hashForTimers[target.__instanceId];
- if (!element){
+ if (!element) {
return false;
}
if (element.timers == null){
return false;
- }else{
+ }
+ else {
var timers = element.timers;
- for (var i = 0; i < timers.length; ++i){
+ for (var i = 0; i < timers.length; ++i) {
var timer = timers[i];
- if (key === timer.getKey()){
+ if (callback === timer._callback){
return true;
}
}
@@ -1028,9 +1031,19 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
this.unscheduleAllWithMinPriority(minPriority);
}
});
+
/**
* Priority level reserved for system services.
* @constant
* @type Number
*/
cc.Scheduler.PRIORITY_SYSTEM = (-2147483647 - 1);
+
+/**
+ * Minimum priority level for user scheduling.
+ * @constant
+ * @type Number
+ */
+cc.Scheduler.PRIORITY_NON_SYSTEM = cc.Scheduler.PRIORITY_SYSTEM + 1;
+
+})();
diff --git a/cocos2d/core/base-nodes/CCAtlasNode.js b/cocos2d/core/base-nodes/CCAtlasNode.js
index c2b543931a..336ab7cc57 100644
--- a/cocos2d/core/base-nodes/CCAtlasNode.js
+++ b/cocos2d/core/base-nodes/CCAtlasNode.js
@@ -68,6 +68,7 @@ cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
_ignoreContentScaleFactor: false,
_className: "AtlasNode",
+ _texture: null,
_textureForCanvas: null,
/**
@@ -85,7 +86,7 @@ cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
},
_createRenderCmd: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
this._renderCmd = new cc.AtlasNode.CanvasRenderCmd(this);
else
this._renderCmd = new cc.AtlasNode.WebGLRenderCmd(this);
@@ -202,7 +203,7 @@ cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
*/
initWithTileFile: function (tile, tileWidth, tileHeight, itemsToRender) {
if (!tile)
- throw "cc.AtlasNode.initWithTileFile(): title should not be null";
+ throw new Error("cc.AtlasNode.initWithTileFile(): title should not be null");
var texture = cc.textureCache.addImage(tile);
return this.initWithTexture(texture, tileWidth, tileHeight, itemsToRender);
},
@@ -244,7 +245,7 @@ cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
* @return {cc.Texture2D}
*/
getTexture: function(){
- return this._renderCmd.getTexture();
+ return this._texture;
},
/**
@@ -253,7 +254,7 @@ cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
* @param {cc.Texture2D} texture The new texture
*/
setTexture: function(texture){
- this._renderCmd.setTexture(texture);
+ this._texture = texture;
},
_setIgnoreContentScaleFactor: function (ignoreContentScaleFactor) {
diff --git a/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js
index 64e557c966..4fb324f4a9 100644
--- a/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js
@@ -25,37 +25,36 @@
/**
* cc.AtlasNode's rendering objects of Canvas
*/
-(function(){
- cc.AtlasNode.CanvasRenderCmd = function(renderableObject){
- cc.Node.CanvasRenderCmd.call(this, renderableObject);
+(function () {
+ cc.AtlasNode.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
this._needDraw = false;
this._colorUnmodified = cc.color.WHITE;
- this._originalTexture = null;
- this._texture = null;
+ this._textureToRender = null;
};
var proto = cc.AtlasNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
proto.constructor = cc.AtlasNode.CanvasRenderCmd;
- proto.initWithTexture = function(texture, tileWidth, tileHeight, itemsToRender){
+ proto.initWithTexture = function (texture, tileWidth, tileHeight, itemsToRender) {
var node = this._node;
node._itemWidth = tileWidth;
node._itemHeight = tileHeight;
node._opacityModifyRGB = true;
- this._originalTexture = texture;
- if (!this._originalTexture) {
+ node._texture = texture;
+ if (!node._texture) {
cc.log(cc._LogInfos.AtlasNode__initWithTexture);
return false;
}
- this._texture = this._originalTexture;
+ this._textureToRender = texture;
this._calculateMaxItems();
node.quadsToDraw = itemsToRender;
return true;
};
- proto.setColor = function(color3){
+ proto.setColor = function (color3) {
var node = this._node;
var locRealColor = node._realColor;
if ((locRealColor.r === color3.r) && (locRealColor.g === color3.g) && (locRealColor.b === color3.b))
@@ -64,72 +63,26 @@
this._changeTextureColor();
};
- if(cc.sys._supportCanvasNewBlendModes)
- proto._changeTextureColor = function(){
- var node = this._node;
- var locTexture = node.getTexture();
- if (locTexture && this._originalTexture) {
- var element = this._originalTexture.getHtmlElementObj();
- if(!element)
- return;
- var locElement = locTexture.getHtmlElementObj();
- var textureRect = cc.rect(0, 0, element.width, element.height);
- if (locElement instanceof HTMLCanvasElement)
- cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(element, this._colorUnmodified, textureRect, locElement);
- else {
- locElement = cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(element, this._colorUnmodified, textureRect);
- locTexture = new cc.Texture2D();
- locTexture.initWithElement(locElement);
- locTexture.handleLoadedTexture();
- node.setTexture(locTexture);
- }
- }
- };
- else
- proto._changeTextureColor = function(){
- var node = this._node;
- var locElement, locTexture = node.getTexture();
- if (locTexture && this._originalTexture) {
- locElement = locTexture.getHtmlElementObj();
- if (!locElement)
- return;
- var element = this._originalTexture.getHtmlElementObj();
- var cacheTextureForColor = cc.textureCache.getTextureColors(element);
- if (cacheTextureForColor) {
- var textureRect = cc.rect(0, 0, element.width, element.height);
- if (locElement instanceof HTMLCanvasElement)
- cc.Sprite.CanvasRenderCmd._generateTintImage(locElement, cacheTextureForColor, this._displayedColor, textureRect, locElement);
- else {
- locElement = cc.Sprite.CanvasRenderCmd._generateTintImage(locElement, cacheTextureForColor, this._displayedColor, textureRect);
- locTexture = new cc.Texture2D();
- locTexture.initWithElement(locElement);
- locTexture.handleLoadedTexture();
- node.setTexture(locTexture);
- }
- }
- }
- };
-
- proto.setOpacity = function(opacity){
+ proto._changeTextureColor = function () {
var node = this._node;
- cc.Node.prototype.setOpacity.call(node, opacity);
- // special opacity for premultiplied textures
- //if (node._opacityModifyRGB) {
- // node.color = this._colorUnmodified;
- //}
- };
-
- proto.getTexture = function(){
- return this._texture;
+ var texture = node._texture,
+ color = this._colorUnmodified,
+ element = texture.getHtmlElementObj();
+ var textureRect = cc.rect(0, 0, element.width, element.height);
+ if (texture === this._textureToRender)
+ this._textureToRender = texture._generateColorTexture(color.r, color.g, color.b, textureRect);
+ else
+ texture._generateColorTexture(color.r, color.g, color.b, textureRect, this._textureToRender.getHtmlElementObj());
};
- proto.setTexture = function (texture) {
- this._texture = texture;
+ proto.setOpacity = function (opacity) {
+ var node = this._node;
+ cc.Node.prototype.setOpacity.call(node, opacity);
};
- proto._calculateMaxItems = function(){
+ proto._calculateMaxItems = function () {
var node = this._node;
- var selTexture = this._texture;
+ var selTexture = node._texture;
var size = selTexture.getContentSize();
node._itemsPerColumn = 0 | (size.height / node._itemHeight);
diff --git a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
index d398f20eef..5810d00794 100644
--- a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
@@ -25,15 +25,18 @@
/**
* cc.AtlasNode's rendering objects of WebGL
*/
-(function(){
- cc.AtlasNode.WebGLRenderCmd = function(renderableObject){
- cc.Node.WebGLRenderCmd.call(this, renderableObject);
+(function () {
+ cc.AtlasNode.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
this._needDraw = true;
this._textureAtlas = null;
this._colorUnmodified = cc.color.WHITE;
this._colorF32Array = null;
this._uniformColor = null;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+
//shader stuff
this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR);
this._uniformColor = cc._renderContext.getUniformLocation(this._shaderProgram.getProgram(), "u_color");
@@ -57,8 +60,15 @@
proto.rendering = function (ctx) {
var context = ctx || cc._renderContext, node = this._node;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
if (this._uniformColor && this._colorF32Array) {
@@ -67,7 +77,7 @@
}
};
- proto.initWithTexture = function(texture, tileWidth, tileHeight, itemsToRender){
+ proto.initWithTexture = function (texture, tileWidth, tileHeight, itemsToRender) {
var node = this._node;
node._itemWidth = tileWidth;
node._itemHeight = tileHeight;
@@ -95,7 +105,7 @@
return true;
};
- proto.setColor = function(color3){
+ proto.setColor = function (color3) {
var temp = cc.color(color3.r, color3.g, color3.b), node = this._node;
this._colorUnmodified = color3;
var locDisplayedOpacity = this._displayedOpacity;
@@ -107,7 +117,7 @@
cc.Node.prototype.setColor.call(node, temp);
};
- proto.setOpacity = function(opacity){
+ proto.setOpacity = function (opacity) {
var node = this._node;
cc.Node.prototype.setOpacity.call(node, opacity);
// special opacity for premultiplied textures
@@ -116,23 +126,27 @@
}
};
- proto._updateColor = function(){
- var locDisplayedColor = this._displayedColor;
- this._colorF32Array = new Float32Array([locDisplayedColor.r / 255.0, locDisplayedColor.g / 255.0,
- locDisplayedColor.b / 255.0, this._displayedOpacity / 255.0]);
+ proto._updateColor = function () {
+ if (this._colorF32Array) {
+ var locDisplayedColor = this._displayedColor;
+ this._colorF32Array[0] = locDisplayedColor.r / 255.0;
+ this._colorF32Array[1] = locDisplayedColor.g / 255.0;
+ this._colorF32Array[2] = locDisplayedColor.b / 255.0;
+ this._colorF32Array[3] = this._displayedOpacity / 255.0;
+ }
};
- proto.getTexture = function(){
+ proto.getTexture = function () {
return this._textureAtlas.texture;
};
- proto.setTexture = function(texture){
+ proto.setTexture = function (texture) {
this._textureAtlas.texture = texture;
this._updateBlendFunc();
this._updateOpacityModifyRGB();
};
- proto._calculateMaxItems = function(){
+ proto._calculateMaxItems = function () {
var node = this._node;
var selTexture = this._textureAtlas.texture;
var size = selTexture.getContentSize();
@@ -142,4 +156,4 @@
node._itemsPerColumn = 0 | (size.height / node._itemHeight);
node._itemsPerRow = 0 | (size.width / node._itemWidth);
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/base-nodes/CCNode.js b/cocos2d/core/base-nodes/CCNode.js
index 5184a42b9c..9d3e6f15e5 100644
--- a/cocos2d/core/base-nodes/CCNode.js
+++ b/cocos2d/core/base-nodes/CCNode.js
@@ -85,7 +85,6 @@ cc.s_globalOrderOfArrival = 1;
* -# The node will be rotated (rotation)
* -# The node will be scaled (scale)
* -# The grid will capture the screen
- * -# The node will be moved according to the camera values (camera)
* -# The grid will render the captured screen
*
* @class
@@ -132,6 +131,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
_localZOrder: 0, ///< Local order (relative to its siblings) used to sort the node
_globalZOrder: 0, ///< Global order used to sort the node
_vertexZ: 0.0,
+ _customZ: NaN,
_rotationX: 0,
_rotationY: 0.0,
@@ -163,12 +163,10 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
//since 2.0 api
_reorderChildDirty: false,
- _shaderProgram: null,
arrivalOrder: 0,
_actionManager: null,
_scheduler: null,
- _eventDispatcher: null,
_additionalTransformDirty: false,
_additionalTransform: null,
@@ -186,38 +184,27 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
_renderCmd:null,
- _camera: null,
-
/**
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
* @function
*/
- ctor: function(){
- this._initNode();
- this._initRendererCmd();
- },
-
- _initNode: function () {
+ ctor: function () {
var _t = this;
_t._anchorPoint = cc.p(0, 0);
_t._contentSize = cc.size(0, 0);
_t._position = cc.p(0, 0);
- _t._normalizedPosition = cc.p(0,0);
+ _t._normalizedPosition = cc.p(0, 0);
_t._children = [];
var director = cc.director;
- _t._actionManager = director.getActionManager();
- _t._scheduler = director.getScheduler();
_t._additionalTransform = cc.affineTransformMakeIdentity();
if (cc.ComponentContainer) {
_t._componentContainer = new cc.ComponentContainer(_t);
}
-
- this._realOpacity = 255;
this._realColor = cc.color(255, 255, 255, 255);
- this._cascadeColorEnabled = false;
- this._cascadeOpacityEnabled = false;
+
+ this._renderCmd = this._createRenderCmd();
},
/**
@@ -226,72 +213,9 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @returns {boolean} Whether the initialization was successful.
*/
init: function () {
- //this._initNode(); //this has been called in ctor.
return true;
},
- _arrayMakeObjectsPerformSelector: function (array, callbackType) {
- if (!array || array.length === 0)
- return;
-
- var i, len = array.length, node;
- var nodeCallbackType = cc.Node._stateCallbackType;
- switch (callbackType) {
- case nodeCallbackType.onEnter:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.onEnter();
- }
- break;
- case nodeCallbackType.onExit:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.onExit();
- }
- break;
- case nodeCallbackType.onEnterTransitionDidFinish:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.onEnterTransitionDidFinish();
- }
- break;
- case nodeCallbackType.cleanup:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.cleanup();
- }
- break;
- case nodeCallbackType.updateTransform:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.updateTransform();
- }
- break;
- case nodeCallbackType.onExitTransitionDidStart:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.onExitTransitionDidStart();
- }
- break;
- case nodeCallbackType.sortAllChildren:
- for (i = 0; i < len; i++) {
- node = array[i];
- if (node)
- node.sortAllChildren();
- }
- break;
- default :
- cc.assert(0, cc._LogInfos.Node__arrayMakeObjectsPerformSelector);
- break;
- }
- },
-
/**
*
Properties configuration function
* All properties in attrs will be set to the node,
@@ -382,9 +306,12 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {Number} localZOrder
*/
setLocalZOrder: function (localZOrder) {
- this._localZOrder = localZOrder;
+ if (localZOrder === this._localZOrder)
+ return;
if (this._parent)
this._parent.reorderChild(this, localZOrder);
+ else
+ this._localZOrder = localZOrder;
cc.eventManager._setDirtyForNode(this);
},
@@ -487,7 +414,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {Number} Var
*/
setVertexZ: function (Var) {
- this._vertexZ = Var;
+ this._customZ = this._vertexZ = Var;
},
/**
@@ -651,12 +578,12 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
setPosition: function (newPosOrxValue, yValue) {
var locPosition = this._position;
if (yValue === undefined) {
- if(locPosition.x === newPosOrxValue.x && locPosition.y === newPosOrxValue.y)
+ if (locPosition.x === newPosOrxValue.x && locPosition.y === newPosOrxValue.y)
return;
locPosition.x = newPosOrxValue.x;
locPosition.y = newPosOrxValue.y;
} else {
- if(locPosition.x === newPosOrxValue && locPosition.y === yValue)
+ if (locPosition.x === newPosOrxValue && locPosition.y === yValue)
return;
locPosition.x = newPosOrxValue;
locPosition.y = yValue;
@@ -729,7 +656,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {Number}
*/
getPositionY: function () {
- return this._position.y;
+ return this._position.y;
},
/**
@@ -784,7 +711,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {Boolean} visible Pass true to make the node visible, false to hide the node.
*/
setVisible: function (visible) {
- if(this._visible !== visible){
+ if (this._visible !== visible) {
this._visible = visible;
//if(visible)
this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
@@ -944,6 +871,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
*/
setParent: function (parent) {
this._parent = parent;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
},
/**
@@ -1020,8 +948,8 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
* @param {String} name
*/
- setName: function(name){
- this._name = name;
+ setName: function (name) {
+ this._name = name;
},
/**
@@ -1029,7 +957,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
* @returns {string} A string that identifies the node.
*/
- getName: function(){
+ getName: function () {
return this._name;
},
@@ -1115,9 +1043,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.ActionManager} A CCActionManager object.
*/
getActionManager: function () {
- if (!this._actionManager)
- this._actionManager = cc.director.getActionManager();
- return this._actionManager;
+ return this._actionManager || cc.director.getActionManager();
},
/**
@@ -1141,9 +1067,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.Scheduler} A CCScheduler object.
*/
getScheduler: function () {
- if (!this._scheduler)
- this._scheduler = cc.director.getScheduler();
- return this._scheduler;
+ return this._scheduler || cc.director.getScheduler();
},
/**
@@ -1167,7 +1091,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @deprecated since v3.0, please use getBoundingBox instead
* @return {cc.Rect}
*/
- boundingBox: function(){
+ boundingBox: function () {
cc.log(cc._LogInfos.Node_boundingBox);
return this.getBoundingBox();
},
@@ -1194,9 +1118,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
// event
cc.eventManager.removeListeners(this);
-
- // timers
- this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.cleanup);
},
// composition: GET
@@ -1224,16 +1145,16 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {String} name A name to find the child node.
* @return {cc.Node} a CCNode object whose name equals to the input parameter
*/
- getChildByName: function(name){
- if(!name){
+ getChildByName: function (name) {
+ if (!name) {
cc.log("Invalid name");
return null;
}
var locChildren = this._children;
- for(var i = 0, len = locChildren.length; i < len; i++){
- if(locChildren[i]._name === name)
- return locChildren[i];
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ if (locChildren[i]._name === name)
+ return locChildren[i];
}
return null;
},
@@ -1246,18 +1167,17 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
* @param {cc.Node} child A child node
* @param {Number} [localZOrder=] Z order for drawing priority. Please refer to setZOrder(int)
- * @param {Number} [tag=] A integer to identify the node easily. Please refer to setTag(int)
+ * @param {Number|String} [tag=] An integer or a name to identify the node easily. Please refer to setTag(int) and setName(string)
*/
addChild: function (child, localZOrder, tag) {
localZOrder = localZOrder === undefined ? child._localZOrder : localZOrder;
var name, setTag = false;
- if(cc.isUndefined(tag)){
- tag = undefined;
+ if (tag === undefined) {
name = child._name;
- } else if(cc.isString(tag)){
+ } else if (typeof tag === 'string') {
name = tag;
tag = undefined;
- } else if(cc.isNumber(tag)){
+ } else if (typeof tag === 'number') {
setTag = true;
name = "";
}
@@ -1268,12 +1188,12 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
this._addChildHelper(child, localZOrder, tag, name, setTag);
},
- _addChildHelper: function(child, localZOrder, tag, name, setTag){
- if(!this._children)
+ _addChildHelper: function (child, localZOrder, tag, name, setTag) {
+ if (!this._children)
this._children = [];
this._insertChild(child, localZOrder);
- if(setTag)
+ if (setTag)
child.setTag(tag);
else
child.setName(name);
@@ -1281,12 +1201,13 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
child.setParent(this);
child.setOrderOfArrival(cc.s_globalOrderOfArrival++);
- if( this._running ){
- child.onEnter();
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onEnter);
// prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
if (this._isTransitionFinished)
- child.onEnterTransitionDidFinish();
+ child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
}
+ child._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
if (this._cascadeColorEnabled)
child._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
if (this._cascadeOpacityEnabled)
@@ -1387,13 +1308,13 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
var node = __children[i];
if (node) {
if (this._running) {
- node.onExitTransitionDidStart();
- node.onExit();
+ node._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ node._performRecursive(cc.Node._stateCallbackType.onExit);
}
// If you don't do cleanup, the node's actions will not get removed and the
if (cleanup)
- node.cleanup();
+ node._performRecursive(cc.Node._stateCallbackType.cleanup);
// set parent nil at the end
node.parent = null;
@@ -1410,13 +1331,13 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
// -1st do onExit
// -2nd cleanup
if (this._running) {
- child.onExitTransitionDidStart();
- child.onExit();
+ child._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ child._performRecursive(cc.Node._stateCallbackType.onExit);
}
// If you don't do cleanup, the child's actions will not get removed and the
if (doCleanup)
- child.cleanup();
+ child._performRecursive(cc.Node._stateCallbackType.cleanup);
// set parent nil at the end
child.parent = null;
@@ -1430,7 +1351,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
child._setLocalZOrder(z);
},
- setNodeDirty: function(){
+ setNodeDirty: function () {
this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
},
@@ -1442,10 +1363,15 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
*/
reorderChild: function (child, zOrder) {
cc.assert(child, cc._LogInfos.Node_reorderChild);
+ if (this._children.indexOf(child) === -1) {
+ cc.log(cc._LogInfos.Node_reorderChild_2);
+ return;
+ }
cc.renderer.childrenOrderDirty = this._reorderChildDirty = true;
child.arrivalOrder = cc.s_globalOrderOfArrival;
cc.s_globalOrderOfArrival++;
child._setLocalZOrder(zOrder);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.orderDirty);
},
/**
@@ -1462,22 +1388,22 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
// insertion sort
var len = _children.length, i, j, tmp;
- for(i=1; i= 0){
- if(tmp._localZOrder < _children[j]._localZOrder){
- _children[j+1] = _children[j];
- }else if(tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder){
- _children[j+1] = _children[j];
- }else{
+ while (j >= 0) {
+ if (tmp._localZOrder < _children[j]._localZOrder) {
+ _children[j + 1] = _children[j];
+ } else if (tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder) {
+ _children[j + 1] = _children[j];
+ } else {
break;
}
j--;
}
- _children[j+1] = tmp;
+ _children[j + 1] = tmp;
}
//don't need to check children recursively, that's done in visit of each child
@@ -1504,7 +1430,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
}
},
- //scene managment
+ //scene management
/**
*
* Event callback that is invoked every time when CCNode enters the 'stage'.
@@ -1517,10 +1443,72 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
onEnter: function () {
this._isTransitionFinished = false;
this._running = true;//should be running before resumeSchedule
- this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onEnter);
this.resume();
},
+ _performRecursive: function (callbackType) {
+ var nodeCallbackType = cc.Node._stateCallbackType;
+ if (callbackType >= nodeCallbackType.max) {
+ return;
+ }
+
+ var index = 0;
+ var children, child, curr, i, len;
+ var stack = cc.Node._performStacks[cc.Node._performing];
+ if (!stack) {
+ stack = [];
+ cc.Node._performStacks.push(stack);
+ }
+ stack.length = 0;
+ cc.Node._performing++;
+ curr = stack[0] = this;
+ while (curr) {
+ // Walk through children
+ children = curr._children;
+ if (children && children.length > 0) {
+ for (i = 0, len = children.length; i < len; ++i) {
+ child = children[i];
+ stack.push(child);
+ }
+ }
+ children = curr._protectedChildren;
+ if (children && children.length > 0) {
+ for (i = 0, len = children.length; i < len; ++i) {
+ child = children[i];
+ stack.push(child);
+ }
+ }
+
+ index++;
+ curr = stack[index];
+ }
+ for (i = stack.length - 1; i >= 0; --i) {
+ curr = stack[i];
+ stack[i] = null;
+ if (!curr) continue;
+
+ // Perform actual action
+ switch (callbackType) {
+ case nodeCallbackType.onEnter:
+ curr.onEnter();
+ break;
+ case nodeCallbackType.onExit:
+ curr.onExit();
+ break;
+ case nodeCallbackType.onEnterTransitionDidFinish:
+ curr.onEnterTransitionDidFinish();
+ break;
+ case nodeCallbackType.cleanup:
+ curr.cleanup();
+ break;
+ case nodeCallbackType.onExitTransitionDidStart:
+ curr.onExitTransitionDidStart();
+ break;
+ }
+ }
+ cc.Node._performing--;
+ },
+
/**
*
* Event callback that is invoked when the CCNode enters in the 'stage'.
@@ -1531,7 +1519,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
*/
onEnterTransitionDidFinish: function () {
this._isTransitionFinished = true;
- this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onEnterTransitionDidFinish);
},
/**
@@ -1541,7 +1528,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
*/
onExitTransitionDidStart: function () {
- this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onExitTransitionDidStart);
},
/**
@@ -1556,7 +1542,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
onExit: function () {
this._running = false;
this.pause();
- this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onExit);
this.removeAllComponents();
},
@@ -1680,49 +1665,49 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
*/
schedule: function (callback, interval, repeat, delay, key) {
var len = arguments.length;
- if(typeof callback === "function"){
+ if (typeof callback === "function") {
//callback, interval, repeat, delay, key
- if(len === 1){
+ if (len === 1) {
//callback
interval = 0;
repeat = cc.REPEAT_FOREVER;
delay = 0;
key = this.__instanceId;
- }else if(len === 2){
- if(typeof interval === "number"){
+ } else if (len === 2) {
+ if (typeof interval === "number") {
//callback, interval
repeat = cc.REPEAT_FOREVER;
delay = 0;
key = this.__instanceId;
- }else{
+ } else {
//callback, key
key = interval;
interval = 0;
repeat = cc.REPEAT_FOREVER;
delay = 0;
}
- }else if(len === 3){
- if(typeof repeat === "string"){
+ } else if (len === 3) {
+ if (typeof repeat === "string") {
//callback, interval, key
key = repeat;
repeat = cc.REPEAT_FOREVER;
- }else{
+ } else {
//callback, interval, repeat
key = this.__instanceId;
}
delay = 0;
- }else if(len === 4){
+ } else if (len === 4) {
key = this.__instanceId;
}
- }else{
+ } else {
//selector
//selector, interval
//selector, interval, repeat, delay
- if(len === 1){
+ if (len === 1) {
interval = 0;
repeat = cc.REPEAT_FOREVER;
delay = 0;
- }else if(len === 2){
+ } else if (len === 2) {
repeat = cc.REPEAT_FOREVER;
delay = 0;
}
@@ -1732,7 +1717,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
cc.assert(interval >= 0, cc._LogInfos.Node_schedule_2);
interval = interval || 0;
- repeat = (repeat == null) ? cc.REPEAT_FOREVER : repeat;
+ repeat = isNaN(repeat) ? cc.REPEAT_FOREVER : repeat;
delay = delay || 0;
this.scheduler.schedule(callback, this, interval, repeat, delay, !this._running, key);
@@ -1749,7 +1734,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
scheduleOnce: function (callback, delay, key) {
//selector, delay
//callback, delay, key
- if(key === undefined)
+ if (key === undefined)
key = this.__instanceId;
this.schedule(callback, 0, 0, delay, key);
},
@@ -1885,7 +1870,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.AffineTransform}
*/
getParentToNodeTransform: function () {
- this._renderCmd.getParentToNodeTransform();
+ return this._renderCmd.getParentToNodeTransform();
},
/**
@@ -1902,7 +1887,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.AffineTransform}
*/
getNodeToWorldTransform: function () {
- //TODO renderCmd has a WorldTransform
var t = this.getNodeToParentTransform();
for (var p = this._parent; p !== null; p = p.parent)
t = cc.affineTransformConcat(t, p.getNodeToParentTransform());
@@ -1913,7 +1897,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
* @deprecated since v3.0, please use getNodeToWorldTransform instead
*/
- nodeToWorldTransform: function(){
+ nodeToWorldTransform: function () {
return this.getNodeToWorldTransform();
},
@@ -1951,7 +1935,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.Point}
*/
convertToWorldSpace: function (nodePoint) {
- nodePoint = nodePoint || cc.p(0,0);
+ nodePoint = nodePoint || cc.p(0, 0);
return cc.pointApplyAffineTransform(nodePoint, this.getNodeToWorldTransform());
},
@@ -1974,7 +1958,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.Point}
*/
convertToWorldSpaceAR: function (nodePoint) {
- nodePoint = nodePoint || cc.p(0,0);
+ nodePoint = nodePoint || cc.p(0, 0);
var pt = cc.pAdd(nodePoint, this._renderCmd.getAnchorPointInPoints());
return this.convertToWorldSpace(pt);
},
@@ -2028,8 +2012,12 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
*/
updateTransform: function () {
- // Recursively iterate over children
- this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.updateTransform);
+ var children = this._children, node;
+ for (var i = 0; i < children.length; i++) {
+ node = children[i];
+ if (node)
+ node.updateTransform();
+ }
},
/**
@@ -2110,10 +2098,44 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
/**
* Recursive method that visit its children and draw them
* @function
- * @param {cc.Node.RenderCmd} parentCmd
+ * @param {cc.Node} parent
*/
- visit: function(parentCmd){
- this._renderCmd.visit(parentCmd);
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ var i, children = this._children, len = children.length, child;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(cmd);
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(cmd);
+ }
+ cmd._dirtyFlag = 0;
},
/**
@@ -2122,7 +2144,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {cc.Node.RenderCmd} parentCmd parent's render command
* @param {boolean} recursive whether call its children's transform
*/
- transform: function(parentCmd, recursive){
+ transform: function (parentCmd, recursive) {
this._renderCmd.transform(parentCmd, recursive);
},
@@ -2133,7 +2155,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @return {cc.AffineTransform}
* @deprecated since v3.0, please use getNodeToParentTransform instead
*/
- nodeToParentTransform: function(){
+ nodeToParentTransform: function () {
return this.getNodeToParentTransform();
},
@@ -2143,24 +2165,31 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @function
* @return {cc.AffineTransform} The affine transform object
*/
- getNodeToParentTransform: function(){
- return this._renderCmd.getNodeToParentTransform();
+ getNodeToParentTransform: function (ancestor) {
+ var t = this._renderCmd.getNodeToParentTransform();
+ if (ancestor) {
+ var T = {a: t.a, b: t.b, c: t.c, d: t.d, tx: t.tx, ty: t.ty};
+ for (var p = this._parent; p != null && p != ancestor; p = p.getParent()) {
+ cc.affineTransformConcatIn(T, p.getNodeToParentTransform());
+ }
+ return T;
+ } else {
+ return t;
+ }
+ },
+
+ getNodeToParentAffineTransform: function (ancestor) {
+ return this.getNodeToParentTransform(ancestor);
},
/**
- * Returns a camera object that lets you move the node using a gluLookAt
+ * Returns null
* @function
- * @return {cc.Camera} A CCCamera object that lets you move the node using a gluLookAt
+ * @return {null}
* @deprecated since v3.0, no alternative function
- * @example
- * var camera = node.getCamera();
- * camera.setEye(0, 0, 415/2);
- * camera.setCenter(0, 0, 0);
*/
getCamera: function () {
- if (!this._camera)
- this._camera = new cc.Camera();
- return this._camera;
+ return null;
},
/**
@@ -2210,6 +2239,14 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
this._renderCmd.setShaderProgram(newShaderProgram);
},
+ setGLProgramState: function (glProgramState) {
+ this._renderCmd.setGLProgramState(glProgramState);
+ },
+
+ getGLProgramState: function () {
+ return this._renderCmd.getGLProgramState();
+ },
+
/**
* Returns the state of OpenGL server side.
* @function
@@ -2419,12 +2456,8 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
return false;
},
- _initRendererCmd: function(){
- this._renderCmd = cc.renderer.getRenderCmd(this);
- },
-
- _createRenderCmd: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.Node.CanvasRenderCmd(this);
else
return new cc.Node.WebGLRenderCmd(this);
@@ -2456,7 +2489,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* And returns a boolean result. Your callback can return `true` to terminate the enumeration.
*
*/
- enumerateChildren: function(name, callback){
+ enumerateChildren: function (name, callback) {
cc.assert(name && name.length != 0, "Invalid name");
cc.assert(callback != null, "Invalid callback function");
@@ -2466,39 +2499,39 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
// Starts with '//'?
var searchRecursively = false;
- if(length > 2 && name[0] === "/" && name[1] === "/"){
+ if (length > 2 && name[0] === "/" && name[1] === "/") {
searchRecursively = true;
subStrStartPos = 2;
subStrlength -= 2;
}
var searchFromParent = false;
- if(length > 3 && name[length-3] === "/" && name[length-2] === "." && name[length-1] === "."){
+ if (length > 3 && name[length - 3] === "/" && name[length - 2] === "." && name[length - 1] === ".") {
searchFromParent = true;
subStrlength -= 3;
}
var newName = name.substr(subStrStartPos, subStrlength);
- if(searchFromParent)
+ if (searchFromParent)
newName = "[[:alnum:]]+/" + newName;
- if(searchRecursively)
+ if (searchRecursively)
this.doEnumerateRecursive(this, newName, callback);
else
this.doEnumerate(newName, callback);
},
- doEnumerateRecursive: function(node, name, callback){
+ doEnumerateRecursive: function (node, name, callback) {
var ret = false;
- if(node.doEnumerate(name,callback)){
+ if (node.doEnumerate(name, callback)) {
ret = true;
- }else{
+ } else {
var child,
children = node.getChildren(),
length = children.length;
// search its children
- for (var i=0; i 0) {
+ parentCmd = curr._renderCmd;
+ for (i = 0, len = children.length; i < len; ++i) {
+ child = children[i];
+ stack[index] = child;
+ index++;
+ child._renderCmd.transform(parentCmd);
+ }
+ }
+ var pChildren = curr._protectedChildren;
+ if (pChildren && pChildren.length > 0) {
+ parentCmd = curr._renderCmd;
+ for (i = 0, len = pChildren.length; i < len; ++i) {
+ child = pChildren[i];
+ stack[index] = child;
+ index++;
+ child._renderCmd.transform(parentCmd);
+ }
+ }
+ }
+ cc.Node._performing--;
+}
+//-------------------------Base -------------------------
+cc.Node.RenderCmd = function (renderable) {
this._node = renderable;
- this._needDraw = false;
- this._anchorPointInPoints = new cc.Point(0,0);
-
- this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
- this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
- this._inverse = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
-
- this._displayedOpacity = 255;
+ this._anchorPointInPoints = {x: 0, y: 0};
this._displayedColor = cc.color(255, 255, 255, 255);
- this._cascadeColorEnabledDirty = false;
- this._cascadeOpacityEnabledDirty = false;
-
- this._curLevel = -1;
};
cc.Node.RenderCmd.prototype = {
constructor: cc.Node.RenderCmd,
- getAnchorPointInPoints: function(){
+ _needDraw: false,
+ _dirtyFlag: 1,
+ _curLevel: -1,
+
+ _displayedOpacity: 255,
+ _cascadeColorEnabledDirty: false,
+ _cascadeOpacityEnabledDirty: false,
+
+ _transform: null,
+ _worldTransform: null,
+ _inverse: null,
+
+ needDraw: function () {
+ return this._needDraw;
+ },
+
+ getAnchorPointInPoints: function () {
return cc.p(this._anchorPointInPoints);
},
- getDisplayedColor: function(){
+ getDisplayedColor: function () {
var tmpColor = this._displayedColor;
return cc.color(tmpColor.r, tmpColor.g, tmpColor.b, tmpColor.a);
},
- getDisplayedOpacity: function(){
+ getDisplayedOpacity: function () {
return this._displayedOpacity;
},
- setCascadeColorEnabledDirty: function(){
+ setCascadeColorEnabledDirty: function () {
this._cascadeColorEnabledDirty = true;
this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
},
- setCascadeOpacityEnabledDirty:function(){
+ setCascadeOpacityEnabledDirty: function () {
this._cascadeOpacityEnabledDirty = true;
this.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
},
- getParentToNodeTransform: function(){
- if(this._dirtyFlag & cc.Node._dirtyFlags.transformDirty)
- this._inverse = cc.affineTransformInvert(this.getNodeToParentTransform());
+ getParentToNodeTransform: function () {
+ if (!this._inverse) {
+ this._inverse = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+ if (this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) {
+ cc.affineTransformInvertOut(this.getNodeToParentTransform(), this._inverse);
+ }
return this._inverse;
},
- detachFromParent: function(){},
+ detachFromParent: function () {
+ },
- _updateAnchorPointInPoint: function() {
+ _updateAnchorPointInPoint: function () {
var locAPP = this._anchorPointInPoints, locSize = this._node._contentSize, locAnchorPoint = this._node._anchorPoint;
locAPP.x = locSize.width * locAnchorPoint.x;
locAPP.y = locSize.height * locAnchorPoint.y;
this.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
},
- setDirtyFlag: function(dirtyFlag){
+ setDirtyFlag: function (dirtyFlag) {
if (this._dirtyFlag === 0 && dirtyFlag !== 0)
cc.renderer.pushDirtyNode(this);
this._dirtyFlag |= dirtyFlag;
},
- getParentRenderCmd: function(){
- if(this._node && this._node._parent && this._node._parent._renderCmd)
+ getParentRenderCmd: function () {
+ if (this._node && this._node._parent && this._node._parent._renderCmd)
return this._node._parent._renderCmd;
return null;
},
+ transform: function (parentCmd, recursive) {
+ if (!this._transform) {
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+
+ var node = this._node,
+ pt = parentCmd ? parentCmd._worldTransform : null,
+ t = this._transform,
+ wt = this._worldTransform; //get the world transform
+
+ if (node._usingNormalizedPosition && node._parent) {
+ var conSize = node._parent._contentSize;
+ node._position.x = node._normalizedPosition.x * conSize.width;
+ node._position.y = node._normalizedPosition.y * conSize.height;
+ node._normalizedPositionDirty = false;
+ }
+
+ var hasRotation = node._rotationX || node._rotationY;
+ var hasSkew = node._skewX || node._skewY;
+ var sx = node._scaleX, sy = node._scaleY;
+ var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y;
+ var a = 1, b = 0, c = 0, d = 1;
+ if (hasRotation || hasSkew) {
+ // position
+ t.tx = node._position.x;
+ t.ty = node._position.y;
+
+ // rotation
+ if (hasRotation) {
+ var rotationRadiansX = node._rotationX * ONE_DEGREE;
+ c = Math.sin(rotationRadiansX);
+ d = Math.cos(rotationRadiansX);
+ if (node._rotationY === node._rotationX) {
+ a = d;
+ b = -c;
+ }
+ else {
+ var rotationRadiansY = node._rotationY * ONE_DEGREE;
+ a = Math.cos(rotationRadiansY);
+ b = -Math.sin(rotationRadiansY);
+ }
+ }
+
+ // scale
+ t.a = a *= sx;
+ t.b = b *= sx;
+ t.c = c *= sy;
+ t.d = d *= sy;
+
+ // skew
+ if (hasSkew) {
+ var skx = Math.tan(node._skewX * ONE_DEGREE);
+ var sky = Math.tan(node._skewY * ONE_DEGREE);
+ if (skx === Infinity)
+ skx = 99999999;
+ if (sky === Infinity)
+ sky = 99999999;
+ t.a = a + c * sky;
+ t.b = b + d * sky;
+ t.c = c + a * skx;
+ t.d = d + b * skx;
+ }
+
+ if (appX || appY) {
+ t.tx -= t.a * appX + t.c * appY;
+ t.ty -= t.b * appX + t.d * appY;
+ // adjust anchorPoint
+ if (node._ignoreAnchorPointForPosition) {
+ t.tx += appX;
+ t.ty += appY;
+ }
+ }
+
+ if (node._additionalTransformDirty) {
+ cc.affineTransformConcatIn(t, node._additionalTransform);
+ }
+
+ if (pt) {
+ // cc.AffineTransformConcat is incorrect at get world transform
+ wt.a = t.a * pt.a + t.b * pt.c; //a
+ wt.b = t.a * pt.b + t.b * pt.d; //b
+ wt.c = t.c * pt.a + t.d * pt.c; //c
+ wt.d = t.c * pt.b + t.d * pt.d; //d
+ wt.tx = pt.a * t.tx + pt.c * t.ty + pt.tx;
+ wt.ty = pt.d * t.ty + pt.ty + pt.b * t.tx;
+ } else {
+ wt.a = t.a;
+ wt.b = t.b;
+ wt.c = t.c;
+ wt.d = t.d;
+ wt.tx = t.tx;
+ wt.ty = t.ty;
+ }
+ }
+ else {
+ t.a = sx;
+ t.b = 0;
+ t.c = 0;
+ t.d = sy;
+ t.tx = node._position.x;
+ t.ty = node._position.y;
+
+ if (appX || appY) {
+ t.tx -= t.a * appX;
+ t.ty -= t.d * appY;
+ // adjust anchorPoint
+ if (node._ignoreAnchorPointForPosition) {
+ t.tx += appX;
+ t.ty += appY;
+ }
+ }
+
+ if (node._additionalTransformDirty) {
+ cc.affineTransformConcatIn(t, node._additionalTransform);
+ }
+
+ if (pt) {
+ wt.a = t.a * pt.a + t.b * pt.c;
+ wt.b = t.a * pt.b + t.b * pt.d;
+ wt.c = t.c * pt.a + t.d * pt.c;
+ wt.d = t.c * pt.b + t.d * pt.d;
+ wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx;
+ wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty;
+ } else {
+ wt.a = t.a;
+ wt.b = t.b;
+ wt.c = t.c;
+ wt.d = t.d;
+ wt.tx = t.tx;
+ wt.ty = t.ty;
+ }
+ }
+
+ if (this._updateCurrentRegions) {
+ this._updateCurrentRegions();
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble);
+ }
+
+ if (recursive) {
+ transformChildTree(node);
+ }
+
+ this._cacheDirty = true;
+ },
+
+ getNodeToParentTransform: function () {
+ if (!this._transform || this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) {
+ this.transform();
+ }
+ return this._transform;
+ },
+
+ visit: function (parentCmd) {
+ var node = this._node, renderer = cc.renderer;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd)
+ this._curLevel = parentCmd._curLevel + 1;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ this._syncStatus(parentCmd);
+ },
+
_updateDisplayColor: function (parentColor) {
- var node = this._node;
- var locDispColor = this._displayedColor, locRealColor = node._realColor;
- var i, len, selChildren, item;
- if (this._cascadeColorEnabledDirty && !node._cascadeColorEnabled) {
- locDispColor.r = locRealColor.r;
- locDispColor.g = locRealColor.g;
- locDispColor.b = locRealColor.b;
- var whiteColor = new cc.Color(255, 255, 255, 255);
- selChildren = node._children;
- for (i = 0, len = selChildren.length; i < len; i++) {
- item = selChildren[i];
- if (item && item._renderCmd)
- item._renderCmd._updateDisplayColor(whiteColor);
- }
- this._cascadeColorEnabledDirty = false;
- } else {
- if (parentColor === undefined) {
- var locParent = node._parent;
- if (locParent && locParent._cascadeColorEnabled)
- parentColor = locParent.getDisplayedColor();
- else
- parentColor = cc.color.WHITE;
- }
- locDispColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
- locDispColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
- locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
- if (node._cascadeColorEnabled) {
- selChildren = node._children;
- for (i = 0, len = selChildren.length; i < len; i++) {
- item = selChildren[i];
- if (item && item._renderCmd){
- item._renderCmd._updateDisplayColor(locDispColor);
- item._renderCmd._updateColor();
- }
- }
- }
- }
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.colorDirty ^ this._dirtyFlag;
- },
+ var node = this._node;
+ var locDispColor = this._displayedColor, locRealColor = node._realColor;
+ var i, len, selChildren, item;
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ if (this._cascadeColorEnabledDirty && !node._cascadeColorEnabled) {
+ locDispColor.r = locRealColor.r;
+ locDispColor.g = locRealColor.g;
+ locDispColor.b = locRealColor.b;
+ var whiteColor = new cc.Color(255, 255, 255, 255);
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd)
+ item._renderCmd._updateDisplayColor(whiteColor);
+ }
+ this._cascadeColorEnabledDirty = false;
+ } else {
+ if (parentColor === undefined) {
+ var locParent = node._parent;
+ if (locParent && locParent._cascadeColorEnabled)
+ parentColor = locParent.getDisplayedColor();
+ else
+ parentColor = cc.color.WHITE;
+ }
+ locDispColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
+ locDispColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
+ locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
+ if (node._cascadeColorEnabled) {
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayColor(locDispColor);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ }
+ this._dirtyFlag &= ~dirtyFlags.colorDirty;
+ },
_updateDisplayOpacity: function (parentOpacity) {
var node = this._node;
var i, len, selChildren, item;
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
if (this._cascadeOpacityEnabledDirty && !node._cascadeOpacityEnabled) {
this._displayedOpacity = node._realOpacity;
selChildren = node._children;
@@ -176,17 +404,17 @@ cc.Node.RenderCmd.prototype = {
selChildren = node._children;
for (i = 0, len = selChildren.length; i < len; i++) {
item = selChildren[i];
- if (item && item._renderCmd){
+ if (item && item._renderCmd) {
item._renderCmd._updateDisplayOpacity(this._displayedOpacity);
item._renderCmd._updateColor();
}
}
}
}
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.opacityDirty ^ this._dirtyFlag;
+ this._dirtyFlag &= ~dirtyFlags.opacityDirty;
},
- _syncDisplayColor : function (parentColor) {
+ _syncDisplayColor: function (parentColor) {
var node = this._node, locDispColor = this._displayedColor, locRealColor = node._realColor;
if (parentColor === undefined) {
var locParent = node._parent;
@@ -200,7 +428,7 @@ cc.Node.RenderCmd.prototype = {
locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
},
- _syncDisplayOpacity : function (parentOpacity) {
+ _syncDisplayOpacity: function (parentOpacity) {
var node = this._node;
if (parentOpacity === undefined) {
var locParent = node._parent;
@@ -211,201 +439,58 @@ cc.Node.RenderCmd.prototype = {
this._displayedOpacity = node._realOpacity * parentOpacity / 255.0;
},
- _updateColor: function(){},
-
- updateStatus: function () {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
- if(colorDirty)
- this._updateDisplayColor();
-
- if(opacityDirty)
- this._updateDisplayOpacity();
-
- if(colorDirty || opacityDirty)
- this._updateColor();
+ _updateColor: function () {
+ },
- if(locFlag & flags.transformDirty){
- //update the transform
- this.transform(this.getParentRenderCmd(), true);
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag;
- }
- }
-};
+ _propagateFlagsDown: function (parentCmd) {
+ var locFlag = this._dirtyFlag;
+ var parentNode = parentCmd ? parentCmd._node : null;
-//-----------------------Canvas ---------------------------
+ if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & dirtyFlags.colorDirty))
+ locFlag |= dirtyFlags.colorDirty;
-(function() {
-//The cc.Node's render command for Canvas
- cc.Node.CanvasRenderCmd = function (renderable) {
- cc.Node.RenderCmd.call(this, renderable);
- this._cachedParent = null;
- this._cacheDirty = false;
+ if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & dirtyFlags.opacityDirty))
+ locFlag |= dirtyFlags.opacityDirty;
- };
+ if(parentCmd && (parentCmd._dirtyFlag & dirtyFlags.transformDirty))
+ locFlag |= dirtyFlags.transformDirty;
- var proto = cc.Node.CanvasRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
- proto.constructor = cc.Node.CanvasRenderCmd;
+ this._dirtyFlag = locFlag;
+ },
- proto.transform = function (parentCmd, recursive) {
- // transform for canvas
- var t = this.getNodeToParentTransform(),
- worldT = this._worldTransform; //get the world transform
- this._cacheDirty = true;
- if (parentCmd) {
- var pt = parentCmd._worldTransform;
- // cc.AffineTransformConcat is incorrect at get world transform
- worldT.a = t.a * pt.a + t.b * pt.c; //a
- worldT.b = t.a * pt.b + t.b * pt.d; //b
- worldT.c = t.c * pt.a + t.d * pt.c; //c
- worldT.d = t.c * pt.b + t.d * pt.d; //d
-
- worldT.tx = pt.a * t.tx + pt.c * t.ty + pt.tx;
- worldT.ty = pt.d * t.ty + pt.ty + pt.b * t.tx;
- } else {
- worldT.a = t.a;
- worldT.b = t.b;
- worldT.c = t.c;
- worldT.d = t.d;
- worldT.tx = t.tx;
- worldT.ty = t.ty;
- }
- if (recursive) {
- var locChildren = this._node._children;
- if (!locChildren || locChildren.length === 0)
- return;
- var i, len;
- for (i = 0, len = locChildren.length; i < len; i++) {
- locChildren[i]._renderCmd.transform(this, recursive);
- }
- }
- };
+ updateStatus: function () {
+ var locFlag = this._dirtyFlag;
+ var colorDirty = locFlag & dirtyFlags.colorDirty,
+ opacityDirty = locFlag & dirtyFlags.opacityDirty;
- proto.getNodeToParentTransform = function () {
- var node = this._node, normalizeDirty = false;
- if (node._usingNormalizedPosition && node._parent) { //TODO need refactor
- var conSize = node._parent._contentSize;
- node._position.x = node._normalizedPosition.x * conSize.width;
- node._position.y = node._normalizedPosition.y * conSize.height;
- node._normalizedPositionDirty = false;
- normalizeDirty = true;
+ if (locFlag & dirtyFlags.contentDirty) {
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ this._dirtyFlag &= ~dirtyFlags.contentDirty;
}
- if (normalizeDirty || (this._dirtyFlag & cc.Node._dirtyFlags.transformDirty)) {
- var t = this._transform;// quick reference
- // base position
- t.tx = node._position.x;
- t.ty = node._position.y;
-
- // rotation Cos and Sin
- var a = 1, b = 0,
- c = 0, d = 1;
- if (node._rotationX) {
- var rotationRadiansX = node._rotationX * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance
- c = Math.sin(rotationRadiansX);
- d = Math.cos(rotationRadiansX);
- }
-
- if (node._rotationY) {
- var rotationRadiansY = node._rotationY * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance
- a = Math.cos(rotationRadiansY);
- b = -Math.sin(rotationRadiansY);
- }
- t.a = a;
- t.b = b;
- t.c = c;
- t.d = d;
-
- var lScaleX = node._scaleX, lScaleY = node._scaleY;
- var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y;
-
- // Firefox on Vista and XP crashes
- // GPU thread in case of scale(0.0, 0.0)
- var sx = (lScaleX < 0.000001 && lScaleX > -0.000001) ? 0.000001 : lScaleX,
- sy = (lScaleY < 0.000001 && lScaleY > -0.000001) ? 0.000001 : lScaleY;
-
- // scale
- if (lScaleX !== 1 || lScaleY !== 1) {
- a = t.a *= sx;
- b = t.b *= sx;
- c = t.c *= sy;
- d = t.d *= sy;
- }
-
- // skew
- if (node._skewX || node._skewY) {
- // offset the anchorpoint
- var skx = Math.tan(-node._skewX * Math.PI / 180);
- var sky = Math.tan(-node._skewY * Math.PI / 180);
- if (skx === Infinity)
- skx = 99999999;
- if (sky === Infinity)
- sky = 99999999;
- var xx = appY * skx;
- var yy = appX * sky;
- t.a = a - c * sky;
- t.b = b - d * sky;
- t.c = c - a * skx;
- t.d = d - b * skx;
- t.tx += a * xx + c * yy;
- t.ty += b * xx + d * yy;
- }
+ if (colorDirty)
+ this._updateDisplayColor();
- // adjust anchorPoint
- t.tx -= a * appX + c * appY;
- t.ty -= b * appX + d * appY;
+ if (opacityDirty)
+ this._updateDisplayOpacity();
- // if ignore anchorPoint
- if (node._ignoreAnchorPointForPosition) {
- t.tx += appX;
- t.ty += appY;
- }
+ if (colorDirty || opacityDirty)
+ this._updateColor();
- if (node._additionalTransformDirty)
- this._transform = cc.affineTransformConcat(t, node._additionalTransform);
+ if (locFlag & dirtyFlags.transformDirty) {
+ //update the transform
+ this.transform(this.getParentRenderCmd(), true);
+ this._dirtyFlag &= ~dirtyFlags.transformDirty;
}
- return this._transform;
- };
- proto.visit = function (parentCmd) {
- var node = this._node;
- // quick return if not visible
- if (!node._visible)
- return;
-
- parentCmd = parentCmd || this.getParentRenderCmd();
- if (parentCmd)
- this._curLevel = parentCmd._curLevel + 1;
-
- //visit for canvas
- var i, children = node._children, child;
- this._syncStatus(parentCmd);
- var len = children.length;
- if (len > 0) {
- node.sortAllChildren();
- // draw children zOrder < 0
- for (i = 0; i < len; i++) {
- child = children[i];
- if (child._localZOrder < 0)
- child._renderCmd.visit(this);
- else
- break;
- }
- cc.renderer.pushRenderCommand(this);
- for (; i < len; i++)
- children[i]._renderCmd.visit(this);
- } else {
- cc.renderer.pushRenderCommand(this);
- }
- this._dirtyFlag = 0;
- };
+ if (locFlag & dirtyFlags.orderDirty)
+ this._dirtyFlag &= ~dirtyFlags.orderDirty;
+ },
- proto._syncStatus = function (parentCmd) {
+ _syncStatus: function (parentCmd) {
// In the visit logic does not restore the _dirtyFlag
// Because child elements need parent's _dirtyFlag to change himself
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var parentNode = parentCmd ? parentCmd._node : null;
+ var locFlag = this._dirtyFlag, parentNode = parentCmd ? parentCmd._node : null;
// There is a possibility:
// The parent element changed color, child element not change
@@ -413,21 +498,20 @@ cc.Node.RenderCmd.prototype = {
// But while the child element does not enter the circulation
// Here will be reset state in last
// In order the child elements get the parent state
- if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
- locFlag |= flags.colorDirty;
-
- if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
- locFlag |= flags.opacityDirty;
+ if (parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & dirtyFlags.colorDirty))
+ locFlag |= dirtyFlags.colorDirty;
- if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
- locFlag |= flags.transformDirty;
+ if (parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & dirtyFlags.opacityDirty))
+ locFlag |= dirtyFlags.opacityDirty;
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty,
- transformDirty = locFlag & flags.transformDirty;
+ if (parentCmd && (parentCmd._dirtyFlag & dirtyFlags.transformDirty))
+ locFlag |= dirtyFlags.transformDirty;
this._dirtyFlag = locFlag;
+ var colorDirty = locFlag & dirtyFlags.colorDirty,
+ opacityDirty = locFlag & dirtyFlags.opacityDirty;
+
if (colorDirty)
//update the color
this._syncDisplayColor();
@@ -436,20 +520,95 @@ cc.Node.RenderCmd.prototype = {
//update the opacity
this._syncDisplayOpacity();
- if(colorDirty)
+ if (colorDirty || opacityDirty)
this._updateColor();
- if (transformDirty){
+ if (locFlag & dirtyFlags.transformDirty)
//update the transform
this.transform(parentCmd);
+
+ if (locFlag & dirtyFlags.orderDirty)
+ this._dirtyFlag &= ~dirtyFlags.orderDirty;
+ },
+
+ setShaderProgram: function (shaderProgram) {
+ //do nothing.
+ },
+
+ getShaderProgram: function () {
+ return null;
+ },
+
+ getGLProgramState: function () {
+ return null;
+ },
+
+ setGLProgramState: function (glProgramState) {
+ // do nothing
+ },
+};
+
+cc.Node.RenderCmd.prototype.originTransform = cc.Node.RenderCmd.prototype.transform;
+cc.Node.RenderCmd.prototype.originUpdateStatus = cc.Node.RenderCmd.prototype.updateStatus;
+cc.Node.RenderCmd.prototype._originSyncStatus = cc.Node.RenderCmd.prototype._syncStatus;
+
+//-----------------------Canvas ---------------------------
+
+(function () {
+//The cc.Node's render command for Canvas
+ cc.Node.CanvasRenderCmd = function (renderable) {
+ this._node = renderable;
+ this._anchorPointInPoints = {x: 0, y: 0};
+ this._displayedColor = cc.color(255, 255, 255, 255);
+ this._cachedParent = null;
+ this._cacheDirty = false;
+ this._currentRegion = new cc.Region();
+ this._oldRegion = new cc.Region();
+ this._regionFlag = 0;
+ this._canUseDirtyRegion = false;
+ };
+
+ cc.Node.CanvasRenderCmd.RegionStatus = {
+ NotDirty: 0, //the region is not dirty
+ Dirty: 1, //the region is dirty, because of color, opacity or context
+ DirtyDouble: 2 //the region is moved, the old and the new one need considered when rendering
+ };
+
+ var proto = cc.Node.CanvasRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
+ proto.constructor = cc.Node.CanvasRenderCmd;
+ proto._rootCtor = cc.Node.CanvasRenderCmd;
+
+ proto._notifyRegionStatus = function (status) {
+ if (this._needDraw && this._regionFlag < status) {
+ this._regionFlag = status;
+ }
+ };
+
+ var localBB = new cc.Rect();
+ proto.getLocalBB = function () {
+ var node = this._node;
+ localBB.x = localBB.y = 0;
+ localBB.width = node._contentSize.width;
+ localBB.height = node._contentSize.height;
+ return localBB;
+ };
+
+ proto._updateCurrentRegions = function () {
+ var temp = this._currentRegion;
+ this._currentRegion = this._oldRegion;
+ this._oldRegion = temp;
+ //hittest will call the transform, and set region flag to DirtyDouble, and the changes need to be considered for rendering
+ if (cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble === this._regionFlag && (!this._currentRegion.isEmpty())) {
+ this._oldRegion.union(this._currentRegion);
}
+ this._currentRegion.updateRegion(this.getLocalBB(), this._worldTransform);
};
- proto.setDirtyFlag = function (dirtyFlag) {
- cc.Node.RenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag);
- this._setCacheDirty(); //TODO it should remove from here.
- if(this._cachedParent)
- this._cachedParent.setDirtyFlag(dirtyFlag);
+ proto.setDirtyFlag = function (dirtyFlag, child) {
+ cc.Node.RenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag, child);
+ this._setCacheDirty(child); //TODO it should remove from here.
+ if (this._cachedParent)
+ this._cachedParent.setDirtyFlag(dirtyFlag, true);
};
proto._setCacheDirty = function () {
@@ -480,14 +639,6 @@ cc.Node.RenderCmd.prototype = {
}
};
- proto.setShaderProgram = function (shaderProgram) {
- //do nothing.
- };
-
- proto.getShaderProgram = function () {
- return null;
- };
-
//util functions
cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc = function (blendFunc) {
if (!blendFunc)
@@ -503,4 +654,4 @@ cc.Node.RenderCmd.prototype = {
return "source-over";
}
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
index ce62ce39e3..7680017273 100644
--- a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
@@ -22,233 +22,44 @@
THE SOFTWARE.
****************************************************************************/
// ------------------------------ The cc.Node's render command for WebGL ----------------------------------
-(function() {
+(function () {
cc.Node.WebGLRenderCmd = function (renderable) {
- cc.Node.RenderCmd.call(this, renderable);
-
- var mat4 = new cc.math.Matrix4(), mat = mat4.mat;
- mat[2] = mat[3] = mat[6] = mat[7] = mat[8] = mat[9] = mat[11] = mat[14] = 0.0;
- mat[10] = mat[15] = 1.0;
- this._transform4x4 = mat4;
- this._stackMatrix = new cc.math.Matrix4();
- this._shaderProgram = null;
-
- this._camera = null;
+ this._node = renderable;
+ this._anchorPointInPoints = {x: 0, y: 0};
+ this._displayedColor = cc.color(255, 255, 255, 255);
+ this._glProgramState = null;
};
var proto = cc.Node.WebGLRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
proto.constructor = cc.Node.WebGLRenderCmd;
+ proto._rootCtor = cc.Node.WebGLRenderCmd;
- proto.getNodeToParentTransform = function () {
- var node = this._node;
- if (node._usingNormalizedPosition && node._parent) { //TODO need refactor
- var conSize = node._parent._contentSize;
- node._position.x = node._normalizedPosition.x * conSize.width;
- node._position.y = node._normalizedPosition.y * conSize.height;
- node._normalizedPositionDirty = false;
- }
- if (this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) {
- // Translate values
- var x = node._position.x, y = node._position.y;
- var apx = this._anchorPointInPoints.x, napx = -apx;
- var apy = this._anchorPointInPoints.y, napy = -apy;
- var scx = node._scaleX, scy = node._scaleY;
- var rotationRadiansX = node._rotationX * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance
- var rotationRadiansY = node._rotationY * 0.017453292519943295;
-
- if (node._ignoreAnchorPointForPosition) {
- x += apx;
- y += apy;
- }
-
- // Rotation values
- // Change rotation code to handle X and Y
- // If we skew with the exact same value for both x and y then we're simply just rotating
- var cx = 1, sx = 0, cy = 1, sy = 0;
- if (node._rotationX !== 0 || node._rotationY !== 0) {
- cx = Math.cos(-rotationRadiansX);
- sx = Math.sin(-rotationRadiansX);
- cy = Math.cos(-rotationRadiansY);
- sy = Math.sin(-rotationRadiansY);
- }
- var needsSkewMatrix = ( node._skewX || node._skewY );
-
- // optimization:
- // inline anchor point calculation if skew is not needed
- // Adjusted transform calculation for rotational skew
- if (!needsSkewMatrix && (apx !== 0 || apy !== 0)) {
- x += cy * napx * scx + -sx * napy * scy;
- y += sy * napx * scx + cx * napy * scy;
- }
-
- // Build Transform Matrix
- // Adjusted transform calculation for rotational skew
- var t = this._transform;
- t.a = cy * scx;
- t.b = sy * scx;
- t.c = -sx * scy;
- t.d = cx * scy;
- t.tx = x;
- t.ty = y;
-
- // XXX: Try to inline skew
- // If skew is needed, apply skew and then anchor point
- if (needsSkewMatrix) {
- t = cc.affineTransformConcat({a: 1.0, b: Math.tan(cc.degreesToRadians(node._skewY)),
- c: Math.tan(cc.degreesToRadians(node._skewX)), d: 1.0, tx: 0.0, ty: 0.0}, t);
-
- // adjust anchor point
- if (apx !== 0 || apy !== 0)
- t = cc.affineTransformTranslate(t, napx, napy);
- }
-
- if (node._additionalTransformDirty) {
- t = cc.affineTransformConcat(t, node._additionalTransform);
- node._additionalTransformDirty = false;
- }
- this._transform = t;
- }
- return this._transform;
+ proto._updateColor = function () {
};
- proto._syncStatus = function (parentCmd) {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var parentNode = parentCmd ? parentCmd._node : null;
-
- if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
- locFlag |= flags.colorDirty;
-
- if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
- locFlag |= flags.opacityDirty;
-
- if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
- locFlag |= flags.transformDirty;
-
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
-
- this._dirtyFlag = locFlag;
-
- if (colorDirty)
- this._syncDisplayColor();
-
- if (opacityDirty)
- this._syncDisplayOpacity();
-
- if(colorDirty || opacityDirty)
- this._updateColor();
-
- //if (locFlag & flags.transformDirty) { //need update the stackMatrix every calling visit, because when projection changed, need update all scene graph element.
- //update the transform
- this.transform(parentCmd);
- //}
+ proto.setShaderProgram = function (shaderProgram) {
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram);
};
- proto._updateColor = function(){};
-
- proto.visit = function (parentCmd) {
- var node = this._node;
- // quick return if not visible
- if (!node._visible)
- return;
-
- parentCmd = parentCmd || this.getParentRenderCmd();
- if (node._parent && node._parent._renderCmd)
- this._curLevel = node._parent._renderCmd._curLevel + 1;
-
- var i, currentStack = cc.current_stack;
-
- //optimize performance for javascript
- currentStack.stack.push(currentStack.top);
- this._syncStatus(parentCmd);
- currentStack.top = this._stackMatrix;
-
- var locChildren = node._children;
- if (locChildren && locChildren.length > 0) {
- var childLen = locChildren.length;
- node.sortAllChildren();
- // draw children zOrder < 0
- for (i = 0; i < childLen; i++) {
- if (locChildren[i] && locChildren[i]._localZOrder < 0)
- locChildren[i]._renderCmd.visit(this);
- else
- break;
- }
-
- cc.renderer.pushRenderCommand(this);
- // draw children zOrder >= 0
- for (; i < childLen; i++) {
- if (locChildren[i])
- locChildren[i]._renderCmd.visit(this);
- }
- } else
- cc.renderer.pushRenderCommand(this);
-
- this._dirtyFlag = 0;
- //optimize performance for javascript
- currentStack.top = currentStack.stack.pop();
+ proto.getShaderProgram = function () {
+ return this._glProgramState ? this._glProgramState.getGLProgram() : null;
};
- proto.transform = function (parentCmd, recursive) {
- var t4x4 = this._transform4x4, stackMatrix = this._stackMatrix, node = this._node;
- parentCmd = parentCmd || this.getParentRenderCmd();
- var parentMatrix = (parentCmd ? parentCmd._stackMatrix : cc.current_stack.top);
-
- // Convert 3x3 into 4x4 matrix
- var trans = this.getNodeToParentTransform();
-
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag;
-
- var t4x4Mat = t4x4.mat;
- t4x4Mat[0] = trans.a;
- t4x4Mat[4] = trans.c;
- t4x4Mat[12] = trans.tx;
- t4x4Mat[1] = trans.b;
- t4x4Mat[5] = trans.d;
- t4x4Mat[13] = trans.ty;
-
- // Update Z vertex manually
- t4x4Mat[14] = node._vertexZ;
-
- //optimize performance for Javascript
- cc.kmMat4Multiply(stackMatrix, parentMatrix, t4x4);
-
- // XXX: Expensive calls. Camera should be integrated into the cached affine matrix
- if (node._camera !== null && !(node.grid !== null && node.grid.isActive())) {
- var apx = this._anchorPointInPoints.x, apy = this._anchorPointInPoints.y;
- var translate = (apx !== 0.0 || apy !== 0.0);
- if (translate){
- if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) {
- apx = 0 | apx;
- apy = 0 | apy;
- }
- //cc.kmGLTranslatef(apx, apy, 0);
- var translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, t4x4); //t4x4 as a temp matrix
- stackMatrix.multiply(translation);
-
- node._camera._locateForRenderer(stackMatrix);
-
- //cc.kmGLTranslatef(-apx, -apy, 0); optimize at here : kmGLTranslatef
- translation = cc.math.Matrix4.createByTranslation(-apx, -apy, 0, translation);
- stackMatrix.multiply(translation);
- t4x4.identity(); //reset t4x4;
- } else {
- node._camera._locateForRenderer(stackMatrix);
- }
- }
- if(!recursive || !node._children || node._children.length === 0)
- return;
- var i, len, locChildren = node._children;
- for(i = 0, len = locChildren.length; i< len; i++){
- locChildren[i]._renderCmd.transform(this, recursive);
- }
+ proto.getGLProgramState = function () {
+ return this._glProgramState;
};
- proto.setShaderProgram = function (shaderProgram) {
- this._shaderProgram = shaderProgram;
+ proto.setGLProgramState = function (glProgramState) {
+ this._glProgramState = glProgramState;
};
- proto.getShaderProgram = function () {
- return this._shaderProgram;
- };
+ // Use a property getter/setter for backwards compatability, and
+ // to ease the transition from using glPrograms directly, to
+ // using glProgramStates.
+ Object.defineProperty(proto, '_shaderProgram', {
+ set: function (value) { this.setShaderProgram(value); },
+ get: function () { return this.getShaderProgram(); }
+ });
+ /** @expose */
+ proto._shaderProgram;
})();
diff --git a/cocos2d/core/cocoa/CCAffineTransform.js b/cocos2d/core/cocoa/CCAffineTransform.js
index d979b9d61b..8ff0957dfb 100644
--- a/cocos2d/core/cocoa/CCAffineTransform.js
+++ b/cocos2d/core/cocoa/CCAffineTransform.js
@@ -49,7 +49,7 @@ cc.AffineTransform = function (a, b, c, d, tx, ty) {
/**
* Create a cc.AffineTransform object with all contents in the matrix
* @function
- *
+ *
* @param {Number} a
* @param {Number} b
* @param {Number} c
@@ -65,7 +65,7 @@ cc.affineTransformMake = function (a, b, c, d, tx, ty) {
/**
* Apply the affine transformation on a point.
* @function
- *
+ *
* @param {cc.Point|Number} point or x
* @param {cc.AffineTransform|Number} transOrY transform matrix or y
* @param {cc.AffineTransform} t transform matrix or y
@@ -91,7 +91,7 @@ cc._pointApplyAffineTransform = function (x, y, t) { //it will remove.
/**
* Apply the affine transformation on a size.
* @function
- *
+ *
* @param {cc.Size} size
* @param {cc.AffineTransform} t
* @return {cc.Size}
@@ -105,7 +105,7 @@ cc.sizeApplyAffineTransform = function (size, t) {
* [ 1, 0, 0,
* 0, 1, 0 ]
* @function
- *
+ *
* @return {cc.AffineTransform}
* @deprecated since v3.0, please use cc.affineTransformMakeIdentity() instead
* @see cc.affineTransformMakeIdentity
@@ -129,7 +129,7 @@ cc.affineTransformIdentity = function () {
/**
* Apply the affine transformation on a rect.
* @function
- *
+ *
* @param {cc.Rect} rect
* @param {cc.AffineTransform} anAffineTransform
* @return {cc.Rect}
@@ -153,7 +153,7 @@ cc.rectApplyAffineTransform = function (rect, anAffineTransform) {
return cc.rect(minX, minY, (maxX - minX), (maxY - minY));
};
-cc._rectApplyAffineTransformIn = function(rect, anAffineTransform){
+cc._rectApplyAffineTransformIn = function (rect, anAffineTransform) {
var top = cc.rectGetMinY(rect);
var left = cc.rectGetMinX(rect);
var right = cc.rectGetMaxX(rect);
@@ -179,7 +179,7 @@ cc._rectApplyAffineTransformIn = function(rect, anAffineTransform){
/**
* Create a new affine transformation with a base transformation matrix and a translation based on it.
* @function
- *
+ *
* @param {cc.AffineTransform} t The base affine transform object
* @param {Number} tx The translation on x axis
* @param {Number} ty The translation on y axis
@@ -219,12 +219,14 @@ cc.affineTransformRotate = function (aTransform, anAngle) {
var fSin = Math.sin(anAngle);
var fCos = Math.cos(anAngle);
- return {a: aTransform.a * fCos + aTransform.c * fSin,
+ return {
+ a: aTransform.a * fCos + aTransform.c * fSin,
b: aTransform.b * fCos + aTransform.d * fSin,
c: aTransform.c * fCos - aTransform.a * fSin,
d: aTransform.d * fCos - aTransform.b * fSin,
tx: aTransform.tx,
- ty: aTransform.ty};
+ ty: aTransform.ty
+ };
};
/**
@@ -236,12 +238,34 @@ cc.affineTransformRotate = function (aTransform, anAngle) {
* @return {cc.AffineTransform} The result of concatenation
*/
cc.affineTransformConcat = function (t1, t2) {
- return {a: t1.a * t2.a + t1.b * t2.c, //a
+ return {
+ a: t1.a * t2.a + t1.b * t2.c, //a
b: t1.a * t2.b + t1.b * t2.d, //b
c: t1.c * t2.a + t1.d * t2.c, //c
d: t1.c * t2.b + t1.d * t2.d, //d
tx: t1.tx * t2.a + t1.ty * t2.c + t2.tx, //tx
- ty: t1.tx * t2.b + t1.ty * t2.d + t2.ty}; //ty
+ ty: t1.tx * t2.b + t1.ty * t2.d + t2.ty
+ }; //ty
+};
+
+/**
+ * Concatenate a transform matrix to another
+ * The results are reflected in the first matrix.
+ * t' = t1 * t2
+ * @function
+ * @param {cc.AffineTransform} t1 The first transform object
+ * @param {cc.AffineTransform} t2 The transform object to concatenate
+ * @return {cc.AffineTransform} The result of concatenation
+ */
+cc.affineTransformConcatIn = function (t1, t2) {
+ var a = t1.a, b = t1.b, c = t1.c, d = t1.d, tx = t1.tx, ty = t1.ty;
+ t1.a = a * t2.a + b * t2.c;
+ t1.b = a * t2.b + b * t2.d;
+ t1.c = c * t2.a + d * t2.c;
+ t1.d = c * t2.b + d * t2.d;
+ t1.tx = tx * t2.a + ty * t2.c + t2.tx;
+ t1.ty = tx * t2.b + ty * t2.d + t2.ty;
+ return t1;
};
/**
@@ -263,6 +287,19 @@ cc.affineTransformEqualToTransform = function (t1, t2) {
*/
cc.affineTransformInvert = function (t) {
var determinant = 1 / (t.a * t.d - t.b * t.c);
- return {a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
- tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)};
+ return {
+ a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
+ tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)
+ };
+};
+
+cc.affineTransformInvertOut = function (t, out) {
+ var a = t.a, b = t.b, c = t.c, d = t.d;
+ var determinant = 1 / (a * d - b * c);
+ out.a = determinant * d;
+ out.b = -determinant * b;
+ out.c = -determinant * c;
+ out.d = determinant * a;
+ out.tx = determinant * (c * t.ty - d * t.tx);
+ out.ty = determinant * (b * t.tx - a * t.ty);
};
diff --git a/cocos2d/core/cocoa/CCGeometry.js b/cocos2d/core/cocoa/CCGeometry.js
index 0eeffd5ad2..a3690f21c1 100644
--- a/cocos2d/core/cocoa/CCGeometry.js
+++ b/cocos2d/core/cocoa/CCGeometry.js
@@ -29,6 +29,9 @@
* @class cc.Point
* @param {Number} x
* @param {Number} y
+ *
+ * @property x {Number}
+ * @property y {Number}
* @see cc.p
*/
cc.Point = function (x, y) {
@@ -79,6 +82,8 @@ cc.pointEqualToPoint = function (point1, point2) {
* @class cc.Size
* @param {Number} width
* @param {Number} height
+ * @property {Number} width
+ * @property {Number} height
* @see cc.size
*/
cc.Size = function (width, height) {
@@ -127,8 +132,16 @@ cc.sizeEqualToSize = function (size1, size2) {
/**
* cc.Rect is the class for rect object, please do not use its constructor to create rects, use cc.rect() alias function instead.
* @class cc.Rect
+ * @param {Number} x
+ * @param {Number} y
* @param {Number} width
* @param {Number} height
+ *
+ * @property {Number} x
+ * @property {Number} y
+ * @property {Number} width
+ * @property {Number} height
+ *
* @see cc.rect
*/
cc.Rect = function (x, y, width, height) {
@@ -323,5 +336,3 @@ cc.rectIntersection = function (rectA, rectB) {
intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
return intersection;
};
-
-
diff --git a/cocos2d/core/event-manager/CCEventHelper.js b/cocos2d/core/event-manager/CCEventHelper.js
new file mode 100644
index 0000000000..b005e71c59
--- /dev/null
+++ b/cocos2d/core/event-manager/CCEventHelper.js
@@ -0,0 +1,138 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+// The event helper
+cc.EventHelper = function () {
+};
+
+cc.EventHelper.prototype = {
+ constructor: cc.EventHelper,
+
+ apply: function (object) {
+ object.addEventListener = cc.EventHelper.prototype.addEventListener;
+ object.hasEventListener = cc.EventHelper.prototype.hasEventListener;
+ object.removeEventListener = cc.EventHelper.prototype.removeEventListener;
+ object.dispatchEvent = cc.EventHelper.prototype.dispatchEvent;
+ },
+
+ addEventListener: function (type, listener, target) {
+ //check 'type' status, if the status is ready, dispatch event next frame
+ if (type === "load" && this._textureLoaded) { //only load event checked.
+ setTimeout(function () {
+ listener.call(target);
+ }, 0);
+ return;
+ }
+
+ if (this._listeners === undefined)
+ this._listeners = {};
+
+ var listeners = this._listeners;
+ if (listeners[type] === undefined)
+ listeners[type] = [];
+
+ if (!this.hasEventListener(type, listener, target))
+ listeners[type].push({callback: listener, eventTarget: target});
+ },
+
+ hasEventListener: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return false;
+
+ var listeners = this._listeners;
+ if (listeners[type] !== undefined) {
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var selListener = listeners[i];
+ if (selListener.callback === listener && selListener.eventTarget === target)
+ return true;
+ }
+ }
+ return false;
+ },
+
+ removeEventListener: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return;
+
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+
+ if (listenerArray !== undefined) {
+ for (var i = 0; i < listenerArray.length;) {
+ var selListener = listenerArray[i];
+ if (selListener.eventTarget === target && selListener.callback === listener)
+ listenerArray.splice(i, 1);
+ else
+ i++
+ }
+ }
+ },
+
+ removeEventTarget: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return;
+
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+
+ if (listenerArray !== undefined) {
+ for (var i = 0; i < listenerArray.length;) {
+ var selListener = listenerArray[i];
+ if (selListener.eventTarget === target)
+ listenerArray.splice(i, 1);
+ else
+ i++
+ }
+ }
+ },
+
+ dispatchEvent: function (event, clearAfterDispatch) {
+ if (this._listeners === undefined)
+ return;
+
+ if (clearAfterDispatch == null)
+ clearAfterDispatch = true;
+ var listeners = this._listeners;
+ var listenerArray = listeners[event];
+
+ if (listenerArray !== undefined) {
+ var array = [];
+ var length = listenerArray.length;
+
+ for (var i = 0; i < length; i++) {
+ array[i] = listenerArray[i];
+ }
+
+ for (i = 0; i < length; i++) {
+ array[i].callback.call(array[i].eventTarget, this);
+ }
+
+ if (clearAfterDispatch)
+ listenerArray.length = 0;
+ }
+ }
+};
+
+cc.EventHelper.prototype.apply(cc.game);
diff --git a/cocos2d/core/event-manager/CCEventListener.js b/cocos2d/core/event-manager/CCEventListener.js
index 3c9dbab79d..c970c43fdf 100644
--- a/cocos2d/core/event-manager/CCEventListener.js
+++ b/cocos2d/core/event-manager/CCEventListener.js
@@ -261,13 +261,13 @@ cc.EventListener.MOUSE = 4;
* @constant
* @type {number}
*/
-cc.EventListener.ACCELERATION = 5;
+cc.EventListener.ACCELERATION = 6;
/**
- * The type code of focus event listener.
+ * The type code of Focus change event listener.
* @constant
* @type {number}
*/
-cc.EventListener.ACCELERATION = 6;
+cc.EventListener.FOCUS = 7;
/**
* The type code of custom event listener.
* @constant
@@ -275,24 +275,18 @@ cc.EventListener.ACCELERATION = 6;
*/
cc.EventListener.CUSTOM = 8;
-/**
- * The type code of Focus change event listener.
- * @constant
- * @type {number}
- */
-cc.EventListener.FOCUS = 7;
-
cc._EventListenerCustom = cc.EventListener.extend({
_onCustomEvent: null,
- ctor: function (listenerId, callback) {
+ ctor: function (listenerId, callback, target) {
this._onCustomEvent = callback;
- var selfPointer = this;
- var listener = function (event) {
- if (selfPointer._onCustomEvent !== null)
- selfPointer._onCustomEvent(event);
- };
+ this._target = target;
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, this._callback);
+ },
+
+ _callback: function (event) {
+ if (this._onCustomEvent !== null)
+ this._onCustomEvent.call(this._target, event);
},
checkAvailable: function () {
@@ -315,31 +309,31 @@ cc._EventListenerMouse = cc.EventListener.extend({
onMouseScroll: null,
ctor: function () {
- var selfPointer = this;
- var listener = function (event) {
- var eventType = cc.EventMouse;
- switch (event._eventType) {
- case eventType.DOWN:
- if (selfPointer.onMouseDown)
- selfPointer.onMouseDown(event);
- break;
- case eventType.UP:
- if (selfPointer.onMouseUp)
- selfPointer.onMouseUp(event);
- break;
- case eventType.MOVE:
- if (selfPointer.onMouseMove)
- selfPointer.onMouseMove(event);
- break;
- case eventType.SCROLL:
- if (selfPointer.onMouseScroll)
- selfPointer.onMouseScroll(event);
- break;
- default:
- break;
- }
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, this._callback);
+ },
+
+ _callback: function (event) {
+ var eventType = cc.EventMouse;
+ switch (event._eventType) {
+ case eventType.DOWN:
+ if (this.onMouseDown)
+ this.onMouseDown(event);
+ break;
+ case eventType.UP:
+ if (this.onMouseUp)
+ this.onMouseUp(event);
+ break;
+ case eventType.MOVE:
+ if (this.onMouseMove)
+ this.onMouseMove(event);
+ break;
+ case eventType.SCROLL:
+ if (this.onMouseScroll)
+ this.onMouseScroll(event);
+ break;
+ default:
+ break;
+ }
},
clone: function () {
@@ -508,11 +502,12 @@ cc._EventListenerFocus = cc.EventListener.extend({
},
onFocusChanged: null,
ctor: function(){
- var listener = function(event){
- if(this.onFocusChanged)
- this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, this._callback);
+ },
+ _callback: function (event) {
+ if (this.onFocusChanged) {
+ this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
+ }
}
});
diff --git a/cocos2d/core/event-manager/CCEventManager.js b/cocos2d/core/event-manager/CCEventManager.js
index 46ba136659..7f54f03939 100644
--- a/cocos2d/core/event-manager/CCEventManager.js
+++ b/cocos2d/core/event-manager/CCEventManager.js
@@ -1,6 +1,6 @@
/****************************************************************************
Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
@@ -23,6 +23,8 @@
THE SOFTWARE.
****************************************************************************/
+(function () {
+
/**
* @ignore
*/
@@ -73,25 +75,25 @@ cc._EventListenerVector = cc.Class.extend({
}
});
-cc.__getListenerID = function (event) {
- var eventType = cc.Event, getType = event.getType();
- if(getType === eventType.ACCELERATION)
+function __getListenerID (event) {
+ var eventType = cc.Event, getType = event._type;
+ if (getType === eventType.ACCELERATION)
return cc._EventListenerAcceleration.LISTENER_ID;
- if(getType === eventType.CUSTOM)
- return event.getEventName();
- if(getType === eventType.KEYBOARD)
+ if (getType === eventType.CUSTOM)
+ return event._eventName;
+ if (getType === eventType.KEYBOARD)
return cc._EventListenerKeyboard.LISTENER_ID;
- if(getType === eventType.MOUSE)
+ if (getType === eventType.MOUSE)
return cc._EventListenerMouse.LISTENER_ID;
- if(getType === eventType.FOCUS)
+ if (getType === eventType.FOCUS)
return cc._EventListenerFocus.LISTENER_ID;
- if(getType === eventType.TOUCH){
+ if (getType === eventType.TOUCH) {
// Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
// return UNKNOWN instead.
cc.log(cc._LogInfos.__getListenerID);
}
return "";
-};
+}
/**
*
@@ -105,9 +107,9 @@ cc.__getListenerID = function (event) {
*/
cc.eventManager = /** @lends cc.eventManager# */{
//Priority dirty flag
- DIRTY_NONE:0,
- DIRTY_FIXED_PRIORITY:1 <<0,
- DIRTY_SCENE_GRAPH_PRIORITY : 1<< 1,
+ DIRTY_NONE: 0,
+ DIRTY_FIXED_PRIORITY: 1 << 0,
+ DIRTY_SCENE_GRAPH_PRIORITY: 1 << 1,
DIRTY_ALL: 3,
_listenersMap: {},
@@ -116,12 +118,13 @@ cc.eventManager = /** @lends cc.eventManager# */{
_nodePriorityMap: {},
_globalZOrderNodeMap: {},
_toAddedListeners: [],
+ _toRemovedListeners: [],
_dirtyNodes: [],
_inDispatch: 0,
_isEnabled: false,
_nodePriorityIndex: 0,
- _internalCustomListenerIDs:[cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
+ _internalCustomListenerIDs: [cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
_setDirtyForNode: function (node) {
// Mark the node dirty only when there is an event listener associated with it.
@@ -140,12 +143,12 @@ cc.eventManager = /** @lends cc.eventManager# */{
pauseTarget: function (node, recursive) {
var listeners = this._nodeListenersMap[node.__instanceId], i, len;
if (listeners) {
- for ( i = 0, len = listeners.length; i < len; i++)
+ for (i = 0, len = listeners.length; i < len; i++)
listeners[i]._setPaused(true);
}
if (recursive === true) {
var locChildren = node.getChildren();
- for ( i = 0, len = locChildren.length; i< len; i++)
+ for (i = 0, len = locChildren.length; i < len; i++)
this.pauseTarget(locChildren[i], true);
}
},
@@ -157,14 +160,14 @@ cc.eventManager = /** @lends cc.eventManager# */{
*/
resumeTarget: function (node, recursive) {
var listeners = this._nodeListenersMap[node.__instanceId], i, len;
- if (listeners){
- for ( i = 0, len = listeners.length; i < len; i++)
+ if (listeners) {
+ for (i = 0, len = listeners.length; i < len; i++)
listeners[i]._setPaused(false);
}
this._setDirtyForNode(node);
if (recursive === true) {
var locChildren = node.getChildren();
- for ( i = 0, len = locChildren.length; i< len; i++)
+ for (i = 0, len = locChildren.length; i< len; i++)
this.resumeTarget(locChildren[i], true);
}
},
@@ -228,7 +231,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
for (var i = 0; i < listenerVector.length;) {
selListener = listenerVector[i];
selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
+ if (selListener._getSceneGraphPriority() != null) {
this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
}
@@ -255,8 +258,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (!this._inDispatch) {
listeners.clear();
- delete this._listenersMap[listenerID];
}
+ delete this._listenersMap[listenerID];
}
var locToAddedListeners = this._toAddedListeners, listener;
@@ -270,7 +273,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
},
_sortEventListeners: function (listenerID) {
- var dirtyFlag = this.DIRTY_NONE, locFlagMap = this._priorityDirtyFlagMap;
+ var dirtyFlag = this.DIRTY_NONE, locFlagMap = this._priorityDirtyFlagMap;
if (locFlagMap[listenerID])
dirtyFlag = locFlagMap[listenerID];
@@ -281,9 +284,9 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (dirtyFlag & this.DIRTY_FIXED_PRIORITY)
this._sortListenersOfFixedPriority(listenerID);
- if (dirtyFlag & this.DIRTY_SCENE_GRAPH_PRIORITY){
+ if (dirtyFlag & this.DIRTY_SCENE_GRAPH_PRIORITY) {
var rootNode = cc.director.getRunningScene();
- if(rootNode)
+ if (rootNode)
this._sortListenersOfSceneGraphPriority(listenerID, rootNode);
else
locFlagMap[listenerID] = this.DIRTY_SCENE_GRAPH_PRIORITY;
@@ -297,7 +300,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
return;
var sceneGraphListener = listeners.getSceneGraphPriorityListeners();
- if(!sceneGraphListener || sceneGraphListener.length === 0)
+ if (!sceneGraphListener || sceneGraphListener.length === 0)
return;
// Reset priority index
@@ -310,11 +313,13 @@ cc.eventManager = /** @lends cc.eventManager# */{
listeners.getSceneGraphPriorityListeners().sort(this._sortEventListenersOfSceneGraphPriorityDes);
},
- _sortEventListenersOfSceneGraphPriorityDes : function(l1, l2){
+ _sortEventListenersOfSceneGraphPriorityDes: function (l1, l2) {
var locNodePriorityMap = cc.eventManager._nodePriorityMap, node1 = l1._getSceneGraphPriority(),
node2 = l2._getSceneGraphPriority();
- if(!l1 || !l2 || !node1 || !node2 || !locNodePriorityMap[node1.__instanceId] || !locNodePriorityMap[node2.__instanceId])
+ if (!l2 || !node2 || !locNodePriorityMap[node2.__instanceId])
return -1;
+ else if (!l1 || !node1 || !locNodePriorityMap[node1.__instanceId])
+ return 1;
return locNodePriorityMap[l2._getSceneGraphPriority().__instanceId] - locNodePriorityMap[l1._getSceneGraphPriority().__instanceId];
},
@@ -324,7 +329,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
return;
var fixedListeners = listeners.getFixedPriorityListeners();
- if(!fixedListeners || fixedListeners.length === 0)
+ if (!fixedListeners || fixedListeners.length === 0)
return;
// After sort: priority < 0, > 0
fixedListeners.sort(this._sortListenersOfFixedPriorityAsc);
@@ -343,20 +348,20 @@ cc.eventManager = /** @lends cc.eventManager# */{
return l1._getFixedPriority() - l2._getFixedPriority();
},
- _onUpdateListeners: function (listenerID) {
- var listeners = this._listenersMap[listenerID];
- if (!listeners)
- return;
-
+ _onUpdateListeners: function (listeners) {
var fixedPriorityListeners = listeners.getFixedPriorityListeners();
var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
- var i, selListener;
+ var i, selListener, idx, toRemovedListeners = this._toRemovedListeners;
if (sceneGraphPriorityListeners) {
for (i = 0; i < sceneGraphPriorityListeners.length;) {
selListener = sceneGraphPriorityListeners[i];
if (!selListener._isRegistered()) {
cc.arrayRemoveObject(sceneGraphPriorityListeners, selListener);
+ // if item in toRemove list, remove it from the list
+ idx = toRemovedListeners.indexOf(selListener);
+ if(idx !== -1)
+ toRemovedListeners.splice(idx, 1);
} else
++i;
}
@@ -365,9 +370,13 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (fixedPriorityListeners) {
for (i = 0; i < fixedPriorityListeners.length;) {
selListener = fixedPriorityListeners[i];
- if (!selListener._isRegistered())
+ if (!selListener._isRegistered()) {
cc.arrayRemoveObject(fixedPriorityListeners, selListener);
- else
+ // if item in toRemove list, remove it from the list
+ idx = toRemovedListeners.indexOf(selListener);
+ if(idx !== -1)
+ toRemovedListeners.splice(idx, 1);
+ } else
++i;
}
}
@@ -379,20 +388,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
listeners.clearFixedListeners();
},
- _updateListeners: function (event) {
- var locInDispatch = this._inDispatch;
- cc.assert(locInDispatch > 0, cc._LogInfos.EventManager__updateListeners);
-
- if(locInDispatch > 1)
- return;
-
- if (event.getType() === cc.Event.TOUCH) {
- this._onUpdateListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
- this._onUpdateListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
- } else
- this._onUpdateListeners(cc.__getListenerID(event));
-
- cc.assert(locInDispatch === 1, cc._LogInfos.EventManager__updateListeners_2);
+ frameUpdateListeners: function () {
var locListenersMap = this._listenersMap, locPriorityDirtyFlagMap = this._priorityDirtyFlagMap;
for (var selKey in locListenersMap) {
if (locListenersMap[selKey].empty()) {
@@ -405,11 +401,72 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (locToAddedListeners.length !== 0) {
for (var i = 0, len = locToAddedListeners.length; i < len; i++)
this._forceAddEventListener(locToAddedListeners[i]);
- this._toAddedListeners.length = 0;
+ locToAddedListeners.length = 0;
+ }
+ if (this._toRemovedListeners.length !== 0) {
+ this._cleanToRemovedListeners();
}
},
- _onTouchEventCallback: function(listener, argsObj){
+ _updateTouchListeners: function (event) {
+ var locInDispatch = this._inDispatch;
+ cc.assert(locInDispatch > 0, cc._LogInfos.EventManager__updateListeners);
+
+ if (locInDispatch > 1)
+ return;
+
+ var listeners;
+ listeners = this._listenersMap[cc._EventListenerTouchOneByOne.LISTENER_ID];
+ if (listeners) {
+ this._onUpdateListeners(listeners);
+ }
+ listeners = this._listenersMap[cc._EventListenerTouchAllAtOnce.LISTENER_ID];
+ if (listeners) {
+ this._onUpdateListeners(listeners);
+ }
+
+ cc.assert(locInDispatch === 1, cc._LogInfos.EventManager__updateListeners_2);
+
+ var locToAddedListeners = this._toAddedListeners;
+ if (locToAddedListeners.length !== 0) {
+ for (var i = 0, len = locToAddedListeners.length; i < len; i++)
+ this._forceAddEventListener(locToAddedListeners[i]);
+ locToAddedListeners.length = 0;
+ }
+ if (this._toRemovedListeners.length !== 0) {
+ this._cleanToRemovedListeners();
+ }
+ },
+
+ //Remove all listeners in _toRemoveListeners list and cleanup
+ _cleanToRemovedListeners: function () {
+ var toRemovedListeners = this._toRemovedListeners;
+ for (var i = 0; i < toRemovedListeners.length; i++) {
+ var selListener = toRemovedListeners[i];
+ var listeners = this._listenersMap[selListener._getListenerID()];
+ if (!listeners)
+ continue;
+
+ var idx, fixedPriorityListeners = listeners.getFixedPriorityListeners(),
+ sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+
+ if (sceneGraphPriorityListeners) {
+ idx = sceneGraphPriorityListeners.indexOf(selListener);
+ if (idx !== -1) {
+ sceneGraphPriorityListeners.splice(idx, 1);
+ }
+ }
+ if (fixedPriorityListeners) {
+ idx = fixedPriorityListeners.indexOf(selListener);
+ if (idx !== -1) {
+ fixedPriorityListeners.splice(idx, 1);
+ }
+ }
+ }
+ toRemovedListeners.length = 0;
+ },
+
+ _onTouchEventCallback: function (listener, argsObj) {
// Skip if the listener was removed.
if (!listener._isRegistered)
return false;
@@ -428,14 +485,14 @@ cc.eventManager = /** @lends cc.eventManager# */{
} else if (listener._claimedTouches.length > 0
&& ((removedIdx = listener._claimedTouches.indexOf(selTouch)) !== -1)) {
isClaimed = true;
- if(getCode === eventCode.MOVED && listener.onTouchMoved){
+ if (getCode === eventCode.MOVED && listener.onTouchMoved) {
listener.onTouchMoved(selTouch, event);
- } else if(getCode === eventCode.ENDED){
+ } else if (getCode === eventCode.ENDED) {
if (listener.onTouchEnded)
listener.onTouchEnded(selTouch, event);
if (listener._registered)
listener._claimedTouches.splice(removedIdx, 1);
- } else if(getCode === eventCode.CANCELLED){
+ } else if (getCode === eventCode.CANCELLED) {
if (listener.onTouchCancelled)
listener.onTouchCancelled(selTouch, event);
if (listener._registered)
@@ -445,7 +502,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
// If the event was stopped, return directly.
if (event.isStopped()) {
- cc.eventManager._updateListeners(event);
+ cc.eventManager._updateTouchListeners(event);
return true;
}
@@ -491,7 +548,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (event.isStopped())
return;
}
- this._updateListeners(event);
+ this._updateTouchListeners(event);
},
_onTouchesEventCallback: function (listener, callbackParams) {
@@ -501,18 +558,18 @@ cc.eventManager = /** @lends cc.eventManager# */{
var eventCode = cc.EventTouch.EventCode, event = callbackParams.event, touches = callbackParams.touches, getCode = event.getEventCode();
event._setCurrentTarget(listener._node);
- if(getCode === eventCode.BEGAN && listener.onTouchesBegan)
+ if (getCode === eventCode.BEGAN && listener.onTouchesBegan)
listener.onTouchesBegan(touches, event);
- else if(getCode === eventCode.MOVED && listener.onTouchesMoved)
+ else if (getCode === eventCode.MOVED && listener.onTouchesMoved)
listener.onTouchesMoved(touches, event);
- else if(getCode === eventCode.ENDED && listener.onTouchesEnded)
+ else if (getCode === eventCode.ENDED && listener.onTouchesEnded)
listener.onTouchesEnded(touches, event);
- else if(getCode === eventCode.CANCELLED && listener.onTouchesCancelled)
+ else if (getCode === eventCode.CANCELLED && listener.onTouchesCancelled)
listener.onTouchesCancelled(touches, event);
// If the event was stopped, return directly.
if (event.isStopped()) {
- cc.eventManager._updateListeners(event);
+ cc.eventManager._updateTouchListeners(event);
return true;
}
return false;
@@ -634,7 +691,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
}
},
- _sortNumberAsc : function (a, b) {
+ _sortNumberAsc: function (a, b) {
return a - b;
},
@@ -654,11 +711,11 @@ cc.eventManager = /** @lends cc.eventManager# */{
*/
addListener: function (listener, nodeOrPriority) {
cc.assert(listener && nodeOrPriority, cc._LogInfos.eventManager_addListener_2);
- if(!(listener instanceof cc.EventListener)){
+ if (!(listener instanceof cc.EventListener)) {
cc.assert(!cc.isNumber(nodeOrPriority), cc._LogInfos.eventManager_addListener_3);
listener = cc.EventListener.create(listener);
} else {
- if(listener._isRegistered()){
+ if (listener._isRegistered()) {
cc.log(cc._LogInfos.eventManager_addListener_4);
return;
}
@@ -694,8 +751,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
* @param {function} callback
* @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
*/
- addCustomListener: function (eventName, callback) {
- var listener = new cc._EventListenerCustom(eventName, callback);
+ addCustomListener: function (eventName, callback, target) {
+ var listener = new cc._EventListenerCustom(eventName, callback, target);
this.addListener(listener, 1);
return listener;
},
@@ -745,7 +802,28 @@ cc.eventManager = /** @lends cc.eventManager# */{
}
},
- _removeListenerInVector : function(listeners, listener){
+ _removeListenerInCallback: function (listeners, callback) {
+ if (listeners == null)
+ return false;
+
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var selListener = listeners[i];
+ if (selListener._onCustomEvent === callback || selListener._onEvent === callback) {
+ selListener._setRegistered(false);
+ if (selListener._getSceneGraphPriority() != null) {
+ this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
+ selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
+ }
+
+ if (this._inDispatch === 0)
+ cc.arrayRemoveObject(listeners, selListener);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _removeListenerInVector: function (listeners, listener) {
if (listeners == null)
return false;
@@ -753,13 +831,15 @@ cc.eventManager = /** @lends cc.eventManager# */{
var selListener = listeners[i];
if (selListener === listener) {
selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
+ if (selListener._getSceneGraphPriority() != null) {
this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
}
if (this._inDispatch === 0)
cc.arrayRemoveObject(listeners, selListener);
+ else
+ this._toRemovedListeners.push(selListener);
return true;
}
}
@@ -836,8 +916,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
*/
removeAllListeners: function () {
var locListeners = this._listenersMap, locInternalCustomEventIDs = this._internalCustomListenerIDs;
- for (var selKey in locListeners){
- if(locInternalCustomEventIDs.indexOf(selKey) === -1)
+ for (var selKey in locListeners) {
+ if (locInternalCustomEventIDs.indexOf(selKey) === -1)
this._removeListenersForListenerID(selKey);
}
},
@@ -858,7 +938,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (fixedPriorityListeners) {
var found = fixedPriorityListeners.indexOf(listener);
if (found !== -1) {
- if(listener._getSceneGraphPriority() != null)
+ if (listener._getSceneGraphPriority() != null)
cc.log(cc._LogInfos.eventManager_setPriority);
if (listener._getFixedPriority() !== fixedPriority) {
listener._setFixedPriority(fixedPriority);
@@ -896,25 +976,26 @@ cc.eventManager = /** @lends cc.eventManager# */{
this._updateDirtyFlagForSceneGraph();
this._inDispatch++;
- if(!event || !event.getType)
- throw "event is undefined";
- if (event.getType() === cc.Event.TOUCH) {
+ if (!event || !event.getType)
+ throw new Error("event is undefined");
+ if (event._type === cc.Event.TOUCH) {
this._dispatchTouchEvent(event);
this._inDispatch--;
return;
}
- var listenerID = cc.__getListenerID(event);
+ var listenerID = __getListenerID(event);
this._sortEventListeners(listenerID);
var selListeners = this._listenersMap[listenerID];
- if (selListeners != null)
+ if (selListeners) {
this._dispatchEventToListeners(selListeners, this._onListenerCallback, event);
-
- this._updateListeners(event);
+ this._onUpdateListeners(selListeners);
+ }
+
this._inDispatch--;
},
- _onListenerCallback: function(listener, event){
+ _onListenerCallback: function (listener, event) {
event._setCurrentTarget(listener._getSceneGraphPriority());
listener._onEvent(event);
return event.isStopped();
@@ -932,96 +1013,4 @@ cc.eventManager = /** @lends cc.eventManager# */{
}
};
-// The event helper
-cc.EventHelper = function(){};
-
-cc.EventHelper.prototype = {
- constructor: cc.EventHelper,
-
- apply: function ( object ) {
- object.addEventListener = cc.EventHelper.prototype.addEventListener;
- object.hasEventListener = cc.EventHelper.prototype.hasEventListener;
- object.removeEventListener = cc.EventHelper.prototype.removeEventListener;
- object.dispatchEvent = cc.EventHelper.prototype.dispatchEvent;
- },
-
- addEventListener: function ( type, listener, target ) {
- //check 'type' status, if the status is ready, dispatch event next frame
- if(type === "load" && this._textureLoaded){ //only load event checked.
- setTimeout(function(){
- listener.call(target);
- }, 0);
- return;
- }
-
- if ( this._listeners === undefined )
- this._listeners = {};
-
- var listeners = this._listeners;
- if ( listeners[ type ] === undefined )
- listeners[ type ] = [];
-
- if ( !this.hasEventListener(type, listener, target))
- listeners[ type ].push( {callback:listener, eventTarget: target} );
- },
-
- hasEventListener: function ( type, listener, target ) {
- if ( this._listeners === undefined )
- return false;
-
- var listeners = this._listeners;
- if ( listeners[ type ] !== undefined ) {
- for(var i = 0, len = listeners.length; i < len ; i++){
- var selListener = listeners[i];
- if(selListener.callback === listener && selListener.eventTarget === target)
- return true;
- }
- }
- return false;
- },
-
- removeEventListener: function( type, target){
- if ( this._listeners === undefined )
- return;
-
- var listeners = this._listeners;
- var listenerArray = listeners[ type ];
-
- if ( listenerArray !== undefined ) {
- for(var i = 0; i < listenerArray.length ; ){
- var selListener = listenerArray[i];
- if(selListener.eventTarget === target)
- listenerArray.splice( i, 1 );
- else
- i++
- }
- }
- },
-
- dispatchEvent: function ( event, clearAfterDispatch ) {
- if ( this._listeners === undefined )
- return;
-
- if(clearAfterDispatch == null)
- clearAfterDispatch = true;
- var listeners = this._listeners;
- var listenerArray = listeners[ event];
-
- if ( listenerArray !== undefined ) {
- var array = [];
- var length = listenerArray.length;
-
- for ( var i = 0; i < length; i ++ ) {
- array[ i ] = listenerArray[ i ];
- }
-
- for ( i = 0; i < length; i ++ ) {
- array[ i ].callback.call( array[i].eventTarget, this );
- }
-
- if(clearAfterDispatch)
- listenerArray.length = 0;
- }
- }
-};
-
+})();
diff --git a/cocos2d/core/event-manager/CCTouch.js b/cocos2d/core/event-manager/CCTouch.js
index 8a7c017aad..3c8ea79fb9 100644
--- a/cocos2d/core/event-manager/CCTouch.js
+++ b/cocos2d/core/event-manager/CCTouch.js
@@ -33,6 +33,7 @@
* @param {Number} id
*/
cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
+ _lastModified: 0,
_point:null,
_prevPoint:null,
_id:0,
@@ -40,8 +41,7 @@ cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
_startPoint:null,
ctor:function (x, y, id) {
- this._point = cc.p(x || 0, y || 0);
- this._id = id || 0;
+ this.setTouchInfo(id, x, y);
},
/**
@@ -136,7 +136,7 @@ cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
* @deprecated since v3.0, please use getID() instead
*/
getId:function () {
- cc.log("getId is deprecated. Please use getID instead.")
+ cc.log("getId is deprecated. Please use getID instead.");
return this._id;
},
@@ -150,8 +150,9 @@ cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
this._prevPoint = this._point;
this._point = cc.p(x || 0, y || 0);
this._id = id;
- if(!this._startPointCaptured){
+ if (!this._startPointCaptured) {
this._startPoint = cc.p(this._point);
+ cc.view._convertPointWithScale(this._startPoint);
this._startPointCaptured = true;
}
},
diff --git a/cocos2d/core/labelttf/CCLabelTTF.js b/cocos2d/core/labelttf/CCLabelTTF.js
index fb4855e6a5..ac988109b9 100644
--- a/cocos2d/core/labelttf/CCLabelTTF.js
+++ b/cocos2d/core/labelttf/CCLabelTTF.js
@@ -71,6 +71,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
_fontSize: 0.0,
_string: "",
_originalText: null,
+ _onCacheCanvasMode: true,
// font shadow
_shadowEnabled: false,
@@ -134,6 +135,11 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
this._renderCmd._setColorsString();
this._renderCmd._updateTexture();
this._setUpdateTextureDirty();
+
+ // Needed for high dpi text.
+ // In order to render it crisp, we request devicePixelRatio times the
+ // font size and scale it down 1/devicePixelRatio.
+ this._scaleX = this._scaleY = 1 / cc.view.getDevicePixelRatio();
return true;
},
@@ -290,7 +296,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
if (a.r != null && a.g != null && a.b != null && a.a != null) {
this._enableShadow(a, b, c);
} else {
- this._enableShadowNoneColor(a, b, c, d)
+ this._enableShadowNoneColor(a, b, c, d);
}
},
@@ -506,8 +512,8 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
this._fontName = textDefinition.fontName;
this._fontSize = textDefinition.fontSize || 12;
- if(textDefinition.lineHeight)
- this._lineHeight = textDefinition.lineHeight
+ if (textDefinition.lineHeight)
+ this._lineHeight = textDefinition.lineHeight;
else
this._lineHeight = this._fontSize;
@@ -531,7 +537,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
if (mustUpdateTexture)
this._renderCmd._updateTexture();
var flags = cc.Node._dirtyFlags;
- this._renderCmd.setDirtyFlag(flags.colorDirty|flags.opacityDirty|flags.textDirty);
+ this._renderCmd.setDirtyFlag(flags.colorDirty | flags.opacityDirty | flags.textDirty);
},
_prepareTextDefinition: function (adjustForResolution) {
@@ -577,6 +583,87 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
return texDef;
},
+ /*
+ * BEGIN SCALE METHODS
+ *
+ * In order to make the value of scaleX and scaleY consistent across
+ * screens, we provide patched versions that return the same values as if
+ * the screen was not HiDPI.
+ */
+
+ /**
+ * Returns the scale factor of the node.
+ * @warning: Assertion will fail when _scaleX != _scaleY.
+ * @function
+ * @return {Number} The scale factor
+ */
+ getScale: function () {
+ if (this._scaleX !== this._scaleY)
+ cc.log(cc._LogInfos.Node_getScale);
+ return this._scaleX * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ * Sets the scale factor of the node. 1.0 is the default scale factor. This function can modify the X and Y scale at the same time.
+ * @function
+ * @param {Number} scale or scaleX value
+ * @param {Number} [scaleY=]
+ */
+ setScale: function (scale, scaleY) {
+ var ratio = cc.view.getDevicePixelRatio();
+ this._scaleX = scale / ratio;
+ this._scaleY = ((scaleY || scaleY === 0) ? scaleY : scale) / ratio;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on X axis of this node
+ * @function
+ * @return {Number} The scale factor on X axis.
+ */
+ getScaleX: function () {
+ return this._scaleX * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ *
+ * Changes the scale factor on X axis of this node
+ * The default value is 1.0 if you haven't changed it before
+ *
+ * @function
+ * @param {Number} newScaleX The scale factor on X axis.
+ */
+ setScaleX: function (newScaleX) {
+ this._scaleX = newScaleX / cc.view.getDevicePixelRatio();
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on Y axis of this node
+ * @function
+ * @return {Number} The scale factor on Y axis.
+ */
+ getScaleY: function () {
+ return this._scaleY * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ *
+ * Changes the scale factor on Y axis of this node
+ * The Default value is 1.0 if you haven't changed it before.
+ *
+ * @function
+ * @param {Number} newScaleY The scale factor on Y axis.
+ */
+ setScaleY: function (newScaleY) {
+ this._scaleY = newScaleY / cc.view.getDevicePixelRatio();
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /*
+ * END SCALE METHODS
+ */
+
/**
* Changes the text content of the label
* @warning Changing the string is as expensive as creating a new cc.LabelTTF. To obtain better performance use cc.LabelAtlas
@@ -719,34 +806,61 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
getContentSize: function () {
if (this._needUpdateTexture)
this._renderCmd._updateTTF();
- return cc.Sprite.prototype.getContentSize.call(this);
+ var ratio = cc.view.getDevicePixelRatio();
+ return cc.size( this._contentSize.width / ratio, this._contentSize.height / ratio );
},
_getWidth: function () {
if (this._needUpdateTexture)
this._renderCmd._updateTTF();
- return cc.Sprite.prototype._getWidth.call(this);
+ return this._contentSize.width / cc.view.getDevicePixelRatio();
},
_getHeight: function () {
if (this._needUpdateTexture)
this._renderCmd._updateTTF();
- return cc.Sprite.prototype._getHeight.call(this);
+ return this._contentSize.height / cc.view.getDevicePixelRatio();
},
setTextureRect: function (rect, rotated, untrimmedSize) {
- //set needConvert to false
- cc.Sprite.prototype.setTextureRect.call(this, rect, rotated, untrimmedSize, false);
+ var _t = this;
+ _t._rectRotated = rotated || false;
+ _t.setContentSize(untrimmedSize || rect);
+
+ var locRect = _t._rect;
+ locRect.x = rect.x;
+ locRect.y = rect.y;
+ locRect.width = rect.width;
+ locRect.height = rect.height;
+ _t._renderCmd._setTextureCoords(rect, false);
+
+ var relativeOffsetX = _t._unflippedOffsetPositionFromCenter.x, relativeOffsetY = _t._unflippedOffsetPositionFromCenter.y;
+ if (_t._flippedX)
+ relativeOffsetX = -relativeOffsetX;
+ if (_t._flippedY)
+ relativeOffsetY = -relativeOffsetY;
+ _t._offsetPosition.x = relativeOffsetX + (rect.width - locRect.width) / 2;
+ _t._offsetPosition.y = relativeOffsetY + (rect.height - locRect.height) / 2;
+ },
+
+ /**
+ * set Target to draw on
+ * @param boolean onCanvas
+ */
+ setDrawMode: function (onCacheMode) {
+ this._onCacheCanvasMode = onCacheMode;
},
_createRenderCmd: function () {
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
- return new cc.LabelTTF.CanvasRenderCmd(this);
- else
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
return new cc.LabelTTF.WebGLRenderCmd(this);
+ else if (this._onCacheCanvasMode)
+ return new cc.LabelTTF.CacheCanvasRenderCmd(this);
+ else
+ return new cc.LabelTTF.CanvasRenderCmd(this);
},
//For web only
- _setFontStyle: function(fontStyle){
+ _setFontStyle: function (fontStyle) {
if (this._fontStyle !== fontStyle) {
this._fontStyle = fontStyle;
this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
@@ -754,11 +868,11 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
}
},
- _getFontStyle: function(){
+ _getFontStyle: function () {
return this._fontStyle;
},
- _setFontWeight: function(fontWeight){
+ _setFontWeight: function (fontWeight) {
if (this._fontWeight !== fontWeight) {
this._fontWeight = fontWeight;
this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
@@ -766,7 +880,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
}
},
- _getFontWeight: function(){
+ _getFontWeight: function () {
return this._fontWeight;
}
});
@@ -802,12 +916,7 @@ cc.LabelTTF.create = function (text, fontName, fontSize, dimensions, hAlignment,
*/
cc.LabelTTF.createWithFontDefinition = cc.LabelTTF.create;
-if (cc.USE_LA88_LABELS)
- cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTURECOLOR;
-else
- cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTUREA8COLOR;
-
-cc.LabelTTF.__labelHeightDiv = cc.newElement("div");
+cc.LabelTTF.__labelHeightDiv = document.createElement("div");
cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial";
cc.LabelTTF.__labelHeightDiv.style.position = "absolute";
cc.LabelTTF.__labelHeightDiv.style.left = "-100px";
@@ -816,19 +925,27 @@ cc.LabelTTF.__labelHeightDiv.style.lineHeight = "normal";
document.body ?
document.body.appendChild(cc.LabelTTF.__labelHeightDiv) :
- cc._addEventListener(window, 'load', function () {
+ window.addEventListener('load', function () {
this.removeEventListener('load', arguments.callee, false);
document.body.appendChild(cc.LabelTTF.__labelHeightDiv);
}, false);
+/**
+ * Returns the height of text with an specified font family and font size, in
+ * device independent pixels.
+ *
+ * @param {string|cc.FontDefinition} fontName
+ * @param {number} fontSize
+ * @returns {number}
+ * @private
+ */
cc.LabelTTF.__getFontHeightByDiv = function (fontName, fontSize) {
-
+ var clientHeight, labelDiv = cc.LabelTTF.__labelHeightDiv;
if(fontName instanceof cc.FontDefinition){
/** @type cc.FontDefinition */
var fontDef = fontName;
- var clientHeight = cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()];
+ clientHeight = cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()];
if (clientHeight > 0) return clientHeight;
- var labelDiv = cc.LabelTTF.__labelHeightDiv;
labelDiv.innerHTML = "ajghl~!";
labelDiv.style.fontFamily = fontDef.fontName;
labelDiv.style.fontSize = fontDef.fontSize + "px";
@@ -838,21 +955,20 @@ cc.LabelTTF.__getFontHeightByDiv = function (fontName, fontSize) {
clientHeight = labelDiv.clientHeight;
cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()] = clientHeight;
labelDiv.innerHTML = "";
- return clientHeight;
}
-
- //Default
- var clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize];
- if (clientHeight > 0) return clientHeight;
- var labelDiv = cc.LabelTTF.__labelHeightDiv;
- labelDiv.innerHTML = "ajghl~!";
- labelDiv.style.fontFamily = fontName;
- labelDiv.style.fontSize = fontSize + "px";
- clientHeight = labelDiv.clientHeight;
- cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight;
- labelDiv.innerHTML = "";
+ else {
+ //Default
+ clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize];
+ if (clientHeight > 0) return clientHeight;
+ labelDiv.innerHTML = "ajghl~!";
+ labelDiv.style.fontFamily = fontName;
+ labelDiv.style.fontSize = fontSize + "px";
+ clientHeight = labelDiv.clientHeight;
+ cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight;
+ labelDiv.innerHTML = "";
+ }
return clientHeight;
};
-cc.LabelTTF.__fontHeightCache = {};
\ No newline at end of file
+cc.LabelTTF.__fontHeightCache = {};
diff --git a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
index fa687f865a..44c8f1866f 100644
--- a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
+++ b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
@@ -1,18 +1,14 @@
/****************************************************************************
Copyright (c) 2013-2014 Chukong Technologies Inc.
-
http://www.cocos2d-x.org
-
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
-
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,15 +24,27 @@ cc.LabelTTF._textBaseline = ["top", "middle", "bottom"];
//check the first character
cc.LabelTTF.wrapInspection = true;
-//Support: English French German
-//Other as Oriental Language
-cc.LabelTTF._wordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)/;
-cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》?。,!]/;
-cc.LabelTTF._lastWordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)$/;
-cc.LabelTTF._lastEnglish = /[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+$/;
-cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
-
-(function() {
+// These regular expressions consider a word any sequence of characters
+// from these Unicode (sub)blocks:
+// - Basic Latin (letters and numbers, plus the hypen-minus '-')
+// - Latin-1 Supplement (accentuated letters and ¿¡ only)
+// - Latin Extended-A (complete)
+// - Latin Extended-B (complete)
+// - IPA Extensions (complete)
+// - Spacing Modifier Letters (complete)
+// - Combining Diacritical Marks (Combining Grapheme Joiner excluded)
+// - Greek and Coptic (complete, including reserved code points)
+// - Cyrillic (complete)
+// - Cyrillic Supplement (complete)
+// - General Punctuation (Non-Breaking Hyphen* [U+2011] and quotation marks)
+// * Note that Hyphen [U+2010] is considered a word boundary.
+cc.LabelTTF._wordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)/;
+cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》»?。,!\u2010′-‴›‼⁆⁇-⁉]/;
+cc.LabelTTF._lastWordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)$/;
+cc.LabelTTF._lastEnglish = /[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+$/;
+cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]/;
+
+(function () {
cc.LabelTTF.RenderCmd = function () {
this._fontClientHeight = 18;
this._fontStyleStr = "";
@@ -49,37 +57,22 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
this._lineWidths = [];
this._strings = [];
this._isMultiLine = false;
+ this._status = [];
+ this._renderingIndex = 0;
+
+ this._canUseDirtyRegion = true;
};
var proto = cc.LabelTTF.RenderCmd.prototype;
-
proto.constructor = cc.LabelTTF.RenderCmd;
-
- proto._getLabelContext = function () {
- if (this._labelContext)
- return this._labelContext;
-
- var node = this._node;
- if (!this._labelCanvas) {
- var locCanvas = cc.newElement("canvas");
- locCanvas.width = 1;
- locCanvas.height = 1;
- var labelTexture = new cc.Texture2D();
- labelTexture.initWithElement(locCanvas);
- node.setTexture(labelTexture);
- this._labelCanvas = locCanvas;
- }
- this._labelContext = this._labelCanvas.getContext("2d");
- return this._labelContext;
- };
+ proto._labelCmdCtor = cc.LabelTTF.RenderCmd;
proto._setFontStyle = function (fontNameOrFontDef, fontSize, fontStyle, fontWeight) {
-
- if(fontNameOrFontDef instanceof cc.FontDefinition){
+ if (fontNameOrFontDef instanceof cc.FontDefinition) {
this._fontStyleStr = fontNameOrFontDef._getCanvasFontStr();
this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontNameOrFontDef);
-
- }else {
- this._fontStyleStr = fontStyle + " " + fontWeight + " " + fontSize + "px '" + fontNameOrFontDef + "'";
+ } else {
+ var deviceFontSize = fontSize * cc.view.getDevicePixelRatio();
+ this._fontStyleStr = fontStyle + " " + fontWeight + " " + deviceFontSize + "px '" + fontNameOrFontDef + "'";
this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontNameOrFontDef, fontSize);
}
};
@@ -92,53 +85,45 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
return this._fontClientHeight;
};
- proto._updateTexture = function () {
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.textDirty ^ this._dirtyFlag;
- var node = this._node;
- var locContext = this._getLabelContext(), locLabelCanvas = this._labelCanvas;
- var locContentSize = node._contentSize;
-
- if (node._string.length === 0) {
- locLabelCanvas.width = 1;
- locLabelCanvas.height = locContentSize.height || 1;
- node._texture && node._texture.handleLoadedTexture();
- node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
- return true;
- }
-
- //set size for labelCanvas
- locContext.font = this._fontStyleStr;
- this._updateTTF();
- var width = locContentSize.width, height = locContentSize.height;
- var flag = locLabelCanvas.width === width && locLabelCanvas.height === height;
- locLabelCanvas.width = width;
- locLabelCanvas.height = height;
- if (flag) locContext.clearRect(0, 0, width, height);
-
- //draw text to labelCanvas
- this._drawTTFInCanvas(locContext);
- node._texture && node._texture.handleLoadedTexture();
-
- node.setTextureRect(cc.rect(0, 0, width, height));
- return true;
+ proto._updateColor = function () {
+ this._setColorsString();
+ this._updateTexture();
};
- proto._measureConfig = function () {
- this._getLabelContext().font = this._fontStyleStr;
+ proto._setColorsString = function () {
+ var locDisplayColor = this._displayedColor, node = this._node,
+ locShadowColor = node._shadowColor || this._displayedColor;
+ var locStrokeColor = node._strokeColor, locFontFillColor = node._textFillColor;
+ var dr = locDisplayColor.r / 255, dg = locDisplayColor.g / 255, db = locDisplayColor.b / 255;
+
+ this._shadowColorStr = "rgba(" + (0 | (dr * locShadowColor.r)) + "," + (0 | ( dg * locShadowColor.g)) + ","
+ + (0 | (db * locShadowColor.b)) + "," + node._shadowOpacity + ")";
+ this._fillColorStr = "rgba(" + (0 | (dr * locFontFillColor.r)) + "," + (0 | (dg * locFontFillColor.g)) + ","
+ + (0 | (db * locFontFillColor.b)) + ", 1)";
+ this._strokeColorStr = "rgba(" + (0 | (dr * locStrokeColor.r)) + "," + (0 | (dg * locStrokeColor.g)) + ","
+ + (0 | (db * locStrokeColor.b)) + ", 1)";
};
- proto._measure = function (text) {
- return this._getLabelContext().measureText(text).width;
+ var localBB = new cc.Rect();
+ proto.getLocalBB = function () {
+ var node = this._node;
+ localBB.x = localBB.y = 0;
+ var pixelRatio = cc.view.getDevicePixelRatio();
+ localBB.width = node._getWidth() * pixelRatio;
+ localBB.height = node._getHeight() * pixelRatio;
+ return localBB;
};
proto._updateTTF = function () {
var node = this._node;
- var locDimensionsWidth = node._dimensions.width, i, strLength;
+ var pixelRatio = cc.view.getDevicePixelRatio();
+ var locDimensionsWidth = node._dimensions.width * pixelRatio, i, strLength;
var locLineWidth = this._lineWidths;
locLineWidth.length = 0;
this._isMultiLine = false;
this._measureConfig();
+ var textWidthCache = {};
if (locDimensionsWidth !== 0) {
// Content processing
this._strings = node._string.split('\n');
@@ -149,11 +134,17 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
} else {
this._strings = node._string.split('\n');
for (i = 0, strLength = this._strings.length; i < strLength; i++) {
- locLineWidth.push(this._measure(this._strings[i]));
+ if(this._strings[i]) {
+ var measuredWidth = this._measure(this._strings[i]);
+ locLineWidth.push(measuredWidth);
+ textWidthCache[this._strings[i]] = measuredWidth;
+ } else {
+ locLineWidth.push(0);
+ }
}
}
- if (this._strings.length > 0)
+ if (this._strings.length > 1)
this._isMultiLine = true;
var locSize, locStrokeShadowOffsetX = 0, locStrokeShadowOffsetY = 0;
@@ -167,23 +158,36 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
//get offset for stroke and shadow
if (locDimensionsWidth === 0) {
- if (this._isMultiLine)
+ if (this._isMultiLine) {
locSize = cc.size(Math.ceil(Math.max.apply(Math, locLineWidth) + locStrokeShadowOffsetX),
- Math.ceil((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY));
- else
- locSize = cc.size(Math.ceil(this._measure(node._string) + locStrokeShadowOffsetX), Math.ceil(this._fontClientHeight + locStrokeShadowOffsetY));
+ Math.ceil((this._fontClientHeight * pixelRatio * this._strings.length) + locStrokeShadowOffsetY));
+ }
+ else {
+ var measuredWidth = textWidthCache[node._string];
+ if(!measuredWidth && node._string) {
+ measuredWidth = this._measure(node._string);
+ }
+ locSize = cc.size(Math.ceil((measuredWidth ? measuredWidth : 0) + locStrokeShadowOffsetX),
+ Math.ceil(this._fontClientHeight * pixelRatio + locStrokeShadowOffsetY));
+ }
} else {
if (node._dimensions.height === 0) {
if (this._isMultiLine)
- locSize = cc.size(Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX), Math.ceil((node.getLineHeight() * this._strings.length) + locStrokeShadowOffsetY));
+ locSize = cc.size(
+ Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX),
+ Math.ceil((node.getLineHeight() * pixelRatio * this._strings.length) + locStrokeShadowOffsetY));
else
- locSize = cc.size(Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX), Math.ceil(node.getLineHeight() + locStrokeShadowOffsetY));
+ locSize = cc.size(
+ Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX),
+ Math.ceil(node.getLineHeight() * pixelRatio + locStrokeShadowOffsetY));
} else {
//dimension is already set, contentSize must be same as dimension
- locSize = cc.size(Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX), Math.ceil(node._dimensions.height + locStrokeShadowOffsetY));
+ locSize = cc.size(
+ Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX),
+ Math.ceil(node._dimensions.height * pixelRatio + locStrokeShadowOffsetY));
}
}
- if(node._getFontStyle() !== "normal"){ //add width for 'italic' and 'oblique'
+ if (node._getFontStyle() !== "normal") { //add width for 'italic' and 'oblique'
locSize.width = Math.ceil(locSize.width + node._fontSize * 0.3);
}
node.setContentSize(locSize);
@@ -196,46 +200,20 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
this._anchorPointInPoints.y = (locStrokeShadowOffsetY * 0.5) + ((locSize.height - locStrokeShadowOffsetY) * locAP.y);
};
- proto._drawTTFInCanvas = function (context) {
- if (!context)
- return;
+ proto._saveStatus = function () {
var node = this._node;
+ var scale = cc.view.getDevicePixelRatio();
var locStrokeShadowOffsetX = node._strokeShadowOffsetX, locStrokeShadowOffsetY = node._strokeShadowOffsetY;
var locContentSizeHeight = node._contentSize.height - locStrokeShadowOffsetY, locVAlignment = node._vAlignment,
- locHAlignment = node._hAlignment, locStrokeSize = node._strokeSize;
-
- context.setTransform(1, 0, 0, 1, locStrokeShadowOffsetX * 0.5, locContentSizeHeight + locStrokeShadowOffsetY * 0.5);
-
- //this is fillText for canvas
- if (context.font !== this._fontStyleStr)
- context.font = this._fontStyleStr;
- context.fillStyle = this._fillColorStr;
-
- var xOffset = 0, yOffset = 0;
- //stroke style setup
- var locStrokeEnabled = node._strokeEnabled;
- if (locStrokeEnabled) {
- context.lineWidth = locStrokeSize * 2;
- context.strokeStyle = this._strokeColorStr;
- }
-
- //shadow style setup
- if (node._shadowEnabled) {
- var locShadowOffset = node._shadowOffset;
- context.shadowColor = this._shadowColorStr;
- context.shadowOffsetX = locShadowOffset.x;
- context.shadowOffsetY = -locShadowOffset.y;
- context.shadowBlur = node._shadowBlur;
- }
-
- context.textBaseline = cc.LabelTTF._textBaseline[locVAlignment];
- context.textAlign = cc.LabelTTF._textAlign[locHAlignment];
-
+ locHAlignment = node._hAlignment;
+ var dx = locStrokeShadowOffsetX * 0.5,
+ dy = locContentSizeHeight + locStrokeShadowOffsetY * 0.5;
+ var xOffset = 0, yOffset = 0, OffsetYArray = [];
var locContentWidth = node._contentSize.width - locStrokeShadowOffsetX;
//lineHeight
- var lineHeight = node.getLineHeight();
- var transformTop = (lineHeight - this._fontClientHeight) / 2;
+ var lineHeight = node.getLineHeight() * scale;
+ var transformTop = (lineHeight - this._fontClientHeight * scale) / 2;
if (locHAlignment === cc.TEXT_ALIGNMENT_RIGHT)
xOffset += locContentWidth;
@@ -243,6 +221,7 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
xOffset += locContentWidth / 2;
else
xOffset += 0;
+
if (this._isMultiLine) {
var locStrLen = this._strings.length;
if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM)
@@ -251,11 +230,8 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
yOffset = (lineHeight - transformTop * 2) / 2 + (locContentSizeHeight - lineHeight * locStrLen) / 2;
for (var i = 0; i < locStrLen; i++) {
- var line = this._strings[i];
var tmpOffsetY = -locContentSizeHeight + (lineHeight * i + transformTop) + yOffset;
- if (locStrokeEnabled)
- context.strokeText(line, xOffset, tmpOffsetY);
- context.fillText(line, xOffset, tmpOffsetY);
+ OffsetYArray.push(tmpOffsetY);
}
} else {
if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) {
@@ -265,10 +241,24 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
} else {
yOffset -= locContentSizeHeight * 0.5;
}
- if (locStrokeEnabled)
- context.strokeText(node._string, xOffset, yOffset);
- context.fillText(node._string, xOffset, yOffset);
+ OffsetYArray.push(yOffset);
}
+ var tmpStatus = {
+ contextTransform: cc.p(dx, dy),
+ xOffset: xOffset,
+ OffsetYArray: OffsetYArray
+ };
+ this._status.push(tmpStatus);
+ };
+
+ proto._drawTTFInCanvas = function (context) {
+ if (!context)
+ return;
+ var locStatus = this._status.pop();
+ context.setTransform(1, 0, 0, 1, locStatus.contextTransform.x, locStatus.contextTransform.y);
+ var xOffset = locStatus.xOffset;
+ var yOffsetArray = locStatus.OffsetYArray;
+ this.drawLabels(context, xOffset, yOffsetArray);
};
proto._checkWarp = function (strArr, i, maxWidth) {
@@ -321,6 +311,7 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
if (cc.LabelTTF._symbolRex.test(sLine || tmpText)) {
result = cc.LabelTTF._lastWordRex.exec(sText);
fuzzyLen -= result ? result[0].length : 0;
+ if (fuzzyLen === 0) fuzzyLen = 1;
sLine = text.substr(fuzzyLen);
sText = text.substr(0, fuzzyLen);
@@ -341,89 +332,239 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
strArr.splice(i, 0, sText);
}
};
+
+ proto.updateStatus = function () {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+
+ if (locFlag & flags.textDirty)
+ this._updateTexture();
+
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+
+ if (locFlag & flags.textDirty)
+ this._updateTexture();
+
+ this._originSyncStatus(parentCmd);
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL || locFlag & flags.transformDirty)
+ this.transform(parentCmd);
+ };
+
+ proto.drawLabels = function (context, xOffset, yOffsetArray) {
+ var node = this._node;
+ //shadow style setup
+ if (node._shadowEnabled) {
+ var locShadowOffset = node._shadowOffset;
+ context.shadowColor = this._shadowColorStr;
+ context.shadowOffsetX = locShadowOffset.x;
+ context.shadowOffsetY = -locShadowOffset.y;
+ context.shadowBlur = node._shadowBlur;
+ }
+
+ var locHAlignment = node._hAlignment,
+ locVAlignment = node._vAlignment,
+ locStrokeSize = node._strokeSize;
+
+ //this is fillText for canvas
+ if (context.font !== this._fontStyleStr)
+ context.font = this._fontStyleStr;
+ context.fillStyle = this._fillColorStr;
+
+ //stroke style setup
+ var locStrokeEnabled = node._strokeEnabled;
+ if (locStrokeEnabled) {
+ context.lineWidth = locStrokeSize * 2;
+ context.strokeStyle = this._strokeColorStr;
+ }
+
+ context.textBaseline = cc.LabelTTF._textBaseline[locVAlignment];
+ context.textAlign = cc.LabelTTF._textAlign[locHAlignment];
+
+ var locStrLen = this._strings.length;
+ for (var i = 0; i < locStrLen; i++) {
+ var line = this._strings[i];
+ if (locStrokeEnabled) {
+ context.lineJoin = 'round';
+ context.strokeText(line, xOffset, yOffsetArray[i]);
+ }
+ context.fillText(line, xOffset, yOffsetArray[i]);
+ }
+ cc.g_NumberOfDraws++;
+ };
})();
-(function(){
- cc.LabelTTF.CanvasRenderCmd = function (renderable) {
- cc.Sprite.CanvasRenderCmd.call(this, renderable);
- cc.LabelTTF.RenderCmd.call(this);
+(function () {
+ cc.LabelTTF.CacheRenderCmd = function () {
+ this._labelCmdCtor();
+ var locCanvas = this._labelCanvas = document.createElement("canvas");
+ locCanvas.width = 1;
+ locCanvas.height = 1;
+ this._labelContext = locCanvas.getContext("2d");
};
- cc.LabelTTF.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
- cc.inject(cc.LabelTTF.RenderCmd.prototype, cc.LabelTTF.CanvasRenderCmd.prototype);
+ cc.LabelTTF.CacheRenderCmd.prototype = Object.create(cc.LabelTTF.RenderCmd.prototype);
+ cc.inject(cc.LabelTTF.RenderCmd.prototype, cc.LabelTTF.CacheRenderCmd.prototype);
- var proto = cc.LabelTTF.CanvasRenderCmd.prototype;
- proto.constructor = cc.LabelTTF.CanvasRenderCmd;
+ var proto = cc.LabelTTF.CacheRenderCmd.prototype;
+ proto.constructor = cc.LabelTTF.CacheRenderCmd;
+ proto._cacheCmdCtor = cc.LabelTTF.CacheRenderCmd;
- proto.updateStatus = function () {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
+ proto._updateTexture = function () {
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.textDirty ^ this._dirtyFlag;
+ var node = this._node;
+ node._needUpdateTexture = false;
+ var locContentSize = node._contentSize;
+ this._updateTTF();
+ var width = locContentSize.width, height = locContentSize.height;
- if (colorDirty)
- this._updateDisplayColor();
- if (opacityDirty)
- this._updateDisplayOpacity();
+ var locContext = this._labelContext, locLabelCanvas = this._labelCanvas;
- if(colorDirty){
- this._updateColor();
- }else if(locFlag & flags.textDirty)
- this._updateTexture();
+ if (!node._texture) {
+ var labelTexture = new cc.Texture2D();
+ labelTexture.initWithElement(this._labelCanvas);
+ node.setTexture(labelTexture);
+ }
+
+ if (node._string.length === 0) {
+ locLabelCanvas.width = 1;
+ locLabelCanvas.height = locContentSize.height || 1;
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
+ node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
+ return true;
+ }
- if (this._dirtyFlag & flags.transformDirty){
- this.transform(this.getParentRenderCmd(), true);
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag;
+ //set size for labelCanvas
+ locContext.font = this._fontStyleStr;
+
+ var flag = locLabelCanvas.width === width && locLabelCanvas.height === height;
+ locLabelCanvas.width = width;
+ locLabelCanvas.height = height;
+ if (flag) locContext.clearRect(0, 0, width, height);
+ this._saveStatus();
+ this._drawTTFInCanvas(locContext);
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
}
+ node.setTextureRect(cc.rect(0, 0, width, height));
+ return true;
};
- proto._syncStatus = function (parentCmd) {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var parentNode = parentCmd ? parentCmd._node : null;
+ proto._measureConfig = function () {
+ this._labelContext.font = this._fontStyleStr;
+ };
- if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
- locFlag |= flags.colorDirty;
+ proto._measure = function (text) {
+ if (text) {
+ return this._labelContext.measureText(text).width;
+ } else {
+ return 0;
+ }
+ };
- if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
- locFlag |= flags.opacityDirty;
+})();
- if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
- locFlag |= flags.transformDirty;
+(function () {
+ cc.LabelTTF.CacheCanvasRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ this._cacheCmdCtor();
+ };
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
+ var proto = cc.LabelTTF.CacheCanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto);
+ proto.constructor = cc.LabelTTF.CacheCanvasRenderCmd;
+})();
- this._dirtyFlag = locFlag;
+(function () {
+ cc.LabelTTF.CanvasRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ this._labelCmdCtor();
+ };
- if (colorDirty)
- this._syncDisplayColor();
- if (opacityDirty)
- this._syncDisplayOpacity();
+ cc.LabelTTF.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ cc.inject(cc.LabelTTF.RenderCmd.prototype, cc.LabelTTF.CanvasRenderCmd.prototype);
- if(colorDirty){
- this._updateColor();
- }else if(locFlag & flags.textDirty)
- this._updateTexture();
+ var proto = cc.LabelTTF.CanvasRenderCmd.prototype;
+ proto.constructor = cc.LabelTTF.CanvasRenderCmd;
- if (locFlag & flags.transformDirty) //update the transform
- this.transform(parentCmd);
+ proto._measureConfig = function () {
};
- proto._setColorsString = function () {
- var locDisplayColor = this._displayedColor, node = this._node,
- locShadowColor = node._shadowColor || this._displayedColor;
- var locStrokeColor = node._strokeColor, locFontFillColor = node._textFillColor;
- var dr = locDisplayColor.r / 255, dg = locDisplayColor.g / 255, db = locDisplayColor.b / 255;
+ proto._measure = function (text) {
+ if(text) {
+ var context = cc._renderContext.getContext();
+ context.font = this._fontStyleStr;
+ return context.measureText(text).width;
+ } else {
+ return 0;
+ }
+ };
- this._shadowColorStr = "rgba(" + (0 | (dr * locShadowColor.r)) + "," + (0 | ( dg * locShadowColor.g)) + ","
- + (0 | (db * locShadowColor.b)) + "," + node._shadowOpacity + ")";
- this._fillColorStr = "rgba(" + (0 | (dr * locFontFillColor.r)) + "," + (0 | (dg * locFontFillColor.g)) + ","
- + (0 | (db * locFontFillColor.b)) + ", 1)";
- this._strokeColorStr = "rgba(" + (0 | (dr * locStrokeColor.r)) + "," + (0 | (dg * locStrokeColor.g)) + ","
- + (0 | (db * locStrokeColor.b)) + ", 1)";
+ proto._updateTexture = function () {
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.textDirty ^ this._dirtyFlag;
+ var node = this._node;
+ var locContentSize = node._contentSize;
+ this._updateTTF();
+ var width = locContentSize.width, height = locContentSize.height;
+ if (node._string.length === 0) {
+ node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
+ return true;
+ }
+ this._saveStatus();
+ node.setTextureRect(cc.rect(0, 0, width, height));
+ return true;
};
- proto._updateColor = function(){
- this._setColorsString();
- this._updateTexture();
+ proto.rendering = function (ctx) {
+ var scaleX = cc.view.getScaleX(),
+ scaleY = cc.view.getScaleY();
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ if (!context)
+ return;
+ var node = this._node;
+ wrapper.computeRealOffsetY();
+ if (this._status.length <= 0)
+ return;
+ var locIndex = (this._renderingIndex >= this._status.length) ? this._renderingIndex - this._status.length : this._renderingIndex;
+ var status = this._status[locIndex];
+ this._renderingIndex = locIndex + 1;
+
+ var locHeight = node._rect.height,
+ locX = node._offsetPosition.x,
+ locY = -node._offsetPosition.y - locHeight;
+
+ var alpha = (this._displayedOpacity / 255);
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setCompositeOperation(this._blendFuncStr);
+ wrapper.setGlobalAlpha(alpha);
+
+ wrapper.save();
+
+ if (node._flippedX) {
+ locX = -locX - node._rect.width;
+ context.scale(-1, 1);
+ }
+ if (node._flippedY) {
+ locY = node._offsetPosition.y;
+ context.scale(1, -1);
+ }
+
+ var xOffset = status.xOffset + status.contextTransform.x + locX * scaleX;
+ var yOffsetArray = [];
+
+ var locStrLen = this._strings.length;
+ for (var i = 0; i < locStrLen; i++)
+ yOffsetArray.push(status.OffsetYArray[i] + status.contextTransform.y + locY * scaleY);
+
+ this.drawLabels(context, xOffset, yOffsetArray);
+ wrapper.restore();
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js
index dfa2893e61..e1e8411e58 100644
--- a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js
+++ b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js
@@ -23,80 +23,15 @@
****************************************************************************/
// ----------------------------------- LabelTTF WebGL render cmd ----------------------------
-(function() {
+(function () {
cc.LabelTTF.WebGLRenderCmd = function (renderable) {
- cc.Sprite.WebGLRenderCmd.call(this, renderable);
- cc.LabelTTF.RenderCmd.call(this);
- this.setShaderProgram(cc.shaderCache.programForKey(cc.LabelTTF._SHADER_PROGRAM));
+ this._spriteCmdCtor(renderable);
+ this._cacheCmdCtor();
};
-
var proto = cc.LabelTTF.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype);
- cc.inject(cc.LabelTTF.RenderCmd.prototype, proto); //multi-inherit
- proto.constructor = cc.LabelTTF.WebGLRenderCmd;
-
- proto._setColorsString = function () {
- this.setDirtyFlag(cc.Node._dirtyFlags.textDirty);
- var node = this._node;
- var locStrokeColor = node._strokeColor, locFontFillColor = node._textFillColor,
- locShadowColor = node._shadowColor || this._displayedColor;
- this._shadowColorStr = "rgba(" + (0 | locShadowColor.r) + "," + (0 | locShadowColor.g) + "," + (0 | locShadowColor.b) + "," + node._shadowOpacity + ")";
- this._fillColorStr = "rgba(" + (0 | locFontFillColor.r) + "," + (0 | locFontFillColor.g) + "," + (0 | locFontFillColor.b) + ", 1)";
- this._strokeColorStr = "rgba(" + (0 | locStrokeColor.r) + "," + (0 | locStrokeColor.g) + "," + (0 | locStrokeColor.b) + ", 1)";
- };
-
- proto.updateStatus = function () {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
-
- if (colorDirty)
- this._updateDisplayColor();
- if (opacityDirty)
- this._updateDisplayOpacity();
-
- if(colorDirty || opacityDirty){
- this._setColorsString();
- this._updateColor();
- this._updateTexture();
- }else if(locFlag & flags.textDirty)
- this._updateTexture();
-
- if (this._dirtyFlag & flags.transformDirty){
- this.transform(this.getParentRenderCmd(), true);
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag;
- }
- };
- proto._syncStatus = function (parentCmd) {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var parentNode = parentCmd ? parentCmd._node : null;
-
- if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
- locFlag |= flags.colorDirty;
-
- if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
- locFlag |= flags.opacityDirty;
-
- if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
- locFlag |= flags.transformDirty;
-
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
-
- this._dirtyFlag = locFlag;
-
- if (colorDirty)
- this._syncDisplayColor();
- if (opacityDirty)
- this._syncDisplayOpacity();
-
- if(colorDirty || opacityDirty){
- this._setColorsString();
- this._updateColor();
- this._updateTexture();
- }else if(locFlag & flags.textDirty)
- this._updateTexture();
-
- this.transform(parentCmd);
+ cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto);
+ proto.constructor = cc.LabelTTF.WebGLRenderCmd;
+ proto._updateColor = function () {
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/layers/CCLayer.js b/cocos2d/core/layers/CCLayer.js
index f80af56a0c..c752ad814f 100644
--- a/cocos2d/core/layers/CCLayer.js
+++ b/cocos2d/core/layers/CCLayer.js
@@ -36,24 +36,12 @@ cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
*
Constructor of cc.Layer, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
*/
ctor: function () {
- var nodep = cc.Node.prototype;
- nodep.ctor.call(this);
+ cc.Node.prototype.ctor.call(this);
this._ignoreAnchorPointForPosition = true;
- nodep.setAnchorPoint.call(this, 0.5, 0.5);
- nodep.setContentSize.call(this, cc.winSize);
- },
-
- /**
- * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
- */
- init: function(){
- var _t = this;
- _t._ignoreAnchorPointForPosition = true;
- _t.setAnchorPoint(0.5, 0.5);
- _t.setContentSize(cc.winSize);
- _t._cascadeColorEnabled = false;
- _t._cascadeOpacityEnabled = false;
- return true;
+ this.setAnchorPoint(0.5, 0.5);
+ this.setContentSize(cc.winSize);
+ this._cascadeColorEnabled = false;
+ this._cascadeOpacityEnabled = false;
},
/**
@@ -62,7 +50,7 @@ cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
* @function
* @see cc.Layer#unbake
*/
- bake: function(){
+ bake: function () {
this._renderCmd.bake();
},
@@ -72,7 +60,7 @@ cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
* @function
* @see cc.Layer#bake
*/
- unbake: function(){
+ unbake: function () {
this._renderCmd.unbake();
},
@@ -82,17 +70,61 @@ cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
* @returns {boolean}
* @see cc.Layer#bake and cc.Layer#unbake
*/
- isBaked: function(){
- return this._isBaked;
+ isBaked: function () {
+ return this._renderCmd._isBaked;
},
- addChild: function(child, localZOrder, tag){
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ if (cmd._isBaked) {
+ renderer.pushRenderCommand(cmd);
+ cmd._bakeSprite.visit(this);
+ }
+ else {
+ var i, children = this._children, len = children.length, child;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(cmd);
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(cmd);
+ }
+ }
+ cmd._dirtyFlag = 0;
+ },
+
+ addChild: function (child, localZOrder, tag) {
cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
this._renderCmd._bakeForAddChild(child);
},
- _createRenderCmd: function(){
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.Layer.CanvasRenderCmd(this);
else
return new cc.Layer.WebGLRenderCmd(this);
@@ -189,9 +221,9 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
* @param {Number} [width=]
* @param {Number} [height=]
*/
- ctor: function(color, width, height){
+ ctor: function (color, width, height) {
cc.Layer.prototype.ctor.call(this);
- this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
+ this._blendFunc = cc.BlendFunc._alphaNonPremultiplied();
cc.LayerColor.prototype.init.call(this, color, width, height);
},
@@ -203,9 +235,6 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
* @return {Boolean}
*/
init: function (color, width, height) {
- if (cc._renderType !== cc._RENDER_TYPE_CANVAS)
- this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
-
var winSize = cc.director.getWinSize();
color = color || cc.color(0, 0, 0, 255);
width = width === undefined ? winSize.width : width;
@@ -216,12 +245,59 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
locRealColor.g = color.g;
locRealColor.b = color.b;
this._realOpacity = color.a;
- this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty|cc.Node._dirtyFlags.opacityDirty);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty);
cc.LayerColor.prototype.setContentSize.call(this, width, height);
return true;
},
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ if (cmd._isBaked) {
+ renderer.pushRenderCommand(cmd._bakeRenderCmd);
+ //the bakeSprite is drawing
+ cmd._bakeSprite._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ cmd._bakeSprite.visit(this);
+ }
+ else {
+ var i, children = this._children, len = children.length;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(cmd);
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(cmd);
+ }
+ }
+
+ cmd._dirtyFlag = 0;
+ },
+
/**
* Sets the blend func, you can pass either a cc.BlendFunc object or source and destination value separately
* @param {Number|cc.BlendFunc} src
@@ -239,23 +315,8 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
this._renderCmd.updateBlendFunc(locBlendFunc);
},
- _setWidth: function(width){
- cc.Node.prototype._setWidth.call(this, width);
- this._renderCmd._updateSquareVerticesWidth(width);
- },
-
- _setHeight: function(height){
- cc.Node.prototype._setHeight.call(this, height);
- this._renderCmd._updateSquareVerticesHeight(height);
- },
-
- setContentSize: function(size, height){
- cc.Layer.prototype.setContentSize.call(this, size, height);
- this._renderCmd._updateSquareVertices(size, height);
- },
-
- _createRenderCmd: function(){
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.LayerColor.CanvasRenderCmd(this);
else
return new cc.LayerColor.WebGLRenderCmd(this);
@@ -276,7 +337,7 @@ cc.LayerColor.create = function (color, width, height) {
};
//LayerColor - Getter Setter
-(function(){
+(function () {
var proto = cc.LayerColor.prototype;
cc.defineGetterSetter(proto, "width", proto._getWidth, proto._setWidth);
cc.defineGetterSetter(proto, "height", proto._getHeight, proto._setHeight);
@@ -347,12 +408,12 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
this._startOpacity = 255;
this._endOpacity = 255;
- if(stops && stops instanceof Array){
+ if (stops && stops instanceof Array) {
this._colorStops = stops;
- stops.splice(0, 0, {p:0, color: start || cc.color.BLACK});
- stops.push({p:1, color: end || cc.color.BLACK});
+ stops.splice(0, 0, {p: 0, color: start || cc.color.BLACK});
+ stops.push({p: 1, color: end || cc.color.BLACK});
} else
- this._colorStops = [{p:0, color: start || cc.color.BLACK}, {p:1, color: end || cc.color.BLACK}];
+ this._colorStops = [{p: 0, color: start || cc.color.BLACK}, {p: 1, color: end || cc.color.BLACK}];
cc.LayerGradient.prototype.init.call(this, start, end, v, stops);
},
@@ -384,7 +445,7 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
_t._compressedInterpolation = true;
cc.LayerColor.prototype.init.call(_t, cc.color(start.r, start.g, start.b, 255));
- this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty|cc.Node._dirtyFlags.opacityDirty|cc.Node._dirtyFlags.gradientDirty);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty | cc.Node._dirtyFlags.gradientDirty);
return true;
},
@@ -427,7 +488,7 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
this.color = color;
//update the color stops
var stops = this._colorStops;
- if(stops && stops.length > 0){
+ if (stops && stops.length > 0) {
var selColor = stops[0].color;
selColor.r = color.r;
selColor.g = color.g;
@@ -450,8 +511,8 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
locColor.b = color.b;
//update the color stops
var stops = this._colorStops;
- if(stops && stops.length > 0){
- var selColor = stops[stops.length -1].color;
+ if (stops && stops.length > 0) {
+ var selColor = stops[stops.length - 1].color;
selColor.r = color.r;
selColor.g = color.g;
selColor.b = color.b;
@@ -475,7 +536,7 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
this._startOpacity = o;
//update the color stops
var stops = this._colorStops;
- if(stops && stops.length > 0)
+ if (stops && stops.length > 0)
stops[0].color.a = o;
this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
},
@@ -495,8 +556,8 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
setEndOpacity: function (o) {
this._endOpacity = o;
var stops = this._colorStops;
- if(stops && stops.length > 0)
- stops[stops.length -1].color.a = o;
+ if (stops && stops.length > 0)
+ stops[stops.length - 1].color.a = o;
this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
},
@@ -550,7 +611,7 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
* [{p: 0, color: cc.color.RED},{p: 1, color: cc.color.RED},...]
* @returns {Array}
*/
- getColorStops: function(){
+ getColorStops: function () {
return this._colorStops;
},
/**
@@ -567,14 +628,14 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
* //where p = A value between 0.0 and 1.0 that represents the position between start and end in a gradient
*
*/
- setColorStops: function(colorStops){
+ setColorStops: function (colorStops) {
this._colorStops = colorStops;
//todo need update the start color and end color
- this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty|cc.Node._dirtyFlags.opacityDirty|cc.Node._dirtyFlags.gradientDirty);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty | cc.Node._dirtyFlags.gradientDirty);
},
- _createRenderCmd: function(){
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.LayerGradient.CanvasRenderCmd(this);
else
return new cc.LayerGradient.WebGLRenderCmd(this);
@@ -595,7 +656,7 @@ cc.LayerGradient.create = function (start, end, v, stops) {
return new cc.LayerGradient(start, end, v, stops);
};
//LayerGradient - Getter Setter
-(function(){
+(function () {
var proto = cc.LayerGradient.prototype;
// Extended properties
/** @expose */
@@ -718,4 +779,4 @@ cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{
*/
cc.LayerMultiplex.create = function (/*Multiple Arguments*/) {
return new cc.LayerMultiplex(Array.prototype.slice.call(arguments));
-};
\ No newline at end of file
+};
diff --git a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
index 2fb954e115..3149895ee3 100644
--- a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
+++ b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
@@ -31,54 +31,106 @@
/**
* cc.Layer's rendering objects of Canvas
*/
-(function(){
+(function () {
//Layer's canvas render command
- cc.Layer.CanvasRenderCmd = function(renderable){
- cc.Node.CanvasRenderCmd.call(this, renderable);
+ cc.Layer.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
this._isBaked = false;
this._bakeSprite = null;
+ this._canUseDirtyRegion = true;
+ this._updateCache = 2; // 2: Updated child visit 1: Rendering 0: Nothing to do
};
var proto = cc.Layer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
proto.constructor = cc.Layer.CanvasRenderCmd;
+ proto._layerCmdCtor = cc.Layer.CanvasRenderCmd;
+
+ proto._setCacheDirty = function (child) {
+ if (child && this._updateCache === 0)
+ this._updateCache = 2;
+ if (this._cacheDirty === false) {
+ this._cacheDirty = true;
+ var cachedP = this._cachedParent;
+ cachedP && cachedP !== this && cachedP._setNodeDirtyForCache && cachedP._setNodeDirtyForCache();
+ }
+ };
+
+ proto.updateStatus = function () {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.orderDirty) {
+ this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
+ this._dirtyFlag &= ~flags.orderDirty;
+ }
- proto.bake = function(){
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ // if (locFlag & flags.orderDirty) {
+ if (this._isBaked || locFlag & flags.orderDirty) {
+ this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
+ this._dirtyFlag &= ~flags.orderDirty;
+ }
+ this._originSyncStatus(parentCmd);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ if (!this._worldTransform) {
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+ var wt = this._worldTransform;
+ var a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty;
+ this.originTransform(parentCmd, recursive);
+ if (( wt.a !== a || wt.b !== b || wt.c !== c || wt.d !== d ) && this._updateCache === 0)
+ this._updateCache = 2;
+ };
+
+ proto.bake = function () {
if (!this._isBaked) {
this._needDraw = true;
cc.renderer.childrenOrderDirty = true;
//limit: 1. its children's blendfunc are invalid.
this._isBaked = this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
var children = this._node._children;
- for(var i = 0, len = children.length; i < len; i++)
+ for (var i = 0, len = children.length; i < len; i++)
children[i]._renderCmd._setCachedParent(this);
- if (!this._bakeSprite){
+ if (!this._bakeSprite) {
this._bakeSprite = new cc.BakeSprite();
- this._bakeSprite.setAnchorPoint(0,0);
+ this._bakeSprite.setAnchorPoint(0, 0);
}
}
};
- proto.unbake = function(){
+ proto.unbake = function () {
if (this._isBaked) {
cc.renderer.childrenOrderDirty = true;
this._needDraw = false;
this._isBaked = false;
this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
var children = this._node._children;
- for(var i = 0, len = children.length; i < len; i++)
+ for (var i = 0, len = children.length; i < len; i++)
children[i]._renderCmd._setCachedParent(null);
}
};
- proto.isBaked = function(){
+ proto.isBaked = function () {
return this._isBaked;
};
- proto.rendering = function(){
- if(this._cacheDirty){
+ proto.rendering = function () {
+ if (this._cacheDirty) {
var node = this._node;
var children = node._children, locBakeSprite = this._bakeSprite;
@@ -86,54 +138,38 @@
this.transform(this.getParentRenderCmd(), true);
var boundingBox = this._getBoundingBoxForBake();
- boundingBox.width = 0|(boundingBox.width+0.5);
- boundingBox.height = 0|(boundingBox.height+0.5);
+ boundingBox.width = 0 | (boundingBox.width + 0.5);
+ boundingBox.height = 0 | (boundingBox.height + 0.5);
var bakeContext = locBakeSprite.getCacheContext();
var ctx = bakeContext.getContext();
- locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
- bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y );
locBakeSprite.setPosition(boundingBox.x, boundingBox.y);
- //visit for canvas
- node.sortAllChildren();
- cc.renderer._turnToCacheMode(this.__instanceId);
- for (var i = 0, len = children.length; i < len; i++) {
- children[i].visit(this);
+ if (this._updateCache > 0) {
+ locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
+ bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y);
+ //visit for canvas
+ node.sortAllChildren();
+ cc.renderer._turnToCacheMode(this.__instanceId);
+ for (var i = 0, len = children.length; i < len; i++) {
+ children[i].visit(this);
+ }
+ cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId);
+ locBakeSprite.transform(); //because bake sprite's position was changed at rendering.
+ this._updateCache--;
}
- cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId);
- locBakeSprite.transform(); //because bake sprite's position was changed at rendering.
+
this._cacheDirty = false;
}
};
- proto.visit = function(parentCmd){
- if(!this._isBaked){
- cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd);
- return;
- }
-
- var node = this._node, children = node._children;
- var len = children.length;
- // quick return if not visible
- if (!node._visible || len === 0)
- return;
-
- this._syncStatus(parentCmd);
- cc.renderer.pushRenderCommand(this);
-
- //the bakeSprite is drawing
- this._bakeSprite.visit(this);
- this._dirtyFlag = 0;
- };
-
- proto._bakeForAddChild = function(child){
- if(child._parent === this._node && this._isBaked)
+ proto._bakeForAddChild = function (child) {
+ if (child._parent === this._node && this._isBaked)
child._renderCmd._setCachedParent(this);
};
- proto._getBoundingBoxForBake = function(){
+ proto._getBoundingBoxForBake = function () {
var rect = null, node = this._node;
//query child's BoundingBox
@@ -145,11 +181,11 @@
for (var i = 0, len = locChildren.length; i < len; i++) {
var child = locChildren[i];
if (child && child._visible) {
- if(rect){
+ if (rect) {
var childRect = child._getBoundingBoxToCurrentNode(trans);
if (childRect)
rect = cc.rectUnion(rect, childRect);
- }else{
+ } else {
rect = child._getBoundingBoxToCurrentNode(trans);
}
}
@@ -161,10 +197,10 @@
/**
* cc.LayerColor's rendering objects of Canvas
*/
-(function(){
+(function () {
//LayerColor's canvas render command
- cc.LayerColor.CanvasRenderCmd = function(renderable){
- cc.Layer.CanvasRenderCmd.call(this, renderable);
+ cc.LayerColor.CanvasRenderCmd = function (renderable) {
+ this._layerCmdCtor(renderable);
this._needDraw = true;
this._blendFuncStr = "source-over";
this._bakeRenderCmd = new cc.CustomRenderCmd(this, this._bakeRendering);
@@ -172,7 +208,7 @@
var proto = cc.LayerColor.CanvasRenderCmd.prototype = Object.create(cc.Layer.CanvasRenderCmd.prototype);
proto.constructor = cc.LayerColor.CanvasRenderCmd;
- proto.unbake = function(){
+ proto.unbake = function () {
cc.Layer.CanvasRenderCmd.prototype.unbake.call(this);
this._needDraw = true;
};
@@ -194,86 +230,70 @@
+ (0 | curColor.b) + ", 1)"); //TODO: need cache the color string
wrapper.setTransform(this._worldTransform, scaleX, scaleY);
- context.fillRect(0, 0, locWidth * scaleX, -locHeight * scaleY);
+ context.fillRect(0, 0, locWidth, -locHeight);
cc.g_NumberOfDraws++;
};
- proto.updateBlendFunc = function(blendFunc){
+ proto.updateBlendFunc = function (blendFunc) {
this._blendFuncStr = cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc(blendFunc);
};
proto._updateSquareVertices =
proto._updateSquareVerticesWidth =
- proto._updateSquareVerticesHeight = function(){};
+ proto._updateSquareVerticesHeight = function () {};
- proto._bakeRendering = function(){
- if(this._cacheDirty){
+ proto._bakeRendering = function () {
+ if (this._cacheDirty) {
var node = this._node;
var locBakeSprite = this._bakeSprite, children = node._children;
- var len = children.length, i;
+ var i, len = children.length;
//compute the bounding box of the bake layer.
this.transform(this.getParentRenderCmd(), true);
//compute the bounding box of the bake layer.
var boundingBox = this._getBoundingBoxForBake();
- boundingBox.width = 0|(boundingBox.width+0.5);
- boundingBox.height = 0|(boundingBox.height+0.5);
+ boundingBox.width = 0 | (boundingBox.width + 0.5);
+ boundingBox.height = 0 | (boundingBox.height + 0.5);
var bakeContext = locBakeSprite.getCacheContext();
var ctx = bakeContext.getContext();
- locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
- bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y );
locBakeSprite.setPosition(boundingBox.x, boundingBox.y);
- var child;
- cc.renderer._turnToCacheMode(this.__instanceId);
- //visit for canvas
- if (len > 0) {
- node.sortAllChildren();
- // draw children zOrder < 0
- for (i = 0; i < len; i++) {
- child = children[i];
- if (child._localZOrder < 0)
- child._renderCmd.visit(this);
- else
- break;
- }
- cc.renderer.pushRenderCommand(this);
- for (; i < len; i++) {
- children[i]._renderCmd.visit(this);
- }
- } else
- cc.renderer.pushRenderCommand(this);
- cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId);
- locBakeSprite.transform();
+ if (this._updateCache > 0) {
+ ctx.fillStyle = bakeContext._currentFillStyle;
+ locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
+ bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y);
+
+ var child;
+ cc.renderer._turnToCacheMode(this.__instanceId);
+ //visit for canvas
+ if (len > 0) {
+ node.sortAllChildren();
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0)
+ child.visit(node);
+ else
+ break;
+ }
+ cc.renderer.pushRenderCommand(this);
+ for (; i < len; i++) {
+ children[i].visit(node);
+ }
+ } else
+ cc.renderer.pushRenderCommand(this);
+ cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId);
+ locBakeSprite.transform();
+ this._updateCache--;
+ }
this._cacheDirty = false;
}
};
- proto.visit = function(parentCmd){
- if(!this._isBaked){
- cc.Node.CanvasRenderCmd.prototype.visit.call(this);
- return;
- }
-
- var node = this._node;
- // quick return if not visible
- if (!node._visible)
- return;
-
- this._syncStatus(parentCmd);
-
- cc.renderer.pushRenderCommand(this._bakeRenderCmd);
-
- //the bakeSprite is drawing
- this._bakeSprite._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
- this._bakeSprite.visit(this);
- this._dirtyFlag = 0;
- };
-
- proto._getBoundingBoxForBake = function(){
+ proto._getBoundingBoxForBake = function () {
var node = this._node;
//default size
var rect = cc.rect(0, 0, node._contentSize.width, node._contentSize.height);
@@ -296,36 +316,11 @@
};
})();
-(function () {
- cc.LayerGradient.RenderCmd = {
- updateStatus: function () {
- var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
- if (colorDirty)
- this._updateDisplayColor();
-
- if (opacityDirty)
- this._updateDisplayOpacity();
-
- if (locFlag & flags.transformDirty) {
- //update the transform
- this.transform(null, true);
- }
-
- if (colorDirty || opacityDirty || (locFlag & flags.gradientDirty)){
- this._updateColor();
- }
- this._dirtyFlag = 0;
- }
- };
-})();
-
/**
* cc.LayerGradient's rendering objects of Canvas
*/
-(function(){
- cc.LayerGradient.CanvasRenderCmd = function(renderable){
+(function () {
+ cc.LayerGradient.CanvasRenderCmd = function (renderable) {
cc.LayerColor.CanvasRenderCmd.call(this, renderable);
this._needDraw = true;
this._startPoint = cc.p(0, 0);
@@ -334,7 +329,6 @@
this._endStopStr = null;
};
var proto = cc.LayerGradient.CanvasRenderCmd.prototype = Object.create(cc.LayerColor.CanvasRenderCmd.prototype);
- cc.inject(cc.LayerGradient.RenderCmd, proto);
proto.constructor = cc.LayerGradient.CanvasRenderCmd;
proto.rendering = function (ctx, scaleX, scaleY) {
@@ -348,14 +342,14 @@
var locWidth = node._contentSize.width, locHeight = node._contentSize.height;
wrapper.setCompositeOperation(this._blendFuncStr);
wrapper.setGlobalAlpha(opacity);
- var gradient = context.createLinearGradient(this._startPoint.x*scaleX, this._startPoint.y*scaleY, this._endPoint.x*scaleX, this._endPoint.y*scaleY);
-
- if(node._colorStops){ //Should always fall here now
- for(var i=0; i < node._colorStops.length; i++) {
- var stop = node._colorStops[i];
- gradient.addColorStop(stop.p, this._colorStopsStr[i]);
- }
- }else{
+ var gradient = context.createLinearGradient(this._startPoint.x, this._startPoint.y, this._endPoint.x, this._endPoint.y);
+
+ if (node._colorStops) { //Should always fall here now
+ for (var i = 0; i < node._colorStops.length; i++) {
+ var stop = node._colorStops[i];
+ gradient.addColorStop(stop.p, this._colorStopsStr[i]);
+ }
+ } else {
gradient.addColorStop(0, this._startStopStr);
gradient.addColorStop(1, this._endStopStr);
}
@@ -363,54 +357,39 @@
wrapper.setFillStyle(gradient);
wrapper.setTransform(this._worldTransform, scaleX, scaleY);
- context.fillRect(0, 0, locWidth * scaleX, -locHeight * scaleY);
+ context.fillRect(0, 0, locWidth, -locHeight);
cc.g_NumberOfDraws++;
};
- proto._syncStatus = function (parentCmd) {
+ proto.updateStatus = function () {
var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var parentNode = parentCmd ? parentCmd._node : null;
-
- if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
- locFlag |= flags.colorDirty;
-
- if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
- locFlag |= flags.opacityDirty;
-
- if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
- locFlag |= flags.transformDirty;
-
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
-
- this._dirtyFlag = locFlag;
-
- if (colorDirty)
- this._syncDisplayColor();
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
- if (opacityDirty)
- this._syncDisplayOpacity();
+ this.originUpdateStatus();
+ };
- if (locFlag & flags.transformDirty) {
- //update the transform
- this.transform(parentCmd);
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._dirtyFlag &= ~flags.gradientDirty;
}
- if (colorDirty || opacityDirty || (locFlag & flags.gradientDirty)){
- this._updateColor();
- }
+ this._originSyncStatus(parentCmd);
};
- proto._updateColor = function(){
+ proto._updateColor = function () {
var node = this._node;
var contentSize = node._contentSize;
var tWidth = contentSize.width * 0.5, tHeight = contentSize.height * 0.5;
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.gradientDirty ^ this._dirtyFlag;
//fix the bug of gradient layer
var angle = cc.pAngleSigned(cc.p(0, -1), node._alongVector);
- var p1 = cc.pRotateByAngle(cc.p(0, -1), cc.p(0,0), angle);
- var factor = Math.min(Math.abs(1 / p1.x), Math.abs(1/ p1.y));
+ var p1 = cc.pRotateByAngle(cc.p(0, -1), cc.p(0, 0), angle);
+ var factor = Math.min(Math.abs(1 / p1.x), Math.abs(1 / p1.y));
this._startPoint.x = tWidth * (-p1.x * factor) + tWidth;
this._startPoint.y = tHeight * (p1.y * factor) - tHeight;
@@ -418,18 +397,18 @@
this._endPoint.y = tHeight * (-p1.y * factor) - tHeight;
var locStartColor = this._displayedColor, locEndColor = node._endColor;
- var startOpacity = node._startOpacity/255, endOpacity = node._endOpacity/255;
+ var startOpacity = node._startOpacity / 255, endOpacity = node._endOpacity / 255;
this._startStopStr = "rgba(" + Math.round(locStartColor.r) + "," + Math.round(locStartColor.g) + ","
+ Math.round(locStartColor.b) + "," + startOpacity.toFixed(4) + ")";
this._endStopStr = "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + ","
+ Math.round(locEndColor.b) + "," + endOpacity.toFixed(4) + ")";
- if( node._colorStops){
+ if (node._colorStops) {
this._startOpacity = 0;
this._endOpacity = 0;
this._colorStopsStr = [];
- for(var i =0; i < node._colorStops.length; i++){
+ for (var i = 0; i < node._colorStops.length; i++) {
var stopColor = node._colorStops[i].color;
var stopOpacity = stopColor.a == null ? 1 : stopColor.a / 255;
this._colorStopsStr.push("rgba(" + Math.round(stopColor.r) + "," + Math.round(stopColor.g) + ","
@@ -437,4 +416,4 @@
}
}
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
index c9314203ac..4acf7f22d6 100644
--- a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
+++ b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
@@ -31,210 +31,194 @@
/**
* cc.Layer's rendering objects of WebGL
*/
-(function(){
- cc.Layer.WebGLRenderCmd = function(renderable){
- cc.Node.WebGLRenderCmd.call(this, renderable);
+(function () {
+ cc.Layer.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._isBaked = false;
};
var proto = cc.Layer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
proto.constructor = cc.Layer.WebGLRenderCmd;
+ proto._layerCmdCtor = cc.Layer.WebGLRenderCmd;
- proto.bake = function(){};
+ proto.bake = function () {
+ };
- proto.unbake = function(){};
+ proto.unbake = function () {
+ };
- proto._bakeForAddChild = function(){};
+ proto._bakeForAddChild = function () {
+ };
})();
/**
* cc.LayerColor's rendering objects of WebGL
*/
-(function(){
- cc.LayerColor.WebGLRenderCmd = function(renderable){
- cc.Layer.WebGLRenderCmd.call(this, renderable);
+(function () {
+ var FLOAT_PER_VERTEX = 4;
+
+ cc.LayerColor.WebGLRenderCmd = function (renderable) {
+ this._layerCmdCtor(renderable);
this._needDraw = true;
- //
- var _t = this;
- _t._squareVerticesAB = new ArrayBuffer(32);
- _t._squareColorsAB = new ArrayBuffer(16);
-
- var locSquareVerticesAB = _t._squareVerticesAB, locSquareColorsAB = _t._squareColorsAB;
- var locVertex2FLen = cc.Vertex2F.BYTES_PER_ELEMENT, locColorLen = cc.Color.BYTES_PER_ELEMENT;
- _t._squareVertices = [new cc.Vertex2F(0, 0, locSquareVerticesAB, 0),
- new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen),
- new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 2),
- new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 3)];
- _t._squareColors = [cc.color(0, 0, 0, 255, locSquareColorsAB, 0),
- cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen),
- cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * 2),
- cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * 3)];
- _t._verticesFloat32Buffer = cc._renderContext.createBuffer();
- _t._colorsUint8Buffer = cc._renderContext.createBuffer();
+ this._matrix = null;
+
+ this.initData(4);
+ this._color = new Uint32Array(1);
+ this._vertexBuffer = null;
+
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
};
var proto = cc.LayerColor.WebGLRenderCmd.prototype = Object.create(cc.Layer.WebGLRenderCmd.prototype);
proto.constructor = cc.LayerColor.WebGLRenderCmd;
- proto.rendering = function (ctx) {
- var context = ctx || cc._renderContext;
- var node = this._node;
+ proto.initData = function (vertexCount) {
+ this._data = new ArrayBuffer(16 * vertexCount);
+ this._positionView = new Float32Array(this._data);
+ this._colorView = new Uint32Array(this._data);
+ this._dataDirty = true;
+ };
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR);
- cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
- //
- // Attributes
- //
- context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer);
- context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, context.FLOAT, false, 0, 0);
+ var node = this._node,
+ width = node._contentSize.width,
+ height = node._contentSize.height;
- context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer);
- context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0);
+ var pos = this._positionView;
+ pos[FLOAT_PER_VERTEX] = width; // br.x
+ pos[FLOAT_PER_VERTEX * 2 + 1] = height; // tl.y
+ pos[FLOAT_PER_VERTEX * 3] = width; // tr.x
+ pos[FLOAT_PER_VERTEX * 3 + 1] = height; // tr.y
+ pos[2].z =
+ pos[FLOAT_PER_VERTEX + 2] =
+ pos[FLOAT_PER_VERTEX * 2 + 2] =
+ pos[FLOAT_PER_VERTEX * 3 + 2] = node._vertexZ;
- context.drawArrays(context.TRIANGLE_STRIP, 0, this._squareVertices.length);
+ this._dataDirty = true;
};
- proto._updateSquareVertices = function(size, height){
- var locSquareVertices = this._squareVertices;
- if (height === undefined) {
- locSquareVertices[1].x = size.width;
- locSquareVertices[2].y = size.height;
- locSquareVertices[3].x = size.width;
- locSquareVertices[3].y = size.height;
- } else {
- locSquareVertices[1].x = size;
- locSquareVertices[2].y = height;
- locSquareVertices[3].x = size;
- locSquareVertices[3].y = height;
+ proto._updateColor = function () {
+ var color = this._displayedColor;
+ this._color[0] = ((this._displayedOpacity << 24) | (color.b << 16) | (color.g << 8) | color.r);
+
+ var colors = this._colorView;
+ for (var i = 0; i < 4; i++) {
+ colors[i * FLOAT_PER_VERTEX + 3] = this._color[0];
}
- this._bindLayerVerticesBufferData();
+ this._dataDirty = true;
};
- proto._updateSquareVerticesWidth = function(width){
- var locSquareVertices = this._squareVertices;
- locSquareVertices[1].x = width;
- locSquareVertices[3].x = width;
- this._bindLayerVerticesBufferData();
- };
+ proto.rendering = function (ctx) {
+ var gl = ctx || cc._renderContext;
+ var node = this._node;
- proto._updateSquareVerticesHeight = function(height){
- var locSquareVertices = this._squareVertices;
- locSquareVertices[2].y = height;
- locSquareVertices[3].y = height;
- this._bindLayerVerticesBufferData();
- };
+ if (!this._matrix) {
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ }
- proto._updateColor = function(){
- var locDisplayedColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity,
- locSquareColors = this._squareColors;
- for (var i = 0; i < 4; i++) {
- locSquareColors[i].r = locDisplayedColor.r;
- locSquareColors[i].g = locDisplayedColor.g;
- locSquareColors[i].b = locDisplayedColor.b;
- locSquareColors[i].a = locDisplayedOpacity;
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ if (this._dataDirty) {
+ if (!this._vertexBuffer) {
+ this._vertexBuffer = gl.createBuffer();
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._data, gl.DYNAMIC_DRAW);
+ this._dataDirty = false;
}
- this._bindLayerColorsBufferData();
- };
- proto._bindLayerVerticesBufferData = function(){
- var glContext = cc._renderContext;
- glContext.bindBuffer(glContext.ARRAY_BUFFER, this._verticesFloat32Buffer);
- glContext.bufferData(glContext.ARRAY_BUFFER, this._squareVerticesAB, glContext.STATIC_DRAW);
- };
+ this._glProgramState.apply(this._matrix);
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 16, 0);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 16, 12);
- proto._bindLayerColorsBufferData = function(){
- var glContext = cc._renderContext;
- glContext.bindBuffer(glContext.ARRAY_BUFFER, this._colorsUint8Buffer);
- glContext.bufferData(glContext.ARRAY_BUFFER, this._squareColorsAB, glContext.STATIC_DRAW);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
};
- proto.updateBlendFunc = function(blendFunc){};
+ proto.updateBlendFunc = function (blendFunc) {
+ };
})();
/**
* cc.LayerGradient's rendering objects of WebGL
*/
-(function(){
- cc.LayerGradient.WebGLRenderCmd = function(renderable){
+(function () {
+ var FLOAT_PER_VERTEX = 4;
+
+ cc.LayerGradient.WebGLRenderCmd = function (renderable) {
cc.LayerColor.WebGLRenderCmd.call(this, renderable);
this._needDraw = true;
this._clipRect = new cc.Rect();
this._clippingRectDirty = false;
};
var proto = cc.LayerGradient.WebGLRenderCmd.prototype = Object.create(cc.LayerColor.WebGLRenderCmd.prototype);
- cc.inject(cc.LayerGradient.RenderCmd, proto);
proto.constructor = cc.LayerGradient.WebGLRenderCmd;
- proto._syncStatus = function (parentCmd) {
+ proto.updateStatus = function () {
var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
- var parentNode = parentCmd ? parentCmd._node : null;
-
- if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
- locFlag |= flags.colorDirty;
-
- if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
- locFlag |= flags.opacityDirty;
-
- if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
- locFlag |= flags.transformDirty;
-
- var colorDirty = locFlag & flags.colorDirty,
- opacityDirty = locFlag & flags.opacityDirty;
-
- this._dirtyFlag = locFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._updateVertex();
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
- if (colorDirty)
- this._syncDisplayColor();
+ this.originUpdateStatus();
+ };
- if (opacityDirty)
- this._syncDisplayOpacity();
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._updateVertex();
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
- //if (locFlag & flags.transformDirty) {
- //update the transform
- this.transform(parentCmd);
- //}
+ this._originSyncStatus(parentCmd);
+ };
- if (colorDirty || opacityDirty || (locFlag & flags.gradientDirty)){
- this._updateColor();
- }
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this._updateVertex();
};
- proto._updateColor = function(){
- this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.gradientDirty ^ this._dirtyFlag;
+ proto._updateVertex = function () {
var node = this._node, stops = node._colorStops;
- if(!stops || stops.length < 2)
+ if (!stops || stops.length < 2)
return;
this._clippingRectDirty = true;
- var stopsLen = stops.length, verticesLen = stopsLen * 2, i, contentSize = node._contentSize;
- this._squareVerticesAB = new ArrayBuffer(verticesLen * 8);
- this._squareColorsAB = new ArrayBuffer(verticesLen * 4);
- var locVertices = this._squareVertices, locColors = this._squareColors;
- locVertices.length = 0;
- locColors.length = 0;
-
- var locSquareVerticesAB = this._squareVerticesAB, locSquareColorsAB = this._squareColorsAB;
- var locVertex2FLen = cc.Vertex2F.BYTES_PER_ELEMENT, locColorLen = cc.Color.BYTES_PER_ELEMENT;
- for(i = 0; i < verticesLen; i++){
- locVertices.push(new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * i));
- locColors.push(cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * i))
+ var i, stopsLen = stops.length, verticesLen = stopsLen * 2, contentSize = node._contentSize;
+ if (this._positionView.length / FLOAT_PER_VERTEX < verticesLen) {
+ this.initData(verticesLen);
}
//init vertex
- var angle = Math.PI + cc.pAngleSigned(cc.p(0, -1), node._alongVector), locAnchor = cc.p(contentSize.width/2, contentSize.height /2);
+ var angle = Math.PI + cc.pAngleSigned(cc.p(0, -1), node._alongVector), locAnchor = cc.p(contentSize.width / 2, contentSize.height / 2);
var degrees = Math.round(cc.radiansToDegrees(angle));
var transMat = cc.affineTransformMake(1, 0, 0, 1, locAnchor.x, locAnchor.y);
transMat = cc.affineTransformRotate(transMat, angle);
var a, b;
- if(degrees < 90) {
+ if (degrees < 90) {
a = cc.p(-locAnchor.x, locAnchor.y);
b = cc.p(locAnchor.x, locAnchor.y);
- } else if(degrees < 180) {
+ } else if (degrees < 180) {
a = cc.p(locAnchor.x, locAnchor.y);
b = cc.p(locAnchor.x, -locAnchor.y);
- } else if(degrees < 270) {
+ } else if (degrees < 270) {
a = cc.p(locAnchor.x, -locAnchor.y);
b = cc.p(-locAnchor.x, -locAnchor.y);
} else {
@@ -243,64 +227,97 @@
}
var sin = Math.sin(angle), cos = Math.cos(angle);
- var tx = Math.abs((a.x * cos - a.y * sin)/locAnchor.x), ty = Math.abs((b.x * sin + b.y * cos)/locAnchor.y);
+ var tx = Math.abs((a.x * cos - a.y * sin) / locAnchor.x), ty = Math.abs((b.x * sin + b.y * cos) / locAnchor.y);
transMat = cc.affineTransformScale(transMat, tx, ty);
+ var pos = this._positionView;
for (i = 0; i < stopsLen; i++) {
- var stop = stops[i], y = stop.p * contentSize.height ;
- var p0 = cc.pointApplyAffineTransform(- locAnchor.x , y - locAnchor.y, transMat);
- locVertices[i * 2].x = p0.x;
- locVertices[i * 2].y = p0.y;
+ var stop = stops[i], y = stop.p * contentSize.height;
+ var p0 = cc.pointApplyAffineTransform(-locAnchor.x, y - locAnchor.y, transMat);
+ var offset = i * 2 * FLOAT_PER_VERTEX;
+ pos[offset] = p0.x;
+ pos[offset + 1] = p0.y;
+ pos[offset + 2] = node._vertexZ;
var p1 = cc.pointApplyAffineTransform(contentSize.width - locAnchor.x, y - locAnchor.y, transMat);
- locVertices[i * 2 + 1].x = p1.x;
- locVertices[i * 2 + 1].y = p1.y;
+ offset += FLOAT_PER_VERTEX;
+ pos[offset] = p1.x;
+ pos[offset + 1] = p1.y;
+ pos[offset + 2] = node._vertexZ;
}
- //init color
- var opacityf = this._displayedOpacity / 255.0; //, displayColor = this._displayedColor;
- for(i = 0; i < stopsLen; i++){
- var stopColor = stops[i].color, locSquareColor0 = locColors[i * 2], locSquareColor1 = locColors[i * 2 + 1];
- locSquareColor0.r = stopColor.r;
- locSquareColor0.g = stopColor.g;
- locSquareColor0.b = stopColor.b;
- locSquareColor0.a = stopColor.a * opacityf;
-
- locSquareColor1.r = stopColor.r;
- locSquareColor1.g = stopColor.g;
- locSquareColor1.b = stopColor.b;
- locSquareColor1.a = stopColor.a * opacityf;
+ this._dataDirty = true;
+ };
+
+ proto._updateColor = function () {
+ var node = this._node, stops = node._colorStops;
+ if (!stops || stops.length < 2)
+ return;
+
+ var stopsLen = stops.length,
+ stopColor,
+ offset,
+ colors = this._colorView,
+ opacityf = this._displayedOpacity / 255;
+ for (i = 0; i < stopsLen; i++) {
+ stopColor = stops[i].color;
+ this._color[0] = ((stopColor.a*opacityf) << 24) | (stopColor.b << 16) | (stopColor.g << 8) | stopColor.r;
+
+ offset = i * 2 * FLOAT_PER_VERTEX;
+ colors[offset + 3] = this._color[0];
+ offset += FLOAT_PER_VERTEX;
+ colors[offset + 3] = this._color[0];
}
- this._bindLayerVerticesBufferData();
- this._bindLayerColorsBufferData();
+ this._dataDirty = true;
};
proto.rendering = function (ctx) {
var context = ctx || cc._renderContext, node = this._node;
+ if (!this._matrix) {
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ }
+
//it is too expensive to use stencil to clip, so it use Scissor,
//but it has a bug when layer rotated and layer's content size less than canvas's size.
var clippingRect = this._getClippingRect();
context.enable(context.SCISSOR_TEST);
cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ if (this._dataDirty) {
+ if (!this._vertexBuffer) {
+ this._vertexBuffer = gl.createBuffer();
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._data, gl.DYNAMIC_DRAW);
+ this._dataDirty = false;
+ }
+
//draw gradient layer
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
- //
- // Attributes
- //
- context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer);
- context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, context.FLOAT, false, 0, 0);
- context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer);
- context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0);
- context.drawArrays(context.TRIANGLE_STRIP, 0, this._squareVertices.length);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 16, 0);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 16, 12);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
context.disable(context.SCISSOR_TEST);
};
- proto._getClippingRect = function(){
- if(this._clippingRectDirty){
+ proto._getClippingRect = function () {
+ if (this._clippingRectDirty) {
var node = this._node;
var rect = cc.rect(0, 0, node._contentSize.width, node._contentSize.height);
var trans = node.getNodeToWorldTransform();
@@ -308,4 +325,4 @@
}
return this._clipRect;
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/platform/CCClass.js b/cocos2d/core/platform/CCClass.js
index 2aaf3e6621..be34ad92eb 100644
--- a/cocos2d/core/platform/CCClass.js
+++ b/cocos2d/core/platform/CCClass.js
@@ -27,55 +27,132 @@
var cc = cc || {};
/**
- * @namespace
- * @name ClassManager
+ * Common getter setter configuration function
+ * @function
+ * @param {Object} proto A class prototype or an object to config
+ * @param {String} prop Property name
+ * @param {function} getter Getter function for the property
+ * @param {function} setter Setter function for the property
+ * @param {String} getterName Name of getter function for the property
+ * @param {String} setterName Name of setter function for the property
*/
-var ClassManager = {
- id : (0|(Math.random()*998)),
-
- instanceId : (0|(Math.random()*998)),
-
- compileSuper : function(func, name, id){
- //make the func to a string
- var str = func.toString();
- //find parameters
- var pstart = str.indexOf('('), pend = str.indexOf(')');
- var params = str.substring(pstart+1, pend);
- params = params.trim();
-
- //find function body
- var bstart = str.indexOf('{'), bend = str.lastIndexOf('}');
- var str = str.substring(bstart+1, bend);
-
- //now we have the content of the function, replace this._super
- //find this._super
- while(str.indexOf('this._super') !== -1)
- {
- var sp = str.indexOf('this._super');
- //find the first '(' from this._super)
- var bp = str.indexOf('(', sp);
-
- //find if we are passing params to super
- var bbp = str.indexOf(')', bp);
- var superParams = str.substring(bp+1, bbp);
- superParams = superParams.trim();
- var coma = superParams? ',':'';
-
- //replace this._super
- str = str.substring(0, sp)+ 'ClassManager['+id+'].'+name+'.call(this'+coma+str.substring(bp+1);
+cc.defineGetterSetter = function (proto, prop, getter, setter, getterName, setterName) {
+ if (proto.__defineGetter__) {
+ getter && proto.__defineGetter__(prop, getter);
+ setter && proto.__defineSetter__(prop, setter);
+ } else if (Object.defineProperty) {
+ var desc = {enumerable: false, configurable: true};
+ getter && (desc.get = getter);
+ setter && (desc.set = setter);
+ Object.defineProperty(proto, prop, desc);
+ } else {
+ throw new Error("browser does not support getters");
+ }
+
+ if (!getterName && !setterName) {
+ // Lookup getter/setter function
+ var hasGetter = (getter != null), hasSetter = (setter != undefined), props = Object.getOwnPropertyNames(proto);
+ for (var i = 0; i < props.length; i++) {
+ var name = props[i];
+
+ if ((proto.__lookupGetter__ ? proto.__lookupGetter__(name)
+ : Object.getOwnPropertyDescriptor(proto, name))
+ || typeof proto[name] !== "function")
+ continue;
+
+ var func = proto[name];
+ if (hasGetter && func === getter) {
+ getterName = name;
+ if (!hasSetter || setterName) break;
+ }
+ if (hasSetter && func === setter) {
+ setterName = name;
+ if (!hasGetter || getterName) break;
+ }
+ }
+ }
+
+ // Found getter/setter
+ var ctor = proto.constructor;
+ if (getterName) {
+ if (!ctor.__getters__) {
+ ctor.__getters__ = {};
}
- return Function(params, str);
- },
+ ctor.__getters__[getterName] = prop;
+ }
+ if (setterName) {
+ if (!ctor.__setters__) {
+ ctor.__setters__ = {};
+ }
+ ctor.__setters__[setterName] = prop;
+ }
+};
- getNewID : function(){
- return this.id++;
- },
+/**
+ * Create a new object and copy all properties in an exist object to the new object
+ * @function
+ * @param {object|Array} obj The source object
+ * @return {Array|object} The created object
+ */
+cc.clone = function (obj) {
+ // Cloning is better if the new object is having the same prototype chain
+ // as the copied obj (or otherwise, the cloned object is certainly going to
+ // have a different hidden class). Play with C1/C2 of the
+ // PerformanceVirtualMachineTests suite to see how this makes an impact
+ // under extreme conditions.
+ //
+ // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the
+ // prototype lacks a link to the constructor (Carakan, V8) so the new
+ // object wouldn't have the hidden class that's associated with the
+ // constructor (also, for whatever reasons, utilizing
+ // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even
+ // slower than the original in V8). Therefore, we call the constructor, but
+ // there is a big caveat - it is possible that the this.init() in the
+ // constructor would throw with no argument. It is also possible that a
+ // derived class forgets to set "constructor" on the prototype. We ignore
+ // these possibities for and the ultimate solution is a standardized
+ // Object.clone(
* @param {cc.Rect} rect
*/
- setVertexRect:function (rect) {
+ setVertexRect: function (rect) {
var locRect = this._rect;
locRect.x = rect.x;
locRect.y = rect.y;
locRect.width = rect.width;
locRect.height = rect.height;
- },
-
- /**
- * Sort all children of this sprite node.
- * @override
- */
- sortAllChildren:function () {
- if (this._reorderChildDirty) {
- var _children = this._children;
-
- // insertion sort
- var len = _children.length, i, j, tmp;
- for(i=1; i= 0){
- if(tmp._localZOrder < _children[j]._localZOrder){
- _children[j+1] = _children[j];
- }else if(tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder){
- _children[j+1] = _children[j];
- }else{
- break;
- }
- j--;
- }
- _children[j+1] = tmp;
- }
-
- if (this._batchNode) {
- this._arrayMakeObjectsPerformSelector(_children, cc.Node._stateCallbackType.sortAllChildren);
- }
-
- //don't need to check children recursively, that's done in visit of each child
- this._reorderChildDirty = false;
- }
-
- },
-
- /**
- * Reorders a child according to a new z value. (override cc.Node )
- * @param {cc.Node} child
- * @param {Number} zOrder
- * @override
- */
- reorderChild:function (child, zOrder) {
- cc.assert(child, cc._LogInfos.Sprite_reorderChild_2);
- if(this._children.indexOf(child) === -1){
- cc.log(cc._LogInfos.Sprite_reorderChild);
- return;
- }
-
- if (zOrder === child.zIndex)
- return;
-
- if (this._batchNode && !this._reorderChildDirty) {
- this._setReorderChildDirtyRecursively();
- this._batchNode.reorderBatch(true);
- }
- cc.Node.prototype.reorderChild.call(this, child, zOrder);
- },
-
- /**
- * Removes a child from the sprite.
- * @param child
- * @param cleanup whether or not cleanup all running actions
- * @override
- */
- removeChild:function (child, cleanup) {
- if (this._batchNode)
- this._batchNode.removeSpriteFromAtlas(child);
- cc.Node.prototype.removeChild.call(this, child, cleanup);
- },
-
- /**
- * Sets whether the sprite is visible or not.
- * @param {Boolean} visible
- * @override
- */
- setVisible:function (visible) {
- cc.Node.prototype.setVisible.call(this, visible);
- this._renderCmd.setDirtyRecursively(true);
- },
-
- /**
- * Removes all children from the container.
- * @param cleanup whether or not cleanup all running actions
- * @override
- */
- removeAllChildren:function (cleanup) {
- var locChildren = this._children, locBatchNode = this._batchNode;
- if (locBatchNode && locChildren != null) {
- for (var i = 0, len = locChildren.length; i < len; i++)
- locBatchNode.removeSpriteFromAtlas(locChildren[i]);
- }
-
- cc.Node.prototype.removeAllChildren.call(this, cleanup);
- this._hasChildren = false;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
},
//
// cc.Node property overloads
//
- /**
- * Sets whether ignore anchor point for positioning
- * @param {Boolean} relative
- * @override
- */
- ignoreAnchorPointForPosition:function (relative) {
- if(this._batchNode){
- cc.log(cc._LogInfos.Sprite_ignoreAnchorPointForPosition);
- return;
- }
- cc.Node.prototype.ignoreAnchorPointForPosition.call(this, relative);
- },
-
/**
* Sets whether the sprite should be flipped horizontally or not.
* @param {Boolean} flippedX true if the sprite should be flipped horizontally, false otherwise.
*/
- setFlippedX:function (flippedX) {
+ setFlippedX: function (flippedX) {
if (this._flippedX !== flippedX) {
this._flippedX = flippedX;
this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
@@ -438,7 +317,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* Sets whether the sprite should be flipped vertically or not.
* @param {Boolean} flippedY true if the sprite should be flipped vertically, false otherwise.
*/
- setFlippedY:function (flippedY) {
+ setFlippedY: function (flippedY) {
if (this._flippedY !== flippedY) {
this._flippedY = flippedY;
this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
@@ -456,7 +335,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* sprite.setScaleX(sprite.getScaleX() * -1);
* @return {Boolean} true if the sprite is flipped horizontally, false otherwise.
*/
- isFlippedX:function () {
+ isFlippedX: function () {
return this._flippedX;
},
@@ -470,7 +349,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* sprite.setScaleY(sprite.getScaleY() * -1);
* @return {Boolean} true if the sprite is flipped vertically, false otherwise.
*/
- isFlippedY:function () {
+ isFlippedY: function () {
return this._flippedY;
},
@@ -493,7 +372,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* Returns whether opacity modify color or not.
* @return {Boolean}
*/
- isOpacityModifyRGB:function () {
+ isOpacityModifyRGB: function () {
return this._opacityModifyRGB;
},
@@ -505,16 +384,16 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* @param {String} animationName
* @param {Number} frameIndex
*/
- setDisplayFrameWithAnimationName:function (animationName, frameIndex) {
+ setDisplayFrameWithAnimationName: function (animationName, frameIndex) {
cc.assert(animationName, cc._LogInfos.Sprite_setDisplayFrameWithAnimationName_3);
var cache = cc.animationCache.getAnimation(animationName);
- if(!cache){
+ if (!cache) {
cc.log(cc._LogInfos.Sprite_setDisplayFrameWithAnimationName);
return;
}
var animFrame = cache.getFrames()[frameIndex];
- if(!animFrame){
+ if (!animFrame) {
cc.log(cc._LogInfos.Sprite_setDisplayFrameWithAnimationName_2);
return;
}
@@ -525,70 +404,58 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* Returns the batch node object if this sprite is rendered by cc.SpriteBatchNode
* @returns {cc.SpriteBatchNode|null} The cc.SpriteBatchNode object if this sprite is rendered by cc.SpriteBatchNode, null if the sprite isn't used batch node.
*/
- getBatchNode:function () {
+ getBatchNode: function () {
return this._batchNode;
},
- _setReorderChildDirtyRecursively:function () {
- //only set parents flag the first time
- if (!this._reorderChildDirty) {
- this._reorderChildDirty = true;
- var pNode = this._parent;
- while (pNode && pNode !== this._batchNode) {
- pNode._setReorderChildDirtyRecursively();
- pNode = pNode.parent;
- }
- }
- },
-
// CCTextureProtocol
/**
* Returns the texture of the sprite node
* @returns {cc.Texture2D}
*/
- getTexture:function () {
+ getTexture: function () {
return this._texture;
},
- _softInit: function (fileName, rect, rotated) {
- if (fileName === undefined)
- cc.Sprite.prototype.init.call(this);
- else if (cc.isString(fileName)) {
- if (fileName[0] === "#") {
- // Init with a sprite frame name
- var frameName = fileName.substr(1, fileName.length - 1);
- var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName);
- if (spriteFrame)
- this.initWithSpriteFrame(spriteFrame);
- else
- cc.log("%s does not exist", fileName);
- } else {
- // Init with filename and rect
- cc.Sprite.prototype.init.call(this, fileName, rect);
- }
- } else if (typeof fileName === "object") {
- if (fileName instanceof cc.Texture2D) {
- // Init with texture and rect
- this.initWithTexture(fileName, rect, rotated);
- } else if (fileName instanceof cc.SpriteFrame) {
- // Init with a sprite frame
- this.initWithSpriteFrame(fileName);
- } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
- // Init with a canvas or image element
- var texture2d = new cc.Texture2D();
- texture2d.initWithElement(fileName);
- texture2d.handleLoadedTexture();
- this.initWithTexture(texture2d);
- }
- }
- },
+ _softInit: function (fileName, rect, rotated) {
+ if (fileName === undefined)
+ cc.Sprite.prototype.init.call(this);
+ else if (typeof fileName === 'string') {
+ if (fileName[0] === "#") {
+ // Init with a sprite frame name
+ var frameName = fileName.substr(1, fileName.length - 1);
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName);
+ if (spriteFrame)
+ this.initWithSpriteFrame(spriteFrame);
+ else
+ cc.log("%s does not exist", fileName);
+ } else {
+ // Init with filename and rect
+ cc.Sprite.prototype.init.call(this, fileName, rect);
+ }
+ } else if (typeof fileName === "object") {
+ if (fileName instanceof cc.Texture2D) {
+ // Init with texture and rect
+ this.initWithTexture(fileName, rect, rotated);
+ } else if (fileName instanceof cc.SpriteFrame) {
+ // Init with a sprite frame
+ this.initWithSpriteFrame(fileName);
+ } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
+ // Init with a canvas or image element
+ var texture2d = new cc.Texture2D();
+ texture2d.initWithElement(fileName);
+ texture2d.handleLoadedTexture();
+ this.initWithTexture(texture2d);
+ }
+ }
+ },
/**
* Returns the quad (tex coords, vertex coords and color) information.
* @return {cc.V3F_C4B_T2F_Quad|null} Returns a cc.V3F_C4B_T2F_Quad object when render mode is WebGL, returns null when render mode is Canvas.
*/
- getQuad:function () {
- return this._renderCmd.getQuad();
+ getQuad: function () {
+ return null;
},
/**
@@ -638,7 +505,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
_t._offsetPosition.y = 0;
_t._hasChildren = false;
- this._renderCmd._init();
// updated in "useSelfRender"
// Atlas: TexCoords
_t.setTextureRect(cc.rect(0, 0, 0, 0), false, cc.size(0, 0));
@@ -658,20 +524,28 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* @param {cc.Rect} rect The rectangle assigned the content area from texture.
* @return {Boolean} true if the sprite is initialized properly, false otherwise.
*/
- initWithFile:function (filename, rect) {
+ initWithFile: function (filename, rect) {
cc.assert(filename, cc._LogInfos.Sprite_initWithFile);
var tex = cc.textureCache.getTextureForKey(filename);
if (!tex) {
tex = cc.textureCache.addImage(filename);
- return this.initWithTexture(tex, rect || cc.rect(0, 0, tex._contentSize.width, tex._contentSize.height));
- } else {
- if (!rect) {
- var size = tex.getContentSize();
- rect = cc.rect(0, 0, size.width, size.height);
- }
- return this.initWithTexture(tex, rect);
}
+
+ if (!tex.isLoaded()) {
+ this._loader.clear();
+ this._loader.once(tex, function () {
+ this.initWithFile(filename, rect);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ if (!rect) {
+ var size = tex.getContentSize();
+ rect = cc.rect(0, 0, size.width, size.height);
+ }
+ return this.initWithTexture(tex, rect);
},
/**
@@ -688,6 +562,16 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
initWithTexture: function (texture, rect, rotated, counterclockwise) {
var _t = this;
cc.assert(arguments.length !== 0, cc._LogInfos.CCSpriteBatchNode_initWithTexture);
+ this._loader.clear();
+
+ _t._textureLoaded = texture.isLoaded();
+ if (!_t._textureLoaded) {
+ this._loader.once(texture, function () {
+ this.initWithTexture(texture, rect, rotated, counterclockwise);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
rotated = rotated || false;
texture = this._renderCmd._handleTextureForRotatedTexture(texture, rect, rotated, counterclockwise);
@@ -705,32 +589,17 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
_t._flippedX = _t._flippedY = false;
- // default transform anchor: center
- _t.setAnchorPoint(0.5, 0.5);
-
// zwoptex default values
_t._offsetPosition.x = 0;
_t._offsetPosition.y = 0;
_t._hasChildren = false;
- this._renderCmd._init();
-
- var locTextureLoaded = texture.isLoaded();
- _t._textureLoaded = locTextureLoaded;
-
- if (!locTextureLoaded) {
- _t._rectRotated = rotated;
- if (rect) {
- _t._rect.x = rect.x;
- _t._rect.y = rect.y;
- _t._rect.width = rect.width;
- _t._rect.height = rect.height;
- }
- if(_t.texture)
- _t.texture.removeEventListener("load", _t);
- texture.addEventListener("load", _t._renderCmd._textureLoadedCallback, _t);
- _t.texture = texture;
- return true;
+ _t._rectRotated = rotated;
+ if (rect) {
+ _t._rect.x = rect.x;
+ _t._rect.y = rect.y;
+ _t._rect.width = rect.width;
+ _t._rect.height = rect.height;
}
if (!rect)
@@ -738,7 +607,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
this._renderCmd._checkTextureBoundary(texture, rect, rotated);
- _t.texture = texture;
+ _t.setTexture(texture);
_t.setTextureRect(rect, rotated);
// by default use "Self Render".
@@ -753,6 +622,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* @param {cc.Rect} rect a rect of texture
* @param {Boolean} [rotated] Whether or not the texture is rotated
* @param {cc.Size} [untrimmedSize] The original pixels size of the texture
+ * @param {Boolean} [needConvert] contentScaleFactor switch
*/
setTextureRect: function (rect, rotated, untrimmedSize, needConvert) {
var _t = this;
@@ -770,33 +640,16 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
var locRect = _t._rect;
_t._offsetPosition.x = relativeOffsetX + (_t._contentSize.width - locRect.width) / 2;
_t._offsetPosition.y = relativeOffsetY + (_t._contentSize.height - locRect.height) / 2;
-
- // rendering using batch node
- if (_t._batchNode) {
- // update dirty, don't update _recursiveDirty
- _t.dirty = true;
- } else {
- // self rendering
- // Atlas: Vertex
- this._renderCmd._resetForBatchNode();
- }
},
// BatchNode methods
- /**
- * Updates the quad according the the rotation, position, scale values.
- * @function
- */
- updateTransform: function(){
- this._renderCmd.updateTransform();
- },
/**
* Add child to sprite (override cc.Node)
* @function
* @param {cc.Sprite} child
* @param {Number} localZOrder child's zOrder
- * @param {String} [tag] child's tag
+ * @param {number|String} [tag] child's tag
* @override
*/
addChild: function (child, localZOrder, tag) {
@@ -807,7 +660,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
if (tag == null)
tag = child.tag;
- if(this._renderCmd._setBatchNodeForAddChild(child)){
+ if (this._renderCmd._setBatchNodeForAddChild(child)) {
//cc.Node already sets isReorderChildDirty_ so this needs to be after batchNode check
cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
this._hasChildren = true;
@@ -822,38 +675,35 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
*/
setSpriteFrame: function (newFrame) {
var _t = this;
- if(cc.isString(newFrame)){
+ if (typeof newFrame === 'string') {
newFrame = cc.spriteFrameCache.getSpriteFrame(newFrame);
- cc.assert(newFrame, cc._LogInfos.Sprite_setSpriteFrame)
+ cc.assert(newFrame, cc._LogInfos.Sprite_setSpriteFrame);
}
+ this._loader.clear();
this.setNodeDirty(true);
+ // update rect
+ var pNewTexture = newFrame.getTexture();
+ _t._textureLoaded = newFrame.textureLoaded();
+ this._loader.clear();
+ if (!_t._textureLoaded) {
+ this._loader.once(pNewTexture, function () {
+ this.setSpriteFrame(newFrame);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
var frameOffset = newFrame.getOffset();
_t._unflippedOffsetPositionFromCenter.x = frameOffset.x;
_t._unflippedOffsetPositionFromCenter.y = frameOffset.y;
- // update rect
- var pNewTexture = newFrame.getTexture();
- var locTextureLoaded = newFrame.textureLoaded();
- if (!locTextureLoaded) {
- _t._textureLoaded = false;
- newFrame.addEventListener("load", function (sender) {
- _t._textureLoaded = true;
- var locNewTexture = sender.getTexture();
- if (locNewTexture !== _t._texture)
- _t.texture = locNewTexture;
- _t.setTextureRect(sender.getRect(), sender.isRotated(), sender.getOriginalSize());
- _t.dispatchEvent("load");
- _t.setColor(_t.color);
- }, _t);
- }else{
- // update texture before updating texture rect
- if (pNewTexture !== _t._texture)
- _t.texture = pNewTexture;
- _t.setTextureRect(newFrame.getRect(), newFrame.isRotated(), newFrame.getOriginalSize());
+ if (pNewTexture !== _t._texture) {
+ this._renderCmd._setTexture(pNewTexture);
+ _t.setColor(_t._realColor);
}
- this._renderCmd._updateForSetSpriteFrame(pNewTexture);
+ _t.setTextureRect(newFrame.getRect(), newFrame.isRotated(), newFrame.getOriginalSize());
},
/**
@@ -861,7 +711,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* @param {cc.SpriteFrame|String} newFrame
* @deprecated
*/
- setDisplayFrame: function(newFrame){
+ setDisplayFrame: function (newFrame) {
cc.log(cc._LogInfos.Sprite_setDisplayFrame);
this.setSpriteFrame(newFrame);
},
@@ -872,7 +722,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* @param {cc.SpriteFrame} frame
* @return {Boolean}
*/
- isFrameDisplayed: function(frame){
+ isFrameDisplayed: function (frame) {
return this._renderCmd.isFrameDisplayed(frame);
},
@@ -907,23 +757,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* batch.addChild(sprite);
* layer.addChild(batch);
*/
- setBatchNode:function (spriteBatchNode) {
- var _t = this;
- _t._batchNode = spriteBatchNode; // weak reference
-
- // self render
- if (!_t._batchNode) {
- _t.atlasIndex = cc.Sprite.INDEX_NOT_INITIALIZED;
- _t.textureAtlas = null;
- _t._recursiveDirty = false;
- _t.dirty = false;
-
- this._renderCmd._resetForBatchNode();
- } else {
- // using batch
- _t._transformToBatch = cc.affineTransformIdentity();
- _t.textureAtlas = _t._batchNode.getTextureAtlas(); // weak ref
- }
+ setBatchNode: function (spriteBatchNode) {
},
// CCTextureProtocol
@@ -933,62 +767,43 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
* @param {cc.Texture2D|String} texture
*/
setTexture: function (texture) {
- if(!texture)
+ if (!texture)
return this._renderCmd._setTexture(null);
- if(cc.isString(texture)){
+ //CCSprite.cpp 327 and 338
+ var isFileName = (typeof texture === 'string');
+
+ if (isFileName)
texture = cc.textureCache.addImage(texture);
- if(!texture._textureLoaded){
- texture.addEventListener("load", function(){
- this._clearRect();
- this._renderCmd._setTexture(texture);
- this._changeRectWithTexture(texture.getContentSize());
- this.setColor(this._realColor);
- this._textureLoaded = true;
- }, this);
- }else{
- this._clearRect();
- this._renderCmd._setTexture(texture);
- this._changeRectWithTexture(texture.getContentSize());
- this.setColor(this._realColor);
- this._textureLoaded = true;
- }
- }else{
- // CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteSheet
- cc.assert(texture instanceof cc.Texture2D, cc._LogInfos.Sprite_setTexture_2);
- this._clearRect();
- this._changeRectWithTexture(texture.getContentSize());
- this._renderCmd._setTexture(texture);
+ this._loader.clear();
+ if (!texture._textureLoaded) {
+ // wait for the load to be set again
+ this._loader.once(texture, function () {
+ this.setTexture(texture);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
}
- },
- _clearRect: function(){
- var texture = this._texture;
- if(texture){
- var textureRect = texture._contentSize;
- var spriteRect = this._rect;
- if(
- textureRect.width === spriteRect.width &&
- textureRect.height === spriteRect.height
- )
- spriteRect.width = spriteRect.height = 0;
- }
+ this._renderCmd._setTexture(texture);
+ if (isFileName)
+ this._changeRectWithTexture(texture);
+ this.setColor(this._realColor);
+ this._textureLoaded = true;
},
- _changeRectWithTexture: function(rect){
- if(!rect || (!rect.width && !rect.height)) return;
- var textureRect = this.getTextureRect();
- if(textureRect.height || textureRect.width) return;
- rect.x = rect.x || 0;
- rect.y = rect.y || 0;
- rect.width = rect.width || 0;
- rect.height = rect.height || 0;
+ _changeRectWithTexture: function (texture) {
+ var contentSize = texture._contentSize;
+ var rect = cc.rect(
+ 0, 0,
+ contentSize.width, contentSize.height
+ );
this.setTextureRect(rect);
},
- _createRenderCmd: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.Sprite.CanvasRenderCmd(this);
else
return new cc.Sprite.WebGLRenderCmd(this);
@@ -1039,4 +854,39 @@ cc.EventHelper.prototype.apply(cc.Sprite.prototype);
cc.assert(cc.isFunction(cc._tmp.PrototypeSprite), cc._LogInfos.MissingFile, "SpritesPropertyDefine.js");
cc._tmp.PrototypeSprite();
-delete cc._tmp.PrototypeSprite;
\ No newline at end of file
+delete cc._tmp.PrototypeSprite;
+
+(function () {
+ var manager = cc.Sprite.LoadManager = function () {
+ this.list = [];
+ };
+
+ manager.prototype.add = function (source, callback, target) {
+ if (!source || !source.addEventListener) return;
+ source.addEventListener('load', callback, target);
+ this.list.push({
+ source: source,
+ listener: callback,
+ target: target
+ });
+ };
+ manager.prototype.once = function (source, callback, target) {
+ if (!source || !source.addEventListener) return;
+ var tmpCallback = function (event) {
+ source.removeEventListener('load', tmpCallback, target);
+ callback.call(target, event);
+ };
+ source.addEventListener('load', tmpCallback, target);
+ this.list.push({
+ source: source,
+ listener: tmpCallback,
+ target: target
+ });
+ };
+ manager.prototype.clear = function () {
+ while (this.list.length > 0) {
+ var item = this.list.pop();
+ item.source.removeEventListener('load', item.listener, item.target);
+ }
+ };
+})();
diff --git a/cocos2d/core/sprites/CCSpriteBatchNode.js b/cocos2d/core/sprites/CCSpriteBatchNode.js
index a67c4cac19..3abd61fb4c 100644
--- a/cocos2d/core/sprites/CCSpriteBatchNode.js
+++ b/cocos2d/core/sprites/CCSpriteBatchNode.js
@@ -42,15 +42,14 @@
* @extends cc.Node
*
* @param {String|cc.Texture2D} fileImage
- * @param {Number} capacity
* @example
*
* // 1. create a SpriteBatchNode with image path
- * var spriteBatchNode = new cc.SpriteBatchNode("res/animations/grossini.png", 50);
+ * var spriteBatchNode = new cc.SpriteBatchNode("res/animations/grossini.png");
*
* // 2. create a SpriteBatchNode with texture
* var texture = cc.textureCache.addImage("res/animations/grossini.png");
- * var spriteBatchNode = new cc.SpriteBatchNode(texture,50);
+ * var spriteBatchNode = new cc.SpriteBatchNode(texture);
*
* @property {cc.TextureAtlas} textureAtlas - The texture atlas
* @property {Array} descendants - <@readonly> Descendants of sprite batch node
@@ -58,89 +57,64 @@
cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
_blendFunc: null,
// all descendants: chlidren, gran children, etc...
- _descendants: null,
+ _texture: null,
_className: "SpriteBatchNode",
- ctor: function (fileImage, capacity) {
+ ctor: function (fileImage) {
cc.Node.prototype.ctor.call(this);
- this._descendants = [];
this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
var texture2D;
- capacity = capacity || cc.SpriteBatchNode.DEFAULT_CAPACITY;
if (cc.isString(fileImage)) {
texture2D = cc.textureCache.getTextureForKey(fileImage);
if (!texture2D)
texture2D = cc.textureCache.addImage(fileImage);
- }else if (fileImage instanceof cc.Texture2D)
+ } else if (fileImage instanceof cc.Texture2D)
texture2D = fileImage;
- texture2D && this.initWithTexture(texture2D, capacity);
+ texture2D && this.initWithTexture(texture2D);
},
/**
*
- * This is the opposite of "addQuadFromSprite.
- * It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas
+ * Same as addChild
*
* @param {cc.Sprite} child
* @param {Number} z zOrder
* @param {Number} aTag
* @return {cc.SpriteBatchNode}
+ * @deprecated since v3.12
*/
addSpriteWithoutQuad: function (child, z, aTag) {
- cc.assert(child, cc._LogInfos.SpriteBatchNode_addSpriteWithoutQuad_2);
-
- if (!(child instanceof cc.Sprite)) {
- cc.log(cc._LogInfos.SpriteBatchNode_addSpriteWithoutQuad);
- return null;
- }
-
- // quad index is Z
- child.atlasIndex = z;
-
- // XXX: optimize with a binary search
- var i = 0, len, locDescendants = this._descendants;
- if (locDescendants && locDescendants.length > 0) {
- for (i = 0, len = locDescendants.length; i < len; i++) {
- var obj = locDescendants[i];
- if (obj && (obj.atlasIndex >= z))
- break;
- }
- }
- locDescendants.splice(i, 0, child);
-
- // IMPORTANT: Call super, and not self. Avoid adding it to the texture atlas array
- cc.Node.prototype.addChild.call(this, child, z, aTag);
-
- //#issue 1262 don't use lazy sorting, tiles are added as quads not as sprites, so sprites need to be added in order
- this.reorderBatch(false);
+ this.addChild(child, z, aTag);
return this;
},
// property
/**
- * Return TextureAtlas of cc.SpriteBatchNode
+ * Return null, no texture atlas is used any more
* @return {cc.TextureAtlas}
+ * @deprecated since v3.12
*/
getTextureAtlas: function () {
- return this._renderCmd.getTextureAtlas();
+ return null;
},
/**
* TextureAtlas of cc.SpriteBatchNode setter
* @param {cc.TextureAtlas} textureAtlas
+ * @deprecated since v3.12
*/
setTextureAtlas: function (textureAtlas) {
- this._renderCmd.getTextureAtlas(textureAtlas);
},
/**
* Return Descendants of cc.SpriteBatchNode
* @return {Array}
+ * @deprecated since v3.12
*/
getDescendants: function () {
- return this._descendants;
+ return this._children;
},
/**
@@ -161,11 +135,6 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
return this.initWithTexture(texture2D, capacity);
},
- _setNodeDirtyForCache: function () {
- if(this._renderCmd && this._renderCmd._setNodeDirtyForCache)
- this._renderCmd._setNodeDirtyForCache();
- },
-
/**
*
* initializes a cc.SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and a capacity of children.
@@ -185,10 +154,10 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
},
/**
- * Increase Atlas Capacity
+ * Do nothing
+ * @deprecated since v3.12
*/
increaseAtlasCapacity: function () {
- this._renderCmd.increaseAtlasCapacity();
},
/**
@@ -202,32 +171,13 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
},
/**
- * Rebuild index in order for child
+ * Do nothing
* @param {cc.Sprite} pobParent
* @param {Number} index
* @return {Number}
+ * @deprecated since v3.12
*/
rebuildIndexInOrder: function (pobParent, index) {
- var children = pobParent.children;
- if (children && children.length > 0) {
- for (var i = 0; i < children.length; i++) {
- var obj = children[i];
- if (obj && (obj.zIndex < 0))
- index = this.rebuildIndexInOrder(obj, index);
- }
- }
- // ignore self (batch node)
- if (!pobParent === this) {
- pobParent.atlasIndex = index;
- index++;
- }
- if (children && children.length > 0) {
- for (i = 0; i < children.length; i++) {
- obj = children[i];
- if (obj && (obj.zIndex >= 0))
- index = this.rebuildIndexInOrder(obj, index);
- }
- }
return index;
},
@@ -235,12 +185,12 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
* Returns highest atlas index in child
* @param {cc.Sprite} sprite
* @return {Number}
+ * @deprecated since v3.12
*/
highestAtlasIndexInChild: function (sprite) {
var children = sprite.children;
-
if (!children || children.length === 0)
- return sprite.atlasIndex;
+ return sprite.zIndex;
else
return this.highestAtlasIndexInChild(children[children.length - 1]);
},
@@ -249,60 +199,30 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
* Returns lowest atlas index in child
* @param {cc.Sprite} sprite
* @return {Number}
+ * @deprecated since v3.12
*/
lowestAtlasIndexInChild: function (sprite) {
var children = sprite.children;
if (!children || children.length === 0)
- return sprite.atlasIndex;
+ return sprite.zIndex;
else
return this.lowestAtlasIndexInChild(children[children.length - 1]);
},
/**
- * Returns atlas index for child
+ * Returns index for child
* @param {cc.Sprite} sprite
- * @param {Number} nZ
* @return {Number}
+ * @deprecated since v3.12
*/
- atlasIndexForChild: function (sprite, nZ) {
- var selParent = sprite.parent;
- var brothers = selParent.children;
- var childIndex = brothers.indexOf(sprite);
-
- // ignore parent Z if parent is spriteSheet
- var ignoreParent = selParent === this;
- var previous = null;
- if (childIndex > 0 && childIndex < cc.UINT_MAX)
- previous = brothers[childIndex - 1];
-
- // first child of the sprite sheet
- if (ignoreParent) {
- if (childIndex === 0)
- return 0;
- return this.highestAtlasIndexInChild(previous) + 1;
- }
-
- // parent is a cc.Sprite, so, it must be taken into account
- // first child of an cc.Sprite ?
- if (childIndex === 0) {
- // less than parent and brothers
- if (nZ < 0)
- return selParent.atlasIndex;
- else
- return selParent.atlasIndex + 1;
- } else {
- // previous & sprite belong to the same branch
- if ((previous.zIndex < 0 && nZ < 0) || (previous.zIndex >= 0 && nZ >= 0))
- return this.highestAtlasIndexInChild(previous) + 1;
-
- // else (previous < 0 and sprite >= 0 )
- return selParent.atlasIndex + 1;
- }
+ atlasIndexForChild: function (sprite) {
+ return sprite.zIndex;
},
/**
* Sprites use this to start sortChildren, don't call this manually
* @param {Boolean} reorder
+ * @deprecated since v3.12
*/
reorderBatch: function (reorder) {
this._reorderChildDirty = reorder;
@@ -325,46 +245,7 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
* @return {cc.BlendFunc}
*/
getBlendFunc: function () {
- return new cc.BlendFunc(this._blendFunc.src,this._blendFunc.dst);
- },
-
- /**
- * Reorder children (override reorderChild of cc.Node)
- * @override
- * @param {cc.Sprite} child
- * @param {Number} zOrder
- */
- reorderChild: function (child, zOrder) {
- cc.assert(child, cc._LogInfos.SpriteBatchNode_reorderChild_2);
- if (this._children.indexOf(child) === -1) {
- cc.log(cc._LogInfos.SpriteBatchNode_reorderChild);
- return;
- }
- if (zOrder === child.zIndex)
- return;
-
- //set the z-order and sort later
- cc.Node.prototype.reorderChild.call(this, child, zOrder);
- //this.setNodeDirty();
- },
-
- /**
- * Removes a child from cc.SpriteBatchNode (override removeChild of cc.Node)
- * @param {cc.Sprite} child
- * @param {Boolean} cleanup
- */
- removeChild: function (child, cleanup) {
- // explicit null handling
- if (child == null)
- return;
- if (this._children.indexOf(child) === -1) {
- cc.log(cc._LogInfos.SpriteBatchNode_removeChild);
- return;
- }
-
- // cleanup before removing
- this.removeSpriteFromAtlas(child);
- cc.Node.prototype.removeChild.call(this, child, cleanup);
+ return new cc.BlendFunc(this._blendFunc.src, this._blendFunc.dst);
},
/**
@@ -383,155 +264,71 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
cc.log(cc._LogInfos.CCSpriteBatchNode_updateQuadFromSprite);
return;
}
- this._renderCmd.checkAtlasCapacity();
//
// update the quad directly. Don't add the sprite to the scene graph
//
- sprite.batchNode = this;
- sprite.atlasIndex = index;
sprite.dirty = true;
// UpdateTransform updates the textureAtlas quad
- sprite.updateTransform();
+ sprite._renderCmd.transform(this._renderCmd, true);
},
/**
*
- * Inserts a quad at a certain index into the texture atlas. The cc.Sprite won't be added into the children array.
- * This method should be called only when you are dealing with very big AtlasSprite and when most of the cc.Sprite won't be updated.
- * For example: a tile map (cc.TMXMap) or a label with lots of characters (cc.LabelBMFont)
+ * Same as addChild(sprite, index)
*
* @function
* @param {cc.Sprite} sprite
* @param {Number} index
+ * @deprecated since v3.12
*/
insertQuadFromSprite: function (sprite, index) {
- cc.assert(sprite, cc._LogInfos.CCSpriteBatchNode_insertQuadFromSprite_2);
- if (!(sprite instanceof cc.Sprite)) {
- cc.log(cc._LogInfos.CCSpriteBatchNode_insertQuadFromSprite);
- return;
- }
- this._renderCmd.insertQuad(sprite, index);
-
- //
- // update the quad directly. Don't add the sprite to the scene graph
- //
- sprite.batchNode = this;
- sprite.atlasIndex = index;
-
- // XXX: updateTransform will update the textureAtlas too, using updateQuad.
- // XXX: so, it should be AFTER the insertQuad
- sprite.dirty = true;
- sprite.updateTransform();
- this._renderCmd.cutting(sprite, index);
- },
-
- /**
- *
- * Initializes a cc.SpriteBatchNode with a texture2d and capacity of children.
- * The capacity will be increased in 33% in runtime if it run out of space.
- * Please pass parameters to constructor to initialize the sprite batch node, do not call this function yourself.
- *
- * @function
- * @param {cc.Texture2D} tex
- * @param {Number} [capacity]
- * @return {Boolean}
- */
- initWithTexture: function (tex, capacity) {
- this._children.length = 0;
- this._descendants.length = 0;
-
- capacity = capacity || cc.SpriteBatchNode.DEFAULT_CAPACITY;
- this._renderCmd.initWithTexture(tex, capacity);
- return true;
+ this.addChild(sprite, index);
},
/**
- * Insert a child
+ * Same as addChild(sprite, index)
* @param {cc.Sprite} sprite The child sprite
* @param {Number} index The insert index
+ * @deprecated since v3.12
*/
insertChild: function (sprite, index) {
- //TODO WebGL only ?
- sprite.batchNode = this;
- sprite.atlasIndex = index;
- sprite.dirty = true;
-
- this._renderCmd.insertQuad(sprite, index);
- this._descendants.splice(index, 0, sprite);
-
- // update indices
- var i = index + 1, locDescendant = this._descendants;
- if (locDescendant && locDescendant.length > 0) {
- for (; i < locDescendant.length; i++)
- locDescendant[i].atlasIndex++;
- }
-
- // add children recursively
- var locChildren = sprite.children, child, l;
- if (locChildren) {
- for (i = 0, l = locChildren.length || 0; i < l; i++) {
- child = locChildren[i];
- if (child) {
- var getIndex = this.atlasIndexForChild(child, child.zIndex);
- this.insertChild(child, getIndex);
- }
- }
- }
+ this.addChild(sprite, index);
},
/**
- * Add child at the end, faster than insert child
+ * Add child at the end
* @function
* @param {cc.Sprite} sprite
*/
appendChild: function (sprite) {
- this._reorderChildDirty = true;
- sprite.batchNode = this;
- sprite.dirty = true;
-
- this._descendants.push(sprite);
- var index = this._descendants.length - 1;
-
- sprite.atlasIndex = index;
- this._renderCmd.insertQuad(sprite, index);
-
- // add children recursively
- var children = sprite.children;
- for (var i = 0, l = children.length || 0; i < l; i++)
- this.appendChild(children[i]);
+ this.sortAllChildren();
+ var lastLocalZOrder = this._children[this._children.length - 1]._localZOrder;
+ this.addChild(sprite.lastLocalZOrder + 1);
},
/**
- * Removes sprite from TextureAtlas
+ * Same as removeChild
* @function
* @param {cc.Sprite} sprite
+ * @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise.
+ * @deprecated since v3.12
*/
- removeSpriteFromAtlas: function (sprite) {
- this._renderCmd.removeQuadAtIndex(sprite.atlasIndex);
-
- // Cleanup sprite. It might be reused (issue #569)
- sprite.batchNode = null;
- var locDescendants = this._descendants;
- var index = locDescendants.indexOf(sprite);
- if (index !== -1) {
- locDescendants.splice(index, 1);
-
- // update all sprites beyond this one
- var len = locDescendants.length;
- for (; index < len; ++index) {
- var s = locDescendants[index];
- s.atlasIndex--;
- }
- }
+ removeSpriteFromAtlas: function (sprite, cleanup) {
+ this.removeChild(sprite, cleanup);
+ },
- // remove children recursively
- var children = sprite.children;
- if (children) {
- for (var i = 0, l = children.length || 0; i < l; i++)
- children[i] && this.removeSpriteFromAtlas(children[i]);
- }
+ /**
+ * Set the texture property
+ * @function
+ * @param {cc.Texture2D} tex
+ * @return {Boolean}
+ */
+ initWithTexture: function (tex) {
+ this.setTexture(tex);
+ return true;
},
+
// CCTextureProtocol
/**
* Returns texture of the sprite batch node
@@ -539,7 +336,7 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
* @return {cc.Texture2D}
*/
getTexture: function () {
- return this._renderCmd.getTexture();
+ return this._texture;
},
/**
@@ -547,8 +344,31 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
* @function
* @param {cc.Texture2D} texture
*/
- setTexture: function(texture){
- this._renderCmd.setTexture(texture);
+ setTexture: function (texture) {
+ this._texture = texture;
+
+ if (texture._textureLoaded) {
+ var i, children = this._children, len = children.length;
+ for (i = 0; i < len; ++i) {
+ children[i].setTexture(texture);
+ }
+ }
+ else {
+ texture.addEventListener("load", function () {
+ var i, children = this._children, len = children.length;
+ for (i = 0; i < len; ++i) {
+ children[i].setTexture(texture);
+ }
+ }, this);
+ }
+ },
+
+ setShaderProgram: function (newShaderProgram) {
+ this._renderCmd.setShaderProgram(newShaderProgram);
+ var i, children = this._children, len = children.length;
+ for (i = 0; i < len; ++i) {
+ children[i].setShaderProgram(newShaderProgram);
+ }
},
/**
@@ -560,77 +380,31 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
* @param {Number} [tag]
*/
addChild: function (child, zOrder, tag) {
- cc.assert(child != null, cc._LogInfos.CCSpriteBatchNode_addChild_3);
+ cc.assert(child !== undefined, cc._LogInfos.CCSpriteBatchNode_addChild_3);
- if(!this._renderCmd.isValidChild(child))
+ if (!this._isValidChild(child))
return;
- zOrder = (zOrder == null) ? child.zIndex : zOrder;
- tag = (tag == null) ? child.tag : tag;
+ zOrder = (zOrder === undefined) ? child.zIndex : zOrder;
+ tag = (tag === undefined) ? child.tag : tag;
cc.Node.prototype.addChild.call(this, child, zOrder, tag);
- this.appendChild(child);
- //this.setNodeDirty();
- },
-
- /**
- * Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter.
- * (override removeAllChildren of cc.Node)
- * @function
- * @param {Boolean} cleanup
- */
- removeAllChildren: function (cleanup) {
- // Invalidate atlas index. issue #569
- // useSelfRender should be performed on all descendants. issue #1216
- var locDescendants = this._descendants;
- if (locDescendants && locDescendants.length > 0) {
- for (var i = 0, len = locDescendants.length; i < len; i++) {
- if (locDescendants[i])
- locDescendants[i].batchNode = null;
- }
+
+ // Apply shader
+ if (this._renderCmd._shaderProgram) {
+ child.shaderProgram = this._renderCmd._shaderProgram;
}
- cc.Node.prototype.removeAllChildren.call(this, cleanup);
- this._descendants.length = 0;
- this._renderCmd.removeAllQuads();
},
- /**
- * Sort all children nodes (override draw of cc.Node)
- */
- sortAllChildren: function () {
- if (this._reorderChildDirty) {
- var childrenArr = this._children;
- var i, j = 0, length = childrenArr.length, tempChild;
- //insertion sort
- for (i = 1; i < length; i++) {
- var tempItem = childrenArr[i];
- j = i - 1;
- tempChild = childrenArr[j];
-
- //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
- while (j >= 0 && ( tempItem._localZOrder < tempChild._localZOrder ||
- ( tempItem._localZOrder === tempChild._localZOrder && tempItem.arrivalOrder < tempChild.arrivalOrder ))) {
- childrenArr[j + 1] = tempChild;
- j = j - 1;
- tempChild = childrenArr[j];
- }
- childrenArr[j + 1] = tempItem;
- }
-
- //sorted now check all children
- if (childrenArr.length > 0) {
- //first sort all children recursively based on zOrder
- this._arrayMakeObjectsPerformSelector(childrenArr, cc.Node._stateCallbackType.sortAllChildren);
- this._renderCmd.updateChildrenAtlasIndex(childrenArr);
- }
- this._reorderChildDirty = false;
+ _isValidChild: function (child) {
+ if (!(child instanceof cc.Sprite)) {
+ cc.log(cc._LogInfos.Sprite_addChild_4);
+ return false;
}
- },
-
- _createRenderCmd: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
- return new cc.SpriteBatchNode.CanvasRenderCmd(this);
- else
- return new cc.SpriteBatchNode.WebGLRenderCmd(this);
+ if (child.texture !== this._texture) {
+ cc.log(cc._LogInfos.Sprite_addChild_5);
+ return false;
+ }
+ return true;
}
});
@@ -638,20 +412,9 @@ var _p = cc.SpriteBatchNode.prototype;
// Override properties
cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
-cc.defineGetterSetter(_p, "textureAtlas", _p.getTextureAtlas, _p.setTextureAtlas);
-
-// Extended properties
-/** @expose */
-_p.descendants;
-cc.defineGetterSetter(_p, "descendants", _p.getDescendants);
+cc.defineGetterSetter(_p, "shaderProgram", _p.getShaderProgram, _p.setShaderProgram);
-/**
- * @constant
- * @type Number
- */
-cc.SpriteBatchNode.DEFAULT_CAPACITY = 29;
-
/**
*
* creates a cc.SpriteBatchNodeCanvas with a file image (.png, .jpg etc) with a default capacity of 29 children.
@@ -661,11 +424,10 @@ cc.SpriteBatchNode.DEFAULT_CAPACITY = 29;
* @deprecated since v3.0, please use new construction instead
* @see cc.SpriteBatchNode
* @param {String|cc.Texture2D} fileImage
- * @param {Number} capacity
* @return {cc.SpriteBatchNode}
*/
-cc.SpriteBatchNode.create = function (fileImage, capacity) {
- return new cc.SpriteBatchNode(fileImage, capacity);
+cc.SpriteBatchNode.create = function (fileImage) {
+ return new cc.SpriteBatchNode(fileImage);
};
/**
@@ -673,4 +435,4 @@ cc.SpriteBatchNode.create = function (fileImage, capacity) {
* @see cc.SpriteBatchNode
* @function
*/
-cc.SpriteBatchNode.createWithTexture = cc.SpriteBatchNode.create;
\ No newline at end of file
+cc.SpriteBatchNode.createWithTexture = cc.SpriteBatchNode.create;
diff --git a/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js b/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js
deleted file mode 100644
index 249486eae9..0000000000
--- a/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
- Copyright (c) 2013-2014 Chukong Technologies Inc.
-
- http://www.cocos2d-x.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
-
-(function(){
- //SpriteBatchNode's canvas render command
- cc.SpriteBatchNode.CanvasRenderCmd = function(renderable){
- cc.Node.CanvasRenderCmd.call(this, renderable);
-
- this._texture = null;
- this._originalTexture = null;
- };
-
- var proto = cc.SpriteBatchNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
- proto.constructor = cc.SpriteBatchNode.CanvasRenderCmd;
-
- proto.checkAtlasCapacity = function(){};
-
- proto.isValidChild = function(child){
- if (!(child instanceof cc.Sprite)) {
- cc.log(cc._LogInfos.Sprite_addChild_4);
- return false;
- }
- return true;
- };
-
- proto.initWithTexture = function(texture, capacity){
- this._originalTexture = texture;
- this._texture = texture;
- };
-
- proto.insertQuad = function(sprite, index){};
-
- proto.increaseAtlasCapacity = function(){};
-
- proto.removeQuadAtIndex = function(){};
-
- proto.removeAllQuads = function(){};
-
- proto.getTexture = function(){
- return this._texture;
- };
-
- proto.setTexture = function(texture){
- this._texture = texture;
- var locChildren = this._node._children;
- for (var i = 0; i < locChildren.length; i++)
- locChildren[i].setTexture(texture);
- };
-
- proto.updateChildrenAtlasIndex = function(children){
- this._node._descendants.length = 0;
- //update _descendants after sortAllChildren
- for (var i = 0, len = children.length; i < len; i++)
- this._updateAtlasIndex(children[i]);
- };
-
- proto._updateAtlasIndex = function (sprite) {
- var locDescendants = this._node._descendants;
- var pArray = sprite.children, i, len = pArray.length;
- for (i = 0; i < len; i++) {
- if (pArray[i]._localZOrder < 0) {
- locDescendants.push(pArray[i]);
- } else
- break
- }
- locDescendants.push(sprite);
- for (; i < len; i++) {
- locDescendants.push(pArray[i]);
- }
- };
-
- proto.getTextureAtlas = function(){};
-
- proto.setTextureAtlas = function(textureAtlas){};
-
- proto.cutting = function(sprite, index){
- var node = this._node;
- node._children.splice(index, 0, sprite);
- }
-})();
\ No newline at end of file
diff --git a/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js
deleted file mode 100644
index d61973d7e7..0000000000
--- a/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js
+++ /dev/null
@@ -1,243 +0,0 @@
-/****************************************************************************
- Copyright (c) 2013-2014 Chukong Technologies Inc.
-
- http://www.cocos2d-x.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
-
-(function(){
- //SpriteBatchNode's WebGL render command
- cc.SpriteBatchNode.WebGLRenderCmd = function(renderable){
- cc.Node.WebGLRenderCmd.call(this, renderable);
- this._needDraw = true;
-
- this._textureAtlas = null;
- };
-
- var proto = cc.SpriteBatchNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
- proto.constructor = cc.SpriteBatchNode.WebGLRenderCmd;
-
- proto.isValidChild = function(child){
- if (!(child instanceof cc.Sprite)) {
- cc.log(cc._LogInfos.Sprite_addChild_4);
- return false;
- }
- if (child.texture != this.getTexture()) {
- cc.log(cc._LogInfos.Sprite_addChild_5);
- return false;
- }
- return true;
- };
-
- proto.rendering = function () {
- var node = this._node;
- if (this._textureAtlas.totalQuads === 0)
- return;
-
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
- node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform);
- cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
-
- this._textureAtlas.drawQuads();
- };
-
- proto.visit = function(parentCmd){
- var node = this._node;
- // quick return if not visible
- if (!node._visible)
- return;
-
- if (node._parent && node._parent._renderCmd)
- this._curLevel = node._parent._renderCmd._curLevel + 1;
-
- var currentStack = cc.current_stack;
-
- //optimize performance for javascript
- currentStack.stack.push(currentStack.top);
-
- if(!(this._dirtyFlag & cc.Node._dirtyFlags.transformDirty)) //batchNode's transform must update in visit
- this.transform(parentCmd);
- this.updateStatus(parentCmd); //because batchNode doesn't visit its children.
- currentStack.top = this._stackMatrix;
-
- node.sortAllChildren();
-
- cc.renderer.pushRenderCommand(this);
-
- this._dirtyFlag = 0;
- //optimize performance for javascript
- currentStack.top = currentStack.stack.pop();
- };
-
- proto.checkAtlasCapacity = function(index){
- // make needed room
- var locAtlas = this._textureAtlas;
- while (index >= locAtlas.capacity || locAtlas.capacity === locAtlas.totalQuads) {
- this.increaseAtlasCapacity();
- }
- };
-
- proto.increaseAtlasCapacity = function(){
- // if we're going beyond the current TextureAtlas's capacity,
- // all the previously initialized sprites will need to redo their texture coords
- // this is likely computationally expensive
- var locCapacity = this._textureAtlas.capacity;
- var quantity = Math.floor((locCapacity + 1) * 4 / 3);
-
- cc.log(cc._LogInfos.SpriteBatchNode_increaseAtlasCapacity, locCapacity, quantity);
-
- if (!this._textureAtlas.resizeCapacity(quantity)) {
- // serious problems
- cc.log(cc._LogInfos.SpriteBatchNode_increaseAtlasCapacity_2);
- }
- };
-
- proto.initWithTexture = function(texture, capacity){
- this._textureAtlas = new cc.TextureAtlas();
- this._textureAtlas.initWithTexture(texture, capacity);
- this._updateBlendFunc();
- this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
- };
-
- proto.insertQuad = function(sprite, index){
- var locTextureAtlas = this._textureAtlas;
- if (locTextureAtlas.totalQuads >= locTextureAtlas.capacity)
- this.increaseAtlasCapacity();
- locTextureAtlas.insertQuad(sprite.quad, index);
- };
-
- proto.removeQuadAtIndex = function(index){
- this._textureAtlas.removeQuadAtIndex(index); // remove from TextureAtlas
- };
-
- proto.getTexture = function(){
- return this._textureAtlas.texture;
- };
-
- proto.setTexture = function(texture){
- this._textureAtlas.setTexture(texture);
- if(texture)
- this._updateBlendFunc();
- };
-
- proto.removeAllQuads = function(){
- this._textureAtlas.removeAllQuads();
- };
-
- proto._swap = function (oldIndex, newIndex) {
- var locDescendants = this._node._descendants;
- var locTextureAtlas = this._textureAtlas;
- var quads = locTextureAtlas.quads;
- var tempItem = locDescendants[oldIndex];
- var tempIteQuad = cc.V3F_C4B_T2F_QuadCopy(quads[oldIndex]);
-
- //update the index of other swapped item
- locDescendants[newIndex].atlasIndex = oldIndex;
- locDescendants[oldIndex] = locDescendants[newIndex];
-
- locTextureAtlas.updateQuad(quads[newIndex], oldIndex);
- locDescendants[newIndex] = tempItem;
- locTextureAtlas.updateQuad(tempIteQuad, newIndex);
- };
-
- proto._updateAtlasIndex = function (sprite, curIndex) {
- var count = 0;
- var pArray = sprite.children;
- if (pArray)
- count = pArray.length;
-
- var oldIndex = 0;
- if (count === 0) {
- oldIndex = sprite.atlasIndex;
- sprite.atlasIndex = curIndex;
- sprite.arrivalOrder = 0;
- if (oldIndex !== curIndex)
- this._swap(oldIndex, curIndex);
- curIndex++;
- } else {
- var needNewIndex = true;
- if (pArray[0].zIndex >= 0) {
- //all children are in front of the parent
- oldIndex = sprite.atlasIndex;
- sprite.atlasIndex = curIndex;
- sprite.arrivalOrder = 0;
- if (oldIndex !== curIndex)
- this._swap(oldIndex, curIndex);
- curIndex++;
- needNewIndex = false;
- }
- for (var i = 0; i < pArray.length; i++) {
- var child = pArray[i];
- if (needNewIndex && child.zIndex >= 0) {
- oldIndex = sprite.atlasIndex;
- sprite.atlasIndex = curIndex;
- sprite.arrivalOrder = 0;
- if (oldIndex !== curIndex) {
- this._swap(oldIndex, curIndex);
- }
- curIndex++;
- needNewIndex = false;
- }
- curIndex = this._updateAtlasIndex(child, curIndex);
- }
-
- if (needNewIndex) {
- //all children have a zOrder < 0)
- oldIndex = sprite.atlasIndex;
- sprite.atlasIndex = curIndex;
- sprite.arrivalOrder = 0;
- if (oldIndex !== curIndex) {
- this._swap(oldIndex, curIndex);
- }
- curIndex++;
- }
- }
- return curIndex;
- };
-
- proto.updateChildrenAtlasIndex = function(children){
- var index = 0;
- //fast dispatch, give every child a new atlasIndex based on their relative zOrder (keep parent -> child relations intact)
- // and at the same time reorder descedants and the quads to the right index
- for (var i = 0; i < children.length; i++)
- index = this._updateAtlasIndex(children[i], index);
- };
-
- proto._updateBlendFunc = function () {
- if (!this._textureAtlas.texture.hasPremultipliedAlpha()) {
- var blendFunc = this._node._blendFunc;
- blendFunc.src = cc.SRC_ALPHA;
- blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
- }
- };
-
- proto.getTextureAtlas = function(){
- return this._textureAtlas;
- };
-
- proto.setTextureAtlas = function(textureAtlas){
- if (textureAtlas !== this._textureAtlas) {
- this._textureAtlas = textureAtlas;
- }
- };
-
- proto.cutting = function(){};
-})();
diff --git a/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js b/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js
index dd08d36c00..87da2606e5 100644
--- a/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js
+++ b/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js
@@ -22,9 +22,9 @@
THE SOFTWARE.
****************************************************************************/
-(function() {
+(function () {
cc.Sprite.CanvasRenderCmd = function (renderable) {
- cc.Node.CanvasRenderCmd.call(this, renderable);
+ this._rootCtor(renderable);
this._needDraw = true;
this._textureCoord = {
renderX: 0, //the x of texture coordinate for render, when texture tinted, its value doesn't equal x.
@@ -37,30 +37,27 @@
};
this._blendFuncStr = "source-over";
this._colorized = false;
-
- this._originalTexture = null;
+ this._canUseDirtyRegion = true;
+ this._textureToRender = null;
};
var proto = cc.Sprite.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
proto.constructor = cc.Sprite.CanvasRenderCmd;
+ proto._spriteCmdCtor = cc.Sprite.CanvasRenderCmd;
- proto._init = function () {};
-
- proto.setDirtyRecursively = function (value) {};
-
- proto._resetForBatchNode = function () {};
+ proto.setDirtyRecursively = function (value) {
+ };
proto._setTexture = function (texture) {
var node = this._node;
if (node._texture !== texture) {
- if (texture) {
- if(texture.getHtmlElementObj() instanceof HTMLImageElement)
- this._originalTexture = texture;
- node._textureLoaded = texture._textureLoaded;
- }else{
- node._textureLoaded = false;
- }
+ node._textureLoaded = texture ? texture._textureLoaded : false;
node._texture = texture;
+
+ var texSize = texture._contentSize;
+ var rect = cc.rect(0, 0, texSize.width, texSize.height);
+ node.setTextureRect(rect);
+ this._updateColor();
}
};
@@ -105,14 +102,14 @@
if (_y > texture.height)
cc.error(cc._LogInfos.RectHeight, texture.url);
}
- this._node._originalTexture = texture;
};
proto.rendering = function (ctx, scaleX, scaleY) {
var node = this._node;
var locTextureCoord = this._textureCoord, alpha = (this._displayedOpacity / 255);
- if ((node._texture && ((locTextureCoord.width === 0 || locTextureCoord.height === 0) //set texture but the texture isn't loaded.
- || !node._texture._textureLoaded)) || alpha === 0)
+ var texture = this._textureToRender || node._texture;
+
+ if ((texture && (locTextureCoord.width === 0 || locTextureCoord.height === 0 || !texture._textureLoaded)) || alpha === 0)
return;
var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
@@ -123,7 +120,7 @@
wrapper.setCompositeOperation(this._blendFuncStr);
wrapper.setGlobalAlpha(alpha);
- if(node._flippedX || node._flippedY)
+ if (node._flippedX || node._flippedY)
wrapper.save();
if (node._flippedX) {
locX = -locX - locWidth;
@@ -134,159 +131,60 @@
context.scale(1, -1);
}
- if (node._texture) {
- image = node._texture._htmlElementObj;
- if (node._texture._pattern !== "") {
- wrapper.setFillStyle(context.createPattern(image, node._texture._pattern));
- context.fillRect(locX * scaleX, locY * scaleY, locWidth * scaleX, locHeight * scaleY);
+ var sx, sy, sw, sh, x, y, w, h;
+ if (this._colorized) {
+ sx = 0;
+ sy = 0;
+ } else {
+ sx = locTextureCoord.renderX;
+ sy = locTextureCoord.renderY;
+ }
+ sw = locTextureCoord.width;
+ sh = locTextureCoord.height;
+
+ x = locX;
+ y = locY;
+ w = locWidth;
+ h = locHeight;
+
+ if (texture && texture._htmlElementObj) {
+ image = texture._htmlElementObj;
+ if (texture._pattern !== "") {
+ wrapper.setFillStyle(context.createPattern(image, texture._pattern));
+ context.fillRect(x, y, w, h);
} else {
- if (this._colorized) {
- context.drawImage(image,
- 0, 0, locTextureCoord.width,locTextureCoord.height,
- locX * scaleX,locY * scaleY, locWidth * scaleX, locHeight * scaleY);
- } else {
- context.drawImage(image,
- locTextureCoord.renderX, locTextureCoord.renderY, locTextureCoord.width, locTextureCoord.height,
- locX * scaleX, locY * scaleY, locWidth * scaleX, locHeight * scaleY);
- }
+ context.drawImage(image,
+ sx, sy, sw, sh,
+ x, y, w, h);
}
} else {
var contentSize = node._contentSize;
if (locTextureCoord.validRect) {
var curColor = this._displayedColor;
wrapper.setFillStyle("rgba(" + curColor.r + "," + curColor.g + "," + curColor.b + ",1)");
- context.fillRect(locX * scaleX, locY * scaleY, contentSize.width * scaleX, contentSize.height * scaleY);
+ context.fillRect(x, y, contentSize.width * scaleX, contentSize.height * scaleY);
}
}
- if(node._flippedX || node._flippedY)
+ if (node._flippedX || node._flippedY)
wrapper.restore();
cc.g_NumberOfDraws++;
};
- if(!cc.sys._supportCanvasNewBlendModes){
- proto._updateColor = function () {
- var node = this._node, displayedColor = this._displayedColor;
-
- if (displayedColor.r === 255 && displayedColor.g === 255 && displayedColor.b === 255){
- if(this._colorized){
- this._colorized = false;
- node.texture = this._originalTexture;
- }
- return;
- }
-
- var locElement, locTexture = node._texture, locRect = this._textureCoord;
- if (locTexture && locRect.validRect && this._originalTexture) {
- locElement = locTexture.getHtmlElementObj();
- if (!locElement)
- return;
-
- var cacheTextureForColor = cc.textureCache.getTextureColors(this._originalTexture.getHtmlElementObj());
- if (cacheTextureForColor) {
- this._colorized = true;
- //generate color texture cache
- if (locElement instanceof HTMLCanvasElement && !this._rectRotated && !this._newTextureWhenChangeColor)
- cc.Sprite.CanvasRenderCmd._generateTintImage(locElement, cacheTextureForColor, displayedColor, locRect, locElement);
- else {
- locElement = cc.Sprite.CanvasRenderCmd._generateTintImage(locElement, cacheTextureForColor, displayedColor, locRect);
- locTexture = new cc.Texture2D();
- locTexture.initWithElement(locElement);
- locTexture.handleLoadedTexture();
- node.texture = locTexture;
- }
- }
- }
- };
- } else {
- proto._updateColor = function () {
- var node = this._node, displayedColor = this._displayedColor;
- if (displayedColor.r === 255 && displayedColor.g === 255 && displayedColor.b === 255) {
- if (this._colorized) {
- this._colorized = false;
- node.texture = this._originalTexture;
- }
- return;
- }
-
- var locElement, locTexture = node._texture, locRect = this._textureCoord;
- if (locTexture && locRect.validRect && this._originalTexture) {
- locElement = locTexture.getHtmlElementObj();
- if (!locElement)
- return;
-
- this._colorized = true;
- if (locElement instanceof HTMLCanvasElement && !this._rectRotated && !this._newTextureWhenChangeColor
- && this._originalTexture._htmlElementObj !== locElement)
- cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(this._originalTexture._htmlElementObj, displayedColor, locRect, locElement);
- else {
- locElement = cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(this._originalTexture._htmlElementObj, displayedColor, locRect);
- locTexture = new cc.Texture2D();
- locTexture.initWithElement(locElement);
- locTexture.handleLoadedTexture();
- node.texture = locTexture;
- }
- }
- };
- }
-
- proto.getQuad = function () {
- //throw an error. it doesn't support this function.
- return null;
- };
-
- proto._updateForSetSpriteFrame = function (pNewTexture, textureLoaded) {
+ proto._updateColor = function () {
var node = this._node;
- if (node._rectRotated)
- node._originalTexture = pNewTexture; //TODO
- this._colorized = false;
- this._textureCoord.renderX = this._textureCoord.x;
- this._textureCoord.renderY = this._textureCoord.y;
- if (textureLoaded) {
- var curColor = node.getColor();
- if (curColor.r !== 255 || curColor.g !== 255 || curColor.b !== 255)
- this._updateColor();
- }
- };
- proto.updateTransform = function () { //TODO need delete, because Canvas needn't
- var _t = this, node = this._node;
+ var texture = node._texture, rect = this._textureCoord;
+ var dColor = this._displayedColor;
- // re-calculate matrix only if it is dirty
- if (node.dirty) {
- // If it is not visible, or one of its ancestors is not visible, then do nothing:
- var locParent = node._parent;
- if (!node._visible || ( locParent && locParent !== node._batchNode && locParent._shouldBeHidden)) {
- node._shouldBeHidden = true;
- } else {
- node._shouldBeHidden = false;
-
- if (!locParent || locParent === node._batchNode) {
- node._transformToBatch = _t.getNodeToParentTransform();
- } else {
- //cc.assert(_t._parent instanceof cc.Sprite, "Logic error in CCSprite. Parent must be a CCSprite");
- node._transformToBatch = cc.affineTransformConcat(_t.getNodeToParentTransform(), locParent._transformToBatch);
- }
+ if (texture) {
+ if (dColor.r !== 255 || dColor.g !== 255 || dColor.b !== 255) {
+ this._textureToRender = texture._generateColorTexture(dColor.r, dColor.g, dColor.b, rect);
+ this._colorized = true;
+ } else if (texture) {
+ this._textureToRender = texture;
+ this._colorized = false;
}
- node._recursiveDirty = false;
- node.dirty = false;
}
-
- // recursively iterate over children
- if (node._hasChildren)
- node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform);
- };
-
- proto._updateDisplayColor = function (parentColor) {
- cc.Node.CanvasRenderCmd.prototype._updateDisplayColor.call(this, parentColor);
- //this._updateColor();
- };
-
- proto._spriteFrameLoadedCallback = function (spriteFrame) {
- var node = this;
- node.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize());
-
- node._renderCmd._updateColor();
- node.dispatchEvent("load");
};
proto._textureLoadedCallback = function (sender) {
@@ -302,7 +200,6 @@
locRect.width = sender.width;
locRect.height = sender.height;
}
- locRenderCmd._originalTexture = sender;
node.texture = sender;
node.setTextureRect(locRect, node._rectRotated);
@@ -328,166 +225,8 @@
locTextureRect.width = 0 | (rect.width * scaleFactor);
locTextureRect.height = 0 | (rect.height * scaleFactor);
locTextureRect.validRect = !(locTextureRect.width === 0 || locTextureRect.height === 0 || locTextureRect.x < 0 || locTextureRect.y < 0);
-
- if(this._colorized){
- this._node._texture = this._originalTexture;
- this._colorized = false;
- }
- };
-
- //TODO need refactor these functions
- //utils for tint
- // Tint a texture using the "multiply" operation
- cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply = function (image, color, rect, renderCanvas) {
- renderCanvas = renderCanvas || cc.newElement("canvas");
- rect = rect || cc.rect(0, 0, image.width, image.height);
- var context = renderCanvas.getContext("2d");
- if (renderCanvas.width !== rect.width || renderCanvas.height !== rect.height) {
- renderCanvas.width = rect.width;
- renderCanvas.height = rect.height;
- } else {
- context.globalCompositeOperation = "source-over";
- }
-
- context.fillStyle = "rgb(" + (0 | color.r) + "," + (0 | color.g) + "," + (0 | color.b) + ")";
- context.fillRect(0, 0, rect.width, rect.height);
- context.globalCompositeOperation = "multiply";
- context.drawImage(image,
- rect.x,
- rect.y,
- rect.width,
- rect.height,
- 0,
- 0,
- rect.width,
- rect.height);
- context.globalCompositeOperation = "destination-atop";
- context.drawImage(image,
- rect.x,
- rect.y,
- rect.width,
- rect.height,
- 0,
- 0,
- rect.width,
- rect.height);
- return renderCanvas;
- };
-
- //Generate tinted texture with lighter.
- cc.Sprite.CanvasRenderCmd._generateTintImage = function (texture, tintedImgCache, color, rect, renderCanvas) {
- if (!rect)
- rect = cc.rect(0, 0, texture.width, texture.height);
-
- var r = color.r / 255, g = color.g / 255, b = color.b / 255;
- var w = Math.min(rect.width, tintedImgCache[0].width);
- var h = Math.min(rect.height, tintedImgCache[0].height);
- var buff = renderCanvas, ctx;
- // Create a new buffer if required
- if (!buff) {
- buff = cc.newElement("canvas");
- buff.width = w;
- buff.height = h;
- ctx = buff.getContext("2d");
- } else {
- ctx = buff.getContext("2d");
- ctx.clearRect(0, 0, w, h);
- }
- ctx.save();
- ctx.globalCompositeOperation = 'lighter';
- // Make sure to keep the renderCanvas alpha in mind in case of overdraw
- var a = ctx.globalAlpha;
- if (r > 0) {
- ctx.globalAlpha = r * a;
- ctx.drawImage(tintedImgCache[0], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- if (g > 0) {
- ctx.globalAlpha = g * a;
- ctx.drawImage(tintedImgCache[1], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- if (b > 0) {
- ctx.globalAlpha = b * a;
- ctx.drawImage(tintedImgCache[2], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- if (r + g + b < 1) {
- ctx.globalAlpha = a;
- ctx.drawImage(tintedImgCache[3], rect.x, rect.y, w, h, 0, 0, w, h);
- }
- ctx.restore();
- return buff;
};
- cc.Sprite.CanvasRenderCmd._generateTextureCacheForColor = function (texture) {
- if (texture.channelCache) {
- return texture.channelCache;
- }
-
- var textureCache = [
- cc.newElement("canvas"),
- cc.newElement("canvas"),
- cc.newElement("canvas"),
- cc.newElement("canvas")
- ];
-
- function renderToCache() {
- var ref = cc.Sprite.CanvasRenderCmd._generateTextureCacheForColor;
-
- var w = texture.width;
- var h = texture.height;
-
- textureCache[0].width = w;
- textureCache[0].height = h;
- textureCache[1].width = w;
- textureCache[1].height = h;
- textureCache[2].width = w;
- textureCache[2].height = h;
- textureCache[3].width = w;
- textureCache[3].height = h;
-
- ref.canvas.width = w;
- ref.canvas.height = h;
-
- var ctx = ref.canvas.getContext("2d");
- ctx.drawImage(texture, 0, 0);
-
- ref.tempCanvas.width = w;
- ref.tempCanvas.height = h;
-
- var pixels = ctx.getImageData(0, 0, w, h).data;
-
- for (var rgbI = 0; rgbI < 4; rgbI++) {
- var cacheCtx = textureCache[rgbI].getContext('2d');
- cacheCtx.getImageData(0, 0, w, h).data;
- ref.tempCtx.drawImage(texture, 0, 0);
-
- var to = ref.tempCtx.getImageData(0, 0, w, h);
- var toData = to.data;
-
- for (var i = 0; i < pixels.length; i += 4) {
- toData[i ] = (rgbI === 0) ? pixels[i ] : 0;
- toData[i + 1] = (rgbI === 1) ? pixels[i + 1] : 0;
- toData[i + 2] = (rgbI === 2) ? pixels[i + 2] : 0;
- toData[i + 3] = pixels[i + 3];
- }
- cacheCtx.putImageData(to, 0, 0);
- }
- texture.onload = null;
- }
-
- try {
- renderToCache();
- } catch (e) {
- texture.onload = renderToCache;
- }
-
- texture.channelCache = textureCache;
- return textureCache;
- };
-
- cc.Sprite.CanvasRenderCmd._generateTextureCacheForColor.canvas = cc.newElement('canvas');
- cc.Sprite.CanvasRenderCmd._generateTextureCacheForColor.tempCanvas = cc.newElement('canvas');
- cc.Sprite.CanvasRenderCmd._generateTextureCacheForColor.tempCtx = cc.Sprite.CanvasRenderCmd._generateTextureCacheForColor.tempCanvas.getContext('2d');
-
cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas = function (texture, rect, counterclockwise) {
if (!texture)
return null;
@@ -495,14 +234,14 @@
if (!rect)
return texture;
- counterclockwise = counterclockwise == null? true: counterclockwise; // texture package is counterclockwise, spine is clockwise
+ counterclockwise = counterclockwise == null ? true : counterclockwise; // texture package is counterclockwise, spine is clockwise
- var nCanvas = cc.newElement("canvas");
+ var nCanvas = document.createElement("canvas");
nCanvas.width = rect.width;
nCanvas.height = rect.height;
var ctx = nCanvas.getContext("2d");
ctx.translate(nCanvas.width / 2, nCanvas.height / 2);
- if(counterclockwise)
+ if (counterclockwise)
ctx.rotate(-1.5707963267948966);
else
ctx.rotate(1.5707963267948966);
diff --git a/cocos2d/core/sprites/CCSpriteFrame.js b/cocos2d/core/sprites/CCSpriteFrame.js
index b59154f894..4879225a53 100644
--- a/cocos2d/core/sprites/CCSpriteFrame.js
+++ b/cocos2d/core/sprites/CCSpriteFrame.js
@@ -52,18 +52,18 @@
* var frame2 = new cc.SpriteFrame(texture, cc.rect(0,0,90,128),false,0,cc.size(90,128));
*/
cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
- _offset:null,
- _originalSize:null,
- _rectInPixels:null,
- _rotated:false,
- _rect:null,
- _offsetInPixels:null,
- _originalSizeInPixels:null,
- _texture:null,
- _textureFilename:"",
- _textureLoaded:false,
-
- ctor:function (filename, rect, rotated, offset, originalSize) {
+ _offset: null,
+ _originalSize: null,
+ _rectInPixels: null,
+ _rotated: false,
+ _rect: null,
+ _offsetInPixels: null,
+ _originalSizeInPixels: null,
+ _texture: null,
+ _textureFilename: "",
+ _textureLoaded: false,
+
+ ctor: function (filename, rect, rotated, offset, originalSize) {
this._offset = cc.p(0, 0);
this._offsetInPixels = cc.p(0, 0);
this._originalSize = cc.size(0, 0);
@@ -73,11 +73,11 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
this._texture = null;
this._textureLoaded = false;
- if(filename !== undefined && rect !== undefined ){
- if(rotated === undefined || offset === undefined || originalSize === undefined)
+ if (filename !== undefined && rect !== undefined) {
+ if (rotated === undefined || offset === undefined || originalSize === undefined)
this.initWithTexture(filename, rect);
else
- this.initWithTexture(filename, rect, rotated, offset, originalSize)
+ this.initWithTexture(filename, rect, rotated, offset, originalSize);
}
},
@@ -85,7 +85,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns whether the texture have been loaded
* @returns {boolean}
*/
- textureLoaded:function(){
+ textureLoaded: function () {
return this._textureLoaded;
},
@@ -95,7 +95,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* @param {Object} target
* @deprecated since 3.1, please use addEventListener instead
*/
- addLoadedEventListener:function(callback, target){
+ addLoadedEventListener: function (callback, target) {
this.addEventListener("load", callback, target);
},
@@ -103,7 +103,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Gets the rect of the frame in the texture
* @return {cc.Rect}
*/
- getRectInPixels:function () {
+ getRectInPixels: function () {
var locRectInPixels = this._rectInPixels;
return cc.rect(locRectInPixels.x, locRectInPixels.y, locRectInPixels.width, locRectInPixels.height);
},
@@ -112,9 +112,9 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the rect of the frame in the texture
* @param {cc.Rect} rectInPixels
*/
- setRectInPixels:function (rectInPixels) {
- if (!this._rectInPixels){
- this._rectInPixels = cc.rect(0,0,0,0);
+ setRectInPixels: function (rectInPixels) {
+ if (!this._rectInPixels) {
+ this._rectInPixels = cc.rect(0, 0, 0, 0);
}
this._rectInPixels.x = rectInPixels.x;
this._rectInPixels.y = rectInPixels.y;
@@ -127,7 +127,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns whether the sprite frame is rotated in the texture.
* @return {Boolean}
*/
- isRotated:function () {
+ isRotated: function () {
return this._rotated;
},
@@ -135,7 +135,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Set whether the sprite frame is rotated in the texture.
* @param {Boolean} bRotated
*/
- setRotated:function (bRotated) {
+ setRotated: function (bRotated) {
this._rotated = bRotated;
},
@@ -143,7 +143,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns the rect of the sprite frame in the texture
* @return {cc.Rect}
*/
- getRect:function () {
+ getRect: function () {
var locRect = this._rect;
return cc.rect(locRect.x, locRect.y, locRect.width, locRect.height);
},
@@ -152,9 +152,9 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the rect of the sprite frame in the texture
* @param {cc.Rect} rect
*/
- setRect:function (rect) {
- if (!this._rect){
- this._rect = cc.rect(0,0,0,0);
+ setRect: function (rect) {
+ if (!this._rect) {
+ this._rect = cc.rect(0, 0, 0, 0);
}
this._rect.x = rect.x;
this._rect.y = rect.y;
@@ -167,7 +167,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns the offset of the sprite frame in the texture in pixel
* @return {cc.Point}
*/
- getOffsetInPixels:function () {
+ getOffsetInPixels: function () {
return cc.p(this._offsetInPixels);
},
@@ -175,7 +175,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the offset of the sprite frame in the texture in pixel
* @param {cc.Point} offsetInPixels
*/
- setOffsetInPixels:function (offsetInPixels) {
+ setOffsetInPixels: function (offsetInPixels) {
this._offsetInPixels.x = offsetInPixels.x;
this._offsetInPixels.y = offsetInPixels.y;
cc._pointPixelsToPointsOut(this._offsetInPixels, this._offset);
@@ -185,7 +185,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns the original size of the trimmed image
* @return {cc.Size}
*/
- getOriginalSizeInPixels:function () {
+ getOriginalSizeInPixels: function () {
return cc.size(this._originalSizeInPixels);
},
@@ -193,7 +193,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the original size of the trimmed image
* @param {cc.Size} sizeInPixels
*/
- setOriginalSizeInPixels:function (sizeInPixels) {
+ setOriginalSizeInPixels: function (sizeInPixels) {
this._originalSizeInPixels.width = sizeInPixels.width;
this._originalSizeInPixels.height = sizeInPixels.height;
},
@@ -202,7 +202,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns the original size of the trimmed image
* @return {cc.Size}
*/
- getOriginalSize:function () {
+ getOriginalSize: function () {
return cc.size(this._originalSize);
},
@@ -210,7 +210,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the original size of the trimmed image
* @param {cc.Size} sizeInPixels
*/
- setOriginalSize:function (sizeInPixels) {
+ setOriginalSize: function (sizeInPixels) {
this._originalSize.width = sizeInPixels.width;
this._originalSize.height = sizeInPixels.height;
},
@@ -219,7 +219,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns the texture of the frame
* @return {cc.Texture2D}
*/
- getTexture:function () {
+ getTexture: function () {
if (this._texture)
return this._texture;
if (this._textureFilename !== "") {
@@ -235,15 +235,15 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the texture of the frame, the texture is retained automatically
* @param {cc.Texture2D} texture
*/
- setTexture:function (texture) {
+ setTexture: function (texture) {
if (this._texture !== texture) {
var locLoaded = texture.isLoaded();
this._textureLoaded = locLoaded;
this._texture = texture;
- if(!locLoaded){
- texture.addEventListener("load", function(sender){
+ if (!locLoaded) {
+ texture.addEventListener("load", function (sender) {
this._textureLoaded = true;
- if(this._rotated && cc._renderType === cc._RENDER_TYPE_CANVAS){
+ if (this._rotated && cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
var tempElement = sender.getHtmlElementObj();
tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, this.getRect());
var tempTexture = new cc.Texture2D();
@@ -255,15 +255,15 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
this.setRect(cc.rect(0, 0, rect.width, rect.height));
}
var locRect = this._rect;
- if(locRect.width === 0 && locRect.height === 0){
+ if (locRect.width === 0 && locRect.height === 0) {
var w = sender.width, h = sender.height;
this._rect.width = w;
this._rect.height = h;
this._rectInPixels = cc.rectPointsToPixels(this._rect);
this._originalSizeInPixels.width = this._rectInPixels.width;
this._originalSizeInPixels.height = this._rectInPixels.height;
- this._originalSize.width = w;
- this._originalSize.height = h;
+ this._originalSize.width = w;
+ this._originalSize.height = h;
}
//dispatch 'load' event of cc.SpriteFrame
this.dispatchEvent("load");
@@ -276,7 +276,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Returns the offset of the frame in the texture
* @return {cc.Point}
*/
- getOffset:function () {
+ getOffset: function () {
return cc.p(this._offset);
},
@@ -284,7 +284,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Sets the offset of the frame in the texture
* @param {cc.Point} offsets
*/
- setOffset:function (offsets) {
+ setOffset: function (offsets) {
this._offset.x = offsets.x;
this._offset.y = offsets.y;
},
@@ -293,7 +293,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Clone the sprite frame
* @returns {SpriteFrame}
*/
- clone: function(){
+ clone: function () {
var frame = new cc.SpriteFrame();
frame.initWithTexture(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels);
frame.setTexture(this._texture);
@@ -304,7 +304,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Copy the sprite frame
* @return {cc.SpriteFrame}
*/
- copyWithZone:function () {
+ copyWithZone: function () {
var copy = new cc.SpriteFrame();
copy.initWithTexture(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels);
copy.setTexture(this._texture);
@@ -315,7 +315,7 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* Copy the sprite frame
* @returns {cc.SpriteFrame}
*/
- copy:function () {
+ copy: function () {
return this.copyWithZone();
},
@@ -329,39 +329,39 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
* @param {cc.Size} [originalSize=rect.size]
* @return {Boolean}
*/
- initWithTexture:function (texture, rect, rotated, offset, originalSize) {
- if(arguments.length === 2)
+ initWithTexture: function (texture, rect, rotated, offset, originalSize) {
+ if (arguments.length === 2)
rect = cc.rectPointsToPixels(rect);
offset = offset || cc.p(0, 0);
originalSize = originalSize || rect;
rotated = rotated || false;
- if (cc.isString(texture)){
+ if (typeof texture === 'string') {
this._texture = null;
this._textureFilename = texture;
- } else if (texture instanceof cc.Texture2D){
+ } else if (texture instanceof cc.Texture2D) {
this.setTexture(texture);
}
texture = this.getTexture();
this._rectInPixels = rect;
- rect = this._rect = cc.rectPixelsToPoints(rect);
-
- if(texture && texture.url && texture.isLoaded()) {
+ this._rect = cc.rectPixelsToPoints(rect);
+
+ if (texture && texture.url && texture.isLoaded()) {
var _x, _y;
- if(rotated){
+ if (rotated) {
_x = rect.x + rect.height;
_y = rect.y + rect.width;
- }else{
+ } else {
_x = rect.x + rect.width;
_y = rect.y + rect.height;
}
- if(_x > texture.getPixelsWide()){
+ if (_x > texture.getPixelsWide()) {
cc.error(cc._LogInfos.RectWidth, texture.url);
}
- if(_y > texture.getPixelsHigh()){
+ if (_y > texture.getPixelsHigh()) {
cc.error(cc._LogInfos.RectHeight, texture.url);
}
}
@@ -394,7 +394,7 @@ cc.EventHelper.prototype.apply(cc.SpriteFrame.prototype);
* @return {cc.SpriteFrame}
*/
cc.SpriteFrame.create = function (filename, rect, rotated, offset, originalSize) {
- return new cc.SpriteFrame(filename,rect,rotated,offset,originalSize);
+ return new cc.SpriteFrame(filename, rect, rotated, offset, originalSize);
};
/**
diff --git a/cocos2d/core/sprites/CCSpriteFrameCache.js b/cocos2d/core/sprites/CCSpriteFrameCache.js
index f6ebcf2c58..7d38e89a5b 100644
--- a/cocos2d/core/sprites/CCSpriteFrameCache.js
+++ b/cocos2d/core/sprites/CCSpriteFrameCache.js
@@ -36,38 +36,38 @@
* @name cc.spriteFrameCache
*/
cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
- _CCNS_REG1 : /^\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*$/,
- _CCNS_REG2 : /^\s*\{\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*,\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*\}\s*$/,
+ _CCNS_REG1: /^\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*$/,
+ _CCNS_REG2: /^\s*\{\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*,\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*\}\s*$/,
_spriteFrames: {},
_spriteFramesAliases: {},
- _frameConfigCache : {},
+ _frameConfigCache: {},
- _rectFromString : function (content) {
+ _rectFromString: function (content) {
var result = this._CCNS_REG2.exec(content);
- if(!result) return cc.rect(0, 0, 0, 0);
+ if (!result) return cc.rect(0, 0, 0, 0);
return cc.rect(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]));
},
- _pointFromString : function (content) {
+ _pointFromString: function (content) {
var result = this._CCNS_REG1.exec(content);
- if(!result) return cc.p(0,0);
+ if (!result) return cc.p(0, 0);
return cc.p(parseFloat(result[1]), parseFloat(result[2]));
},
- _sizeFromString : function (content) {
+ _sizeFromString: function (content) {
var result = this._CCNS_REG1.exec(content);
- if(!result) return cc.size(0, 0);
+ if (!result) return cc.size(0, 0);
return cc.size(parseFloat(result[1]), parseFloat(result[2]));
},
- _getFrameConfig : function(url){
+ _getFrameConfig: function (url) {
var dict = cc.loader.getRes(url);
cc.assert(dict, cc._LogInfos.spriteFrameCache__getFrameConfig_2, url);
cc.loader.release(url);//release it in loader
- if(dict._inited){
+ if (dict._inited) {
this._frameConfigCache[url] = dict;
return dict;
}
@@ -75,24 +75,24 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
return this._frameConfigCache[url];
},
- _getFrameConfigByJsonObject: function(url, jsonObject) {
+ _getFrameConfigByJsonObject: function (url, jsonObject) {
cc.assert(jsonObject, cc._LogInfos.spriteFrameCache__getFrameConfig_2, url);
this._frameConfigCache[url] = this._parseFrameConfig(jsonObject);
return this._frameConfigCache[url];
},
- _parseFrameConfig: function(dict) {
+ _parseFrameConfig: function (dict) {
var tempFrames = dict["frames"], tempMeta = dict["metadata"] || dict["meta"];
var frames = {}, meta = {};
var format = 0;
- if(tempMeta){//init meta
+ if (tempMeta) {//init meta
var tmpFormat = tempMeta["format"];
format = (tmpFormat.length <= 1) ? parseInt(tmpFormat) : tmpFormat;
meta.image = tempMeta["textureFileName"] || tempMeta["textureFileName"] || tempMeta["image"];
}
for (var key in tempFrames) {
var frameDict = tempFrames[key];
- if(!frameDict) continue;
+ if (!frameDict) continue;
var tempFrame = {};
if (format == 0) {
@@ -140,9 +140,9 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
},
// Adds multiple Sprite Frames from a json object. it uses for local web view app.
- _addSpriteFramesByObject: function(url, jsonObject, texture) {
+ _addSpriteFramesByObject: function (url, jsonObject, texture) {
cc.assert(url, cc._LogInfos.spriteFrameCache_addSpriteFrames_2);
- if(!jsonObject || !jsonObject["frames"])
+ if (!jsonObject || !jsonObject["frames"])
return;
var frameConfig = this._frameConfigCache[url] || this._getFrameConfigByJsonObject(url, jsonObject);
@@ -150,16 +150,16 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
this._createSpriteFrames(url, frameConfig, texture);
},
- _createSpriteFrames: function(url, frameConfig, texture) {
+ _createSpriteFrames: function (url, frameConfig, texture) {
var frames = frameConfig.frames, meta = frameConfig.meta;
- if(!texture){
+ if (!texture) {
var texturePath = cc.path.changeBasename(url, meta.image || ".png");
texture = cc.textureCache.addImage(texturePath);
- }else if(texture instanceof cc.Texture2D){
+ } else if (texture instanceof cc.Texture2D) {
//do nothing
- }else if(cc.isString(texture)){//string
+ } else if (cc.isString(texture)) {//string
texture = cc.textureCache.addImage(texture);
- }else{
+ } else {
cc.assert(0, cc._LogInfos.spriteFrameCache_addSpriteFrames_3);
}
@@ -169,10 +169,10 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
var frame = frames[key];
var spriteFrame = spriteFrames[key];
if (!spriteFrame) {
- spriteFrame = new cc.SpriteFrame(texture, frame.rect, frame.rotated, frame.offset, frame.size);
+ spriteFrame = new cc.SpriteFrame(texture, cc.rect(frame.rect), frame.rotated, frame.offset, frame.size);
var aliases = frame.aliases;
- if(aliases){//set aliases
- for(var i = 0, li = aliases.length; i < li; i++){
+ if (aliases) {//set aliases
+ for (var i = 0, li = aliases.length; i < li; i++) {
var alias = aliases[i];
if (spAliases[alias])
cc.log(cc._LogInfos.spriteFrameCache_addSpriteFrames, alias);
@@ -180,7 +180,7 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
}
}
- if (cc._renderType === cc._RENDER_TYPE_CANVAS && spriteFrame.isRotated()) {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS && spriteFrame.isRotated()) {
//clip to canvas
var locTexture = spriteFrame.getTexture();
if (locTexture.isLoaded()) {
@@ -190,6 +190,7 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
tempTexture.initWithElement(tempElement);
tempTexture.handleLoadedTexture();
spriteFrame.setTexture(tempTexture);
+ spriteFrame.setRotated(false);
var rect = spriteFrame._rect;
spriteFrame.setRect(cc.rect(0, 0, rect.width, rect.height));
@@ -204,10 +205,10 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
*
* Adds multiple Sprite Frames from a plist or json file.
* A texture will be loaded automatically. The texture name will composed by replacing the .plist or .json suffix with .png
- * If you want to use another texture, you should use the addSpriteFrames:texture method.
+ * If you want to use another texture, you should use the addSpriteFrames:texture parameter.
*
* @param {String} url file path
- * @param {HTMLImageElement|cc.Texture2D|string} texture
+ * @param {HTMLImageElement|cc.Texture2D|string} [texture]
* @example
* // add SpriteFrames to SpriteFrameCache With File
* cc.spriteFrameCache.addSpriteFrames(s_grossiniPlist);
@@ -218,7 +219,7 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
//Is it a SpriteFrame plist?
var dict = this._frameConfigCache[url] || cc.loader.getRes(url);
- if(!dict || !dict["frames"])
+ if (!dict || !dict["frames"])
return;
var frameConfig = this._frameConfigCache[url] || this._getFrameConfig(url);
@@ -294,13 +295,13 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
removeSpriteFramesFromFile: function (url) {
var self = this, spriteFrames = self._spriteFrames,
aliases = self._spriteFramesAliases, cfg = self._frameConfigCache[url];
- if(!cfg) return;
+ if (!cfg) return;
var frames = cfg.frames;
for (var key in frames) {
if (spriteFrames[key]) {
delete(spriteFrames[key]);
for (var alias in aliases) {//remove alias
- if(aliases[alias] === key) delete aliases[alias];
+ if (aliases[alias] === key) delete aliases[alias];
}
}
}
@@ -320,7 +321,7 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
if (frame && (frame.getTexture() === texture)) {
delete(spriteFrames[key]);
for (var alias in aliases) {//remove alias
- if(aliases[alias] === key) delete aliases[alias];
+ if (aliases[alias] === key) delete aliases[alias];
}
}
}
@@ -345,15 +346,15 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
var key = self._spriteFramesAliases[name];
if (key) {
frame = self._spriteFrames[key.toString()];
- if(!frame) delete self._spriteFramesAliases[name];
+ if (!frame) delete self._spriteFramesAliases[name];
}
}
return frame;
},
- _clear: function () {
- this._spriteFrames = {};
- this._spriteFramesAliases = {};
- this._frameConfigCache = {};
- }
+ _clear: function () {
+ this._spriteFrames = {};
+ this._spriteFramesAliases = {};
+ this._frameConfigCache = {};
+ }
};
diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
index 78a83f5736..51ea5024cb 100644
--- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
+++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
@@ -23,24 +23,33 @@
****************************************************************************/
//Sprite's WebGL render command
-(function() {
+(function () {
+
cc.Sprite.WebGLRenderCmd = function (renderable) {
- cc.Node.WebGLRenderCmd.call(this, renderable);
+ this._rootCtor(renderable);
this._needDraw = true;
- this._quad = new cc.V3F_C4B_T2F_Quad();
- this._quadWebBuffer = cc._renderContext.createBuffer();
- this._quadDirty = true;
+ this._vertices = [
+ {x: 0, y: 0, u: 0, v: 0}, // tl
+ {x: 0, y: 0, u: 0, v: 0}, // bl
+ {x: 0, y: 0, u: 0, v: 0}, // tr
+ {x: 0, y: 0, u: 0, v: 0} // br
+ ];
+ this._color = new Uint32Array(1);
this._dirty = false;
this._recursiveDirty = false;
+
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
};
var proto = cc.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
proto.constructor = cc.Sprite.WebGLRenderCmd;
+ proto._spriteCmdCtor = cc.Sprite.WebGLRenderCmd;
- proto.updateBlendFunc = function (blendFunc) {};
+ proto.updateBlendFunc = function (blendFunc) {
+ };
- proto.setDirtyFlag = function(dirtyFlag){
+ proto.setDirtyFlag = function (dirtyFlag) {
cc.Node.WebGLRenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag);
this._dirty = true;
};
@@ -81,45 +90,10 @@
proto.isFrameDisplayed = function (frame) {
var node = this._node;
return (cc.rectEqualToRect(frame.getRect(), node._rect) && frame.getTexture().getName() === node._texture.getName()
- && cc.pointEqualToPoint(frame.getOffset(), node._unflippedOffsetPositionFromCenter));
- };
-
- proto._init = function () {
- var tempColor = {r: 255, g: 255, b: 255, a: 255}, quad = this._quad;
- quad.bl.colors = tempColor;
- quad.br.colors = tempColor;
- quad.tl.colors = tempColor;
- quad.tr.colors = tempColor;
- this._quadDirty = true;
- };
-
- proto._resetForBatchNode = function () {
- var node = this._node;
- var x1 = node._offsetPosition.x;
- var y1 = node._offsetPosition.y;
- var x2 = x1 + node._rect.width;
- var y2 = y1 + node._rect.height;
- var locQuad = this._quad;
- locQuad.bl.vertices = {x: x1, y: y1, z: 0};
- locQuad.br.vertices = {x: x2, y: y1, z: 0};
- locQuad.tl.vertices = {x: x1, y: y2, z: 0};
- locQuad.tr.vertices = {x: x2, y: y2, z: 0};
- this._quadDirty = true;
- };
-
- proto.getQuad = function () {
- return this._quad;
- };
-
- proto._updateForSetSpriteFrame = function () {};
-
- proto._spriteFrameLoadedCallback = function (spriteFrame) {
- this.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize());
- this.dispatchEvent("load");
+ && cc.pointEqualToPoint(frame.getOffset(), node._unflippedOffsetPositionFromCenter));
};
proto._textureLoadedCallback = function (sender) {
- var renderCmd = this._renderCmd;
if (this._textureLoaded)
return;
@@ -138,8 +112,10 @@
// by default use "Self Render".
// if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
this.setBatchNode(this._batchNode);
- renderCmd._quadDirty = true;
this.dispatchEvent("load");
+
+ // Force refresh the render command list
+ cc.renderer.childrenOrderDirty = true;
};
proto._setTextureCoords = function (rect, needConvert) {
@@ -150,13 +126,14 @@
var node = this._node;
var tex = node._batchNode ? node.textureAtlas.texture : node._texture;
+ var uvs = this._vertices;
if (!tex)
return;
var atlasWidth = tex.pixelsWidth;
var atlasHeight = tex.pixelsHeight;
- var left, right, top, bottom, tempSwap, locQuad = this._quad;
+ var left, right, top, bottom, tempSwap;
if (node._rectRotated) {
if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
left = (2 * rect.x + 1) / (2 * atlasWidth);
@@ -182,14 +159,14 @@
right = tempSwap;
}
- locQuad.bl.texCoords.u = left;
- locQuad.bl.texCoords.v = top;
- locQuad.br.texCoords.u = left;
- locQuad.br.texCoords.v = bottom;
- locQuad.tl.texCoords.u = right;
- locQuad.tl.texCoords.v = top;
- locQuad.tr.texCoords.u = right;
- locQuad.tr.texCoords.v = bottom;
+ uvs[0].u = right; // tl
+ uvs[0].v = top; // tl
+ uvs[1].u = left; // bl
+ uvs[1].v = top; // bl
+ uvs[2].u = right; // tr
+ uvs[2].v = bottom; // tr
+ uvs[3].u = left; // br
+ uvs[3].v = bottom; // br
} else {
if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
left = (2 * rect.x + 1) / (2 * atlasWidth);
@@ -215,53 +192,18 @@
bottom = tempSwap;
}
- locQuad.bl.texCoords.u = left;
- locQuad.bl.texCoords.v = bottom;
- locQuad.br.texCoords.u = right;
- locQuad.br.texCoords.v = bottom;
- locQuad.tl.texCoords.u = left;
- locQuad.tl.texCoords.v = top;
- locQuad.tr.texCoords.u = right;
- locQuad.tr.texCoords.v = top;
+ uvs[0].u = left; // tl
+ uvs[0].v = top; // tl
+ uvs[1].u = left; // bl
+ uvs[1].v = bottom; // bl
+ uvs[2].u = right; // tr
+ uvs[2].v = top; // tr
+ uvs[3].u = right; // br
+ uvs[3].v = bottom; // br
}
- this._quadDirty = true;
};
- proto.transform = function(parentCmd, recursive){
- cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive);
- this._dirty = true; //use for batching
- };
-
- proto._setColorDirty = function () {};
-
- proto._updateColor = function () {
- var locDisplayedColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity, node = this._node;
- var color4 = {r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: locDisplayedOpacity};
- // special opacity for premultiplied textures
- if (node._opacityModifyRGB) {
- color4.r *= locDisplayedOpacity / 255.0;
- color4.g *= locDisplayedOpacity / 255.0;
- color4.b *= locDisplayedOpacity / 255.0;
- }
- var locQuad = this._quad;
- locQuad.bl.colors = color4;
- locQuad.br.colors = color4;
- locQuad.tl.colors = color4;
- locQuad.tr.colors = color4;
-
- // renders using Sprite Manager
- if (node._batchNode) {
- if (node.atlasIndex !== cc.Sprite.INDEX_NOT_INITIALIZED) {
- node.textureAtlas.updateQuad(locQuad, node.atlasIndex)
- } else {
- // no need to set it recursively
- // update dirty_, don't update recursiveDirty_
- this._dirty = true;
- }
- }
- // self render
- // do nothing
- this._quadDirty = true;
+ proto._setColorDirty = function () {
};
proto._updateBlendFunc = function () {
@@ -271,128 +213,40 @@
}
// it's possible to have an untextured sprite
- var node = this._node;
+ var node = this._node,
+ blendFunc = node._blendFunc;
if (!node._texture || !node._texture.hasPremultipliedAlpha()) {
- node._blendFunc.src = cc.SRC_ALPHA;
- node._blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ if (blendFunc.src === cc.ONE && blendFunc.dst === cc.BLEND_DST) {
+ blendFunc.src = cc.SRC_ALPHA;
+ }
node.opacityModifyRGB = false;
} else {
- node._blendFunc.src = cc.BLEND_SRC;
- node._blendFunc.dst = cc.BLEND_DST;
+ if (blendFunc.src === cc.SRC_ALPHA && blendFunc.dst === cc.BLEND_DST) {
+ blendFunc.src = cc.ONE;
+ }
node.opacityModifyRGB = true;
}
};
proto._setTexture = function (texture) {
var node = this._node;
- // If batchnode, then texture id should be the same
- if (node._batchNode) {
- if(node._batchNode.texture !== texture){
- cc.log(cc._LogInfos.Sprite_setTexture);
- return;
- }
- }else{
- if(node._texture !== texture){
- node._textureLoaded = texture ? texture._textureLoaded : false;
- node._texture = texture;
+ if (node._texture !== texture) {
+ node._textureLoaded = texture ? texture._textureLoaded : false;
+ node._texture = texture;
+
+ // Update texture rect and blend func
+ if (texture) {
+ var texSize = texture._contentSize;
+ var rect = cc.rect(0, 0, texSize.width, texSize.height);
+ node.setTextureRect(rect);
this._updateBlendFunc();
}
- }
-
- if (texture)
- this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
- else
- this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
- };
-
- proto.updateTransform = function () { //called only at batching.
- var _t = this, node = this._node;
-
- // recalculate matrix only if it is dirty
- if (this._dirty) {
- var locQuad = _t._quad, locParent = node._parent;
- // If it is not visible, or one of its ancestors is not visible, then do nothing:
- if (!node._visible || ( locParent && locParent !== node._batchNode && locParent._shouldBeHidden)) {
- locQuad.br.vertices = locQuad.tl.vertices = locQuad.tr.vertices = locQuad.bl.vertices = {x: 0, y: 0, z: 0};
- node._shouldBeHidden = true;
- } else {
- node._shouldBeHidden = false;
- if(this._dirtyFlag !== 0){ //because changing color and opacity uses dirty flag at visit, but visit doesn't call at batching.
- this.updateStatus();
- this._dirtyFlag = 0;
- }
-
- if (!locParent || locParent === node._batchNode) {
- node._transformToBatch = _t.getNodeToParentTransform();
- } else {
- node._transformToBatch = cc.affineTransformConcat(_t.getNodeToParentTransform(), locParent._transformToBatch);
- }
-
- //
- // calculate the Quad based on the Affine Matrix
- //
- var locTransformToBatch = node._transformToBatch;
- var rect = node._rect;
- var x1 = node._offsetPosition.x;
- var y1 = node._offsetPosition.y;
-
- var x2 = x1 + rect.width;
- var y2 = y1 + rect.height;
- var x = locTransformToBatch.tx;
- var y = locTransformToBatch.ty;
-
- var cr = locTransformToBatch.a;
- var sr = locTransformToBatch.b;
- var cr2 = locTransformToBatch.d;
- var sr2 = -locTransformToBatch.c;
- var ax = x1 * cr - y1 * sr2 + x;
- var ay = x1 * sr + y1 * cr2 + y;
-
- var bx = x2 * cr - y1 * sr2 + x;
- var by = x2 * sr + y1 * cr2 + y;
-
- var cx = x2 * cr - y2 * sr2 + x;
- var cy = x2 * sr + y2 * cr2 + y;
-
- var dx = x1 * cr - y2 * sr2 + x;
- var dy = x1 * sr + y2 * cr2 + y;
-
- var locVertexZ = node._vertexZ;
- if (!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) {
- ax = 0 | ax;
- ay = 0 | ay;
- bx = 0 | bx;
- by = 0 | by;
- cx = 0 | cx;
- cy = 0 | cy;
- dx = 0 | dx;
- dy = 0 | dy;
- }
- locQuad.bl.vertices = {x: ax, y: ay, z: locVertexZ};
- locQuad.br.vertices = {x: bx, y: by, z: locVertexZ};
- locQuad.tl.vertices = {x: dx, y: dy, z: locVertexZ};
- locQuad.tr.vertices = {x: cx, y: cy, z: locVertexZ};
+ if (node._textureLoaded) {
+ // Force refresh the render command list
+ cc.renderer.childrenOrderDirty = true;
}
- node.textureAtlas.updateQuad(locQuad, node.atlasIndex);
- node._recursiveDirty = false;
- this._dirty = false;
}
-
- // recursively iterate over children
- if (node._hasChildren)
- node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform);
-
- /*if (cc.SPRITE_DEBUG_DRAW) { //TODO
- // draw bounding box
- var vertices = [
- cc.p(_t._quad.bl.vertices.x, _t._quad.bl.vertices.y),
- cc.p(_t._quad.br.vertices.x, _t._quad.br.vertices.y),
- cc.p(_t._quad.tr.vertices.x, _t._quad.tr.vertices.y),
- cc.p(_t._quad.tl.vertices.x, _t._quad.tl.vertices.y)
- ];
- cc._drawingUtil.drawPoly(vertices, 4, true);
- }*/
};
proto._checkTextureBoundary = function (texture, rect, rotated) {
@@ -414,80 +268,65 @@
}
};
- proto.rendering = function (ctx) {
- var node = this._node, locTexture = node._texture;
- if ((locTexture &&!locTexture._textureLoaded) || this._displayedOpacity === 0)
- return;
-
- var gl = ctx || cc._renderContext ;
- //cc.assert(!_t._batchNode, "If cc.Sprite is being rendered by cc.SpriteBatchNode, cc.Sprite#draw SHOULD NOT be called");
-
- if (locTexture) {
- if (locTexture._textureLoaded) {
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
-
- cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
- //optimize performance for javascript
- cc.glBindTexture2DN(0, locTexture); // = cc.glBindTexture2D(locTexture);
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
- if (this._quadDirty) {
- gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.DYNAMIC_DRAW);
- this._quadDirty = false;
- }
- gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 24, 0); //cc.VERTEX_ATTRIB_POSITION
- gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 24, 12); //cc.VERTEX_ATTRIB_COLOR
- gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 24, 16); //cc.VERTEX_ATTRIB_TEX_COORDS
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
- } else {
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
-
- cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
- cc.glBindTexture2D(null);
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+
+ var node = this._node,
+ lx = node._offsetPosition.x, rx = lx + node._rect.width,
+ by = node._offsetPosition.y, ty = by + node._rect.height,
+ wt = this._worldTransform,
+ wtx = wt.tx, wty = wt.ty,
+ lxa = lx * wt.a, lxb = lx * wt.b, rxa = rx * wt.a, rxb = rx * wt.b,
+ tyc = ty * wt.c, tyd = ty * wt.d, byc = by * wt.c, byd = by * wt.d;
+
+ var vertices = this._vertices;
+ vertices[0].x = lxa + tyc + wtx; // tl
+ vertices[0].y = lxb + tyd + wty;
+ vertices[1].x = lxa + byc + wtx; // bl
+ vertices[1].y = lxb + byd + wty;
+ vertices[2].x = rxa + tyc + wtx; // tr
+ vertices[2].y = rxb + tyd + wty;
+ vertices[3].x = rxa + byc + wtx; // br
+ vertices[3].y = rxb + byd + wty;
+ };
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR);
+ proto.needDraw = function () {
+ var node = this._node, locTexture = node._texture;
+ return (this._needDraw && locTexture);
+ };
- gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
- if (this._quadDirty) {
- gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.STATIC_DRAW);
- this._quadDirty = false;
- }
- gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0);
- gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
+ var node = this._node, locTexture = node._texture;
+ if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity)
+ return 0;
+
+ // Fill in vertex data with quad information (4 vertices for sprite)
+ var opacity = this._displayedOpacity;
+ var r = this._displayedColor.r,
+ g = this._displayedColor.g,
+ b = this._displayedColor.b;
+ if (node._opacityModifyRGB) {
+ var a = opacity / 255;
+ r *= a;
+ g *= a;
+ b *= a;
+ }
+ this._color[0] = ((opacity << 24) | (b << 16) | (g << 8) | r);
+ var z = node._vertexZ;
+
+ var vertices = this._vertices;
+ var i, len = vertices.length, vertex, offset = vertexDataOffset;
+ for (i = 0; i < len; ++i) {
+ vertex = vertices[i];
+ f32buffer[offset] = vertex.x;
+ f32buffer[offset + 1] = vertex.y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = this._color[0];
+ f32buffer[offset + 4] = vertex.u;
+ f32buffer[offset + 5] = vertex.v;
+ offset += 6;
}
- cc.g_NumberOfDraws++;
-
- if (cc.SPRITE_DEBUG_DRAW === 0 && !node._showNode)
- return;
- cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- //cc.kmGLPushMatrixWitMat4(node._stackMatrix);
- cc.current_stack.stack.push(cc.current_stack.top);
- cc.current_stack.top = this._stackMatrix;
-
- if (cc.SPRITE_DEBUG_DRAW === 1 || node._showNode) {
- // draw bounding box
- var locQuad = this._quad;
- var verticesG1 = [
- cc.p(locQuad.tl.vertices.x, locQuad.tl.vertices.y),
- cc.p(locQuad.bl.vertices.x, locQuad.bl.vertices.y),
- cc.p(locQuad.br.vertices.x, locQuad.br.vertices.y),
- cc.p(locQuad.tr.vertices.x, locQuad.tr.vertices.y)
- ];
- cc._drawingUtil.drawPoly(verticesG1, 4, true);
- } else if (cc.SPRITE_DEBUG_DRAW === 2) {
- // draw texture box
- var drawRectG2 = node.getTextureRect();
- var offsetPixG2 = node.getOffsetPosition();
- var verticesG2 = [cc.p(offsetPixG2.x, offsetPixG2.y), cc.p(offsetPixG2.x + drawRectG2.width, offsetPixG2.y),
- cc.p(offsetPixG2.x + drawRectG2.width, offsetPixG2.y + drawRectG2.height), cc.p(offsetPixG2.x, offsetPixG2.y + drawRectG2.height)];
- cc._drawingUtil.drawPoly(verticesG2, 4, true);
- } // CC_SPRITE_DEBUG_DRAW
- cc.current_stack.top = cc.current_stack.stack.pop();
+ return len;
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/core/support/CCPointExtension.js b/cocos2d/core/support/CCPointExtension.js
index 9771087379..3171a5f7ea 100644
--- a/cocos2d/core/support/CCPointExtension.js
+++ b/cocos2d/core/support/CCPointExtension.js
@@ -86,7 +86,7 @@ cc.pMult = function (point, floatVar) {
* Calculates midpoint between two points.
* @param {cc.Point} v1
* @param {cc.Point} v2
- * @return {cc.pMult}
+ * @return {cc.Point}
*/
cc.pMidpoint = function (v1, v2) {
return cc.pMult(cc.pAdd(v1, v2), 0.5);
@@ -134,7 +134,7 @@ cc.pRPerp = function (point) {
* Calculates the projection of v1 over v2.
* @param {cc.Point} v1
* @param {cc.Point} v2
- * @return {cc.pMult}
+ * @return {cc.Point}
*/
cc.pProject = function (v1, v2) {
return cc.pMult(v2, cc.pDot(v1, v2) / cc.pDot(v2, v2));
@@ -284,7 +284,7 @@ cc.pCompOp = function (p, opFunc) {
* @param {cc.Point} a
* @param {cc.Point} b
* @param {Number} alpha
- * @return {cc.pAdd}
+ * @return {cc.Point}
*/
cc.pLerp = function (a, b, alpha) {
return cc.pAdd(cc.pMult(a, 1 - alpha), cc.pMult(b, alpha));
@@ -454,7 +454,7 @@ cc.pSameAs = function (A, B) {
-// High Perfomance In Place Operationrs ---------------------------------------
+// High Performance In Place Operationrs ---------------------------------------
/**
* sets the position of the point to 0
@@ -498,7 +498,7 @@ cc.pSubIn = function(v1, v2) {
/**
* adds one point to another (inplace)
* @param {cc.Point} v1
- * @param {cc.point} v2
+ * @param {cc.Point} v2
*/
cc.pAddIn = function(v1, v2) {
v1.x += v2.x;
@@ -510,6 +510,7 @@ cc.pAddIn = function(v1, v2) {
* @param {cc.Point} v
*/
cc.pNormalizeIn = function(v) {
- cc.pMultIn(v, 1.0 / Math.sqrt(v.x * v.x + v.y * v.y));
+ var n = Math.sqrt(v.x * v.x + v.y * v.y);
+ if (n !== 0)
+ cc.pMultIn(v, 1.0 / n);
};
-
diff --git a/cocos2d/core/textures/CCTexture2D.js b/cocos2d/core/textures/CCTexture2D.js
index dca144d060..b69d83cfd9 100644
--- a/cocos2d/core/textures/CCTexture2D.js
+++ b/cocos2d/core/textures/CCTexture2D.js
@@ -96,360 +96,527 @@ cc.PVRHaveAlphaPremultiplied_ = false;
//cc.Texture2DWebGL move to TextureWebGL.js
-if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
-
- /**
- *
- * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data.
- * The created cc.Texture2D object will always have power-of-two dimensions.
- * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions
- * i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0).
- * Be aware that the content of the generated textures will be upside-down!
- * @name cc.Texture2D
- * @class
- * @extends cc.Class
- *
- * @property {WebGLTexture} name - <@readonly> WebGLTexture Object
- * @property {Number} defaultPixelFormat - The default pixel format
- * @property {Number} pixelFormat - <@readonly> Pixel format of the texture
- * @property {Number} pixelsWidth - <@readonly> Width in pixels
- * @property {Number} pixelsHeight - <@readonly> Height in pixels
- * @property {Number} width - Content width in points
- * @property {Number} height - Content height in points
- * @property {cc.GLProgram} shaderProgram - The shader program used by drawAtPoint and drawInRect
- * @property {Number} maxS - Texture max S
- * @property {Number} maxT - Texture max T
- */
- cc.Texture2D = cc.Class.extend(/** @lends cc.Texture2D# */{
- _contentSize: null,
- _textureLoaded: false,
- _htmlElementObj: null,
- url: null,
- _pattern: null,
-
- ctor: function () {
- this._contentSize = cc.size(0, 0);
- this._textureLoaded = false;
- this._htmlElementObj = null;
- this._pattern = "";
- },
-
- /**
- * get width in pixels
- * @return {Number}
- */
- getPixelsWide: function () {
- return this._contentSize.width;
- },
-
- /**
- * get height of in pixels
- * @return {Number}
- */
- getPixelsHigh: function () {
- return this._contentSize.height;
- },
-
- /**
- * get content size
- * @returns {cc.Size}
- */
- getContentSize: function () {
- var locScaleFactor = cc.contentScaleFactor();
- return cc.size(this._contentSize.width / locScaleFactor, this._contentSize.height / locScaleFactor);
- },
-
- _getWidth: function () {
- return this._contentSize.width / cc.contentScaleFactor();
- },
- _getHeight: function () {
- return this._contentSize.height / cc.contentScaleFactor();
- },
-
- /**
- * get content size in pixels
- * @returns {cc.Size}
- */
- getContentSizeInPixels: function () {
- return this._contentSize;
- },
-
- /**
- * init with HTML element
- * @param {HTMLImageElement|HTMLCanvasElement} element
- */
- initWithElement: function (element) {
- if (!element)
- return;
- this._htmlElementObj = element;
- this._contentSize.width = element.width;
- this._contentSize.height = element.height;
- this._textureLoaded = true;
- },
-
- /**
- * HTMLElement Object getter
- * @return {HTMLImageElement|HTMLCanvasElement}
- */
- getHtmlElementObj: function () {
- return this._htmlElementObj;
- },
-
- /**
- * check whether texture is loaded
- * @returns {boolean}
- */
- isLoaded: function () {
- return this._textureLoaded;
- },
-
- /**
- * handle loaded texture
- */
- handleLoadedTexture: function () {
- var self = this;
- if (self._textureLoaded) return;
- if (!self._htmlElementObj) {
- var img = cc.loader.getRes(self.url);
- if (!img) return;
- self.initWithElement(img);
- }
-
- var locElement = self._htmlElementObj;
- self._contentSize.width = locElement.width;
- self._contentSize.height = locElement.height;
-
- //dispatch load event to listener.
- self.dispatchEvent("load");
- },
-
- /**
- * description of cc.Texture2D
- * @returns {string}
- */
- description: function () {
- return "";
- },
-
- initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) {
- //support only in WebGl rendering mode
- return false;
- },
-
- initWithImage: function (uiImage) {
- //support only in WebGl rendering mode
- return false;
- },
-
- initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
- //support only in WebGl rendering mode
- return false;
- },
-
- releaseTexture: function () {
- cc.loader.release(this.url);
- },
-
- getName: function () {
- //support only in WebGl rendering mode
- return null;
- },
-
- getMaxS: function () {
- //support only in WebGl rendering mode
- return 1;
- },
-
- setMaxS: function (maxS) {
- //support only in WebGl rendering mode
- },
-
- getMaxT: function () {
- return 1;
- },
-
- setMaxT: function (maxT) {
- //support only in WebGl rendering mode
- },
-
- getPixelFormat: function () {
- //support only in WebGl rendering mode
- return null;
- },
-
- getShaderProgram: function () {
- //support only in WebGl rendering mode
- return null;
- },
-
- setShaderProgram: function (shaderProgram) {
- //support only in WebGl rendering mode
- },
-
- hasPremultipliedAlpha: function () {
- //support only in WebGl rendering mode
- return false;
- },
-
- hasMipmaps: function () {
- //support only in WebGl rendering mode
- return false;
- },
-
- releaseData: function (data) {
- //support only in WebGl rendering mode
- data = null;
- },
-
- keepData: function (data, length) {
- //support only in WebGl rendering mode
- return data;
- },
-
- drawAtPoint: function (point) {
- //support only in WebGl rendering mode
- },
-
- drawInRect: function (rect) {
- //support only in WebGl rendering mode
- },
-
- /**
- * init with ETC file
- * @warning does not support on HTML5
- */
- initWithETCFile: function (file) {
- cc.log(cc._LogInfos.Texture2D_initWithETCFile);
- return false;
- },
-
- /**
- * init with PVR file
- * @warning does not support on HTML5
- */
- initWithPVRFile: function (file) {
- cc.log(cc._LogInfos.Texture2D_initWithPVRFile);
- return false;
- },
-
- /**
- * init with PVRTC data
- * @warning does not support on HTML5
- */
- initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) {
- cc.log(cc._LogInfos.Texture2D_initWithPVRTCData);
- return false;
- },
-
- setTexParameters: function (texParams, magFilter, wrapS, wrapT) {
- if(magFilter !== undefined)
- texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
-
- if(texParams.wrapS === cc.REPEAT && texParams.wrapT === cc.REPEAT){
- this._pattern = "repeat";
- return;
- }
-
- if(texParams.wrapS === cc.REPEAT ){
- this._pattern = "repeat-x";
- return;
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+
+ var proto = {
+ _contentSize: null,
+ _textureLoaded: false,
+ _htmlElementObj: null,
+ url: null,
+ _pattern: null,
+
+ ctor: function () {
+ this._contentSize = cc.size(0, 0);
+ this._textureLoaded = false;
+ this._htmlElementObj = null;
+ this._pattern = "";
+ this._pixelsWide = 0;
+ this._pixelsHigh = 0;
+ },
+
+ /**
+ * get width in pixels
+ * @return {Number}
+ */
+ getPixelsWide: function () {
+ return this._pixelsWide;
+ },
+
+ /**
+ * get height of in pixels
+ * @return {Number}
+ */
+ getPixelsHigh: function () {
+ return this._pixelsHigh;
+ },
+
+ /**
+ * get content size
+ * @returns {cc.Size}
+ */
+ getContentSize: function () {
+ var locScaleFactor = cc.contentScaleFactor();
+ return cc.size(this._contentSize.width / locScaleFactor, this._contentSize.height / locScaleFactor);
+ },
+
+ _getWidth: function () {
+ return this._contentSize.width / cc.contentScaleFactor();
+ },
+ _getHeight: function () {
+ return this._contentSize.height / cc.contentScaleFactor();
+ },
+
+ /**
+ * get content size in pixels
+ * @returns {cc.Size}
+ */
+ getContentSizeInPixels: function () {
+ return this._contentSize;
+ },
+
+ /**
+ * init with HTML element
+ * @param {HTMLImageElement|HTMLCanvasElement} element
+ */
+ initWithElement: function (element) {
+ if (!element)
+ return;
+ this._htmlElementObj = element;
+ this._pixelsWide = this._contentSize.width = element.width;
+ this._pixelsHigh = this._contentSize.height = element.height;
+ this._textureLoaded = true;
+ },
+
+ /**
+ * HTMLElement Object getter
+ * @return {HTMLImageElement|HTMLCanvasElement}
+ */
+ getHtmlElementObj: function () {
+ return this._htmlElementObj;
+ },
+
+ /**
+ * check whether texture is loaded
+ * @returns {boolean}
+ */
+ isLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ /**
+ * handle loaded texture
+ */
+ handleLoadedTexture: function () {
+ var self = this;
+ if (!self._htmlElementObj) {
+ return;
+ }
+
+ var locElement = self._htmlElementObj;
+ self._pixelsWide = self._contentSize.width = locElement.width;
+ self._pixelsHigh = self._contentSize.height = locElement.height;
+
+ //dispatch load event to listener.
+ self.dispatchEvent("load");
+ },
+
+ /**
+ * description of cc.Texture2D
+ * @returns {string}
+ */
+ description: function () {
+ return "";
+ },
+
+ initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ initWithImage: function (uiImage) {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ releaseTexture: function () {
+ this._htmlElementObj = null;
+ cc.loader.release(this.url);
+ },
+
+ getName: function () {
+ //support only in WebGl rendering mode
+ return null;
+ },
+
+ getMaxS: function () {
+ //support only in WebGl rendering mode
+ return 1;
+ },
+
+ setMaxS: function (maxS) {
+ //support only in WebGl rendering mode
+ },
+
+ getMaxT: function () {
+ return 1;
+ },
+
+ setMaxT: function (maxT) {
+ //support only in WebGl rendering mode
+ },
+
+ getPixelFormat: function () {
+ //support only in WebGl rendering mode
+ return null;
+ },
+
+ getShaderProgram: function () {
+ //support only in WebGl rendering mode
+ return null;
+ },
+
+ setShaderProgram: function (shaderProgram) {
+ //support only in WebGl rendering mode
+ },
+
+ hasPremultipliedAlpha: function () {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ hasMipmaps: function () {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ releaseData: function (data) {
+ //support only in WebGl rendering mode
+ data = null;
+ },
+
+ keepData: function (data, length) {
+ //support only in WebGl rendering mode
+ return data;
+ },
+
+ drawAtPoint: function (point) {
+ //support only in WebGl rendering mode
+ },
+
+ drawInRect: function (rect) {
+ //support only in WebGl rendering mode
+ },
+
+ /**
+ * init with ETC file
+ * @warning does not support on HTML5
+ */
+ initWithETCFile: function (file) {
+ cc.log(cc._LogInfos.Texture2D_initWithETCFile);
+ return false;
+ },
+
+ /**
+ * init with PVR file
+ * @warning does not support on HTML5
+ */
+ initWithPVRFile: function (file) {
+ cc.log(cc._LogInfos.Texture2D_initWithPVRFile);
+ return false;
+ },
+
+ /**
+ * init with PVRTC data
+ * @warning does not support on HTML5
+ */
+ initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) {
+ cc.log(cc._LogInfos.Texture2D_initWithPVRTCData);
+ return false;
+ },
+
+ setTexParameters: function (texParams, magFilter, wrapS, wrapT) {
+ if (magFilter !== undefined)
+ texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
+
+ if (texParams.wrapS === cc.REPEAT && texParams.wrapT === cc.REPEAT) {
+ this._pattern = "repeat";
+ return;
+ }
+
+ if (texParams.wrapS === cc.REPEAT) {
+ this._pattern = "repeat-x";
+ return;
+ }
+
+ if (texParams.wrapT === cc.REPEAT) {
+ this._pattern = "repeat-y";
+ return;
+ }
+
+ this._pattern = "";
+ },
+
+ setAntiAliasTexParameters: function () {
+ //support only in WebGl rendering mode
+ },
+
+ setAliasTexParameters: function () {
+ //support only in WebGl rendering mode
+ },
+
+ generateMipmap: function () {
+ //support only in WebGl rendering mode
+ },
+
+ stringForFormat: function () {
+ //support only in WebGl rendering mode
+ return "";
+ },
+
+ bitsPerPixelForFormat: function (format) {
+ //support only in WebGl rendering mode
+ return -1;
+ },
+
+ /**
+ * add listener for loaded event
+ * @param {Function} callback
+ * @param {cc.Node} target
+ * @deprecated since 3.1, please use addEventListener instead
+ */
+ addLoadedEventListener: function (callback, target) {
+ this.addEventListener("load", callback, target);
+ },
+
+ /**
+ * remove listener from listeners by target
+ * @param {cc.Node} target
+ */
+ removeLoadedEventListener: function (target) {
+ this.removeEventTarget("load", target);
+ },
+
+ _generateColorTexture: function () {/*overide*/
+ },
+ _generateTextureCacheForColor: function () {
+ if (this.channelCache)
+ return this.channelCache;
+
+ var textureCache = [
+ document.createElement("canvas"),
+ document.createElement("canvas"),
+ document.createElement("canvas"),
+ document.createElement("canvas")
+ ];
+ //todo texture onload
+ renderToCache(this._htmlElementObj, textureCache);
+ return this.channelCache = textureCache;
+ },
+
+ //hack for gray effect
+ _grayElementObj: null,
+ _backupElement: null,
+ _isGray: false,
+ _switchToGray: function (toGray) {
+ if (!this._textureLoaded || this._isGray === toGray)
+ return;
+ this._isGray = toGray;
+ if (this._isGray) {
+ this._backupElement = this._htmlElementObj;
+ if (!this._grayElementObj)
+ this._grayElementObj = cc.Texture2D._generateGrayTexture(this._htmlElementObj);
+ this._htmlElementObj = this._grayElementObj;
+ } else {
+ if (this._backupElement !== null)
+ this._htmlElementObj = this._backupElement;
+ }
+ },
+
+ _generateGrayTexture: function() {
+ if(!this._textureLoaded)
+ return null;
+ var grayElement = cc.Texture2D._generateGrayTexture(this._htmlElementObj);
+ var newTexture = new cc.Texture2D();
+ newTexture.initWithElement(grayElement);
+ newTexture.handleLoadedTexture();
+ return newTexture;
+ },
+ };
+
+ var renderToCache = function (image, cache) {
+ var w = image.width;
+ var h = image.height;
+
+ cache[0].width = w;
+ cache[0].height = h;
+ cache[1].width = w;
+ cache[1].height = h;
+ cache[2].width = w;
+ cache[2].height = h;
+ cache[3].width = w;
+ cache[3].height = h;
+
+ var cacheCtx = cache[3].getContext("2d");
+ cacheCtx.drawImage(image, 0, 0);
+ var pixels = cacheCtx.getImageData(0, 0, w, h).data;
+
+ var ctx;
+ for (var rgbI = 0; rgbI < 4; rgbI++) {
+ ctx = cache[rgbI].getContext("2d");
+
+ var to = ctx.getImageData(0, 0, w, h);
+ var data = to.data;
+ for (var i = 0; i < pixels.length; i += 4) {
+ data[i] = (rgbI === 0) ? pixels[i] : 0;
+ data[i + 1] = (rgbI === 1) ? pixels[i + 1] : 0;
+ data[i + 2] = (rgbI === 2) ? pixels[i + 2] : 0;
+ data[i + 3] = pixels[i + 3];
+ }
+ ctx.putImageData(to, 0, 0);
}
-
- if(texParams.wrapT === cc.REPEAT){
- this._pattern = "repeat-y";
- return;
- }
-
- this._pattern = "";
- },
-
- setAntiAliasTexParameters: function () {
- //support only in WebGl rendering mode
- },
-
- setAliasTexParameters: function () {
- //support only in WebGl rendering mode
- },
-
- generateMipmap: function () {
- //support only in WebGl rendering mode
- },
-
- stringForFormat: function () {
- //support only in WebGl rendering mode
- return "";
- },
-
- bitsPerPixelForFormat: function (format) {
- //support only in WebGl rendering mode
- return -1;
- },
-
- /**
- * add listener for loaded event
- * @param {Function} callback
- * @param {cc.Node} target
- * @deprecated since 3.1, please use addEventListener instead
- */
- addLoadedEventListener: function (callback, target) {
- this.addEventListener("load", callback, target);
- },
+ image.onload = null;
+ };
+
+ //change color function
+ if (cc.sys._supportCanvasNewBlendModes) {
+ //multiply mode
+ //Primary afferent, Draw a new texture based on rect
+ proto._generateColorTexture = function (r, g, b, rect, canvas) {
+ var onlyCanvas = false;
+ if (canvas)
+ onlyCanvas = true;
+ else
+ canvas = document.createElement("canvas");
+ var textureImage = this._htmlElementObj;
+ if (!rect)
+ rect = cc.rect(0, 0, textureImage.width, textureImage.height);
+
+ canvas.width = rect.width;
+ canvas.height = rect.height;
+
+ var context = canvas.getContext("2d");
+ context.globalCompositeOperation = "source-over";
+ context.fillStyle = "rgb(" + (r | 0) + "," + (g | 0) + "," + (b | 0) + ")";
+ context.fillRect(0, 0, rect.width, rect.height);
+ context.globalCompositeOperation = "multiply";
+ context.drawImage(
+ textureImage,
+ rect.x, rect.y, rect.width, rect.height,
+ 0, 0, rect.width, rect.height
+ );
+ context.globalCompositeOperation = "destination-atop";
+ context.drawImage(
+ textureImage,
+ rect.x, rect.y, rect.width, rect.height,
+ 0, 0, rect.width, rect.height
+ );
+ if (onlyCanvas)
+ return canvas;
+ var newTexture = new cc.Texture2D();
+ newTexture.initWithElement(canvas);
+ newTexture.handleLoadedTexture();
+ return newTexture;
+ };
+ } else {
+ //Four color map overlay
+ proto._generateColorTexture = function (r, g, b, rect, canvas) {
+ var onlyCanvas = false;
+ if (canvas)
+ onlyCanvas = true;
+ else
+ canvas = document.createElement("canvas");
+
+ var textureImage = this._htmlElementObj;
+ if (!rect)
+ rect = cc.rect(0, 0, textureImage.width, textureImage.height);
+ var x, y, w, h;
+ x = rect.x; y = rect.y; w = rect.width; h = rect.height;
+ if (!w || !h)
+ return;
+
+ canvas.width = w;
+ canvas.height = h;
+
+ var context = canvas.getContext("2d");
+ var tintedImgCache = cc.textureCache.getTextureColors(this);
+ context.globalCompositeOperation = 'lighter';
+ context.drawImage(
+ tintedImgCache[3],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ if (r > 0) {
+ context.globalAlpha = r / 255;
+ context.drawImage(
+ tintedImgCache[0],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ }
+ if (g > 0) {
+ context.globalAlpha = g / 255;
+ context.drawImage(
+ tintedImgCache[1],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ }
+ if (b > 0) {
+ context.globalAlpha = b / 255;
+ context.drawImage(
+ tintedImgCache[2],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ }
+ if (onlyCanvas)
+ return canvas;
+
+ var newTexture = new cc.Texture2D();
+ newTexture.initWithElement(canvas);
+ newTexture.handleLoadedTexture();
+ return newTexture;
+ };
+ }
/**
- * remove listener from listeners by target
- * @param {cc.Node} target
+ *
+ * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data.
+ * The created cc.Texture2D object will always have power-of-two dimensions.
+ * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions
+ * i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0).
+ * Be aware that the content of the generated textures will be upside-down!
Returns a Texture2D object given an file image
+ * If the file image was not previously loaded, it will create a new Texture2D
+ * object and it will return it. It will use the filename as a key.
+ * Otherwise it will return a reference of a previously loaded image.
+ * Supported image extensions: .png, .jpg, .gif
Returns a Texture2D object given an file image
- * If the file image was not previously loaded, it will create a new Texture2D
- * object and it will return it. It will use the filename as a key.
- * Otherwise it will return a reference of a previously loaded image.
- * Supported image extensions: .png, .jpg, .gif
- * @param {String} url
- * @param {Function} cb
- * @param {Object} target
- * @return {cc.Texture2D}
- * @example
- * //example
- * cc.textureCache.addImage("hello.png");
- */
- _p.addImage = function (url, cb, target) {
-
- cc.assert(url, cc._LogInfos.Texture2D_addImage);
+ var texResult = cc.textureCache.handleLoadedTexture(url, img);
+ cb && cb.call(target, texResult);
+ });
- var locTexs = this._textures;
- //remove judge
- var tex = locTexs[url] || locTexs[cc.loader._aliases[url]];
- if (tex) {
- cb && cb.call(target, tex);
return tex;
- }
+ };
- tex = locTexs[url] = new cc.Texture2D();
- tex.url = url;
- var loadFunc = cc.loader._checkIsImageURL(url) ? cc.loader.load : cc.loader.loadImg;
- loadFunc.call(cc.loader, url, function (err, img) {
- if (err)
- return cb && cb.call(target, err);
- cc.textureCache.handleLoadedTexture(url);
-
- var texResult = locTexs[url];
- cb && cb.call(target, texResult);
- });
-
- return tex;
- };
-
- _p.addImageAsync = _p.addImage;
- _p = null;
-
-} else {
- cc.assert(cc.isFunction(cc._tmp.WebGLTextureCache), cc._LogInfos.MissingFile, "TexturesWebGL.js");
- cc._tmp.WebGLTextureCache();
- delete cc._tmp.WebGLTextureCache;
-}
\ No newline at end of file
+ _p.addImageAsync = _p.addImage;
+ _p = null;
+
+ } else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ cc.assert(cc.isFunction(cc._tmp.WebGLTextureCache), cc._LogInfos.MissingFile, "TexturesWebGL.js");
+ cc._tmp.WebGLTextureCache();
+ delete cc._tmp.WebGLTextureCache;
+ }
+});
diff --git a/cocos2d/core/textures/TexturesPropertyDefine.js b/cocos2d/core/textures/TexturesPropertyDefine.js
index fe1eef3801..518a5f5139 100644
--- a/cocos2d/core/textures/TexturesPropertyDefine.js
+++ b/cocos2d/core/textures/TexturesPropertyDefine.js
@@ -152,6 +152,15 @@ cc._tmp.PrototypeTexture2D = function () {
*/
_c.PIXEL_FORMAT_DEFAULT = _c.PIXEL_FORMAT_RGBA8888;
+ /**
+ * The default pixel format
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_PVRTC2
+ * @static
+ * @type {Number}
+ */
+ _c.defaultPixelFormat = _c.PIXEL_FORMAT_DEFAULT;
+
var _M = cc.Texture2D._M = {};
_M[_c.PIXEL_FORMAT_RGBA8888] = "RGBA8888";
_M[_c.PIXEL_FORMAT_RGB888] = "RGB888";
@@ -198,8 +207,6 @@ cc._tmp.PrototypeTexture2D = function () {
/** @expose */
_p.height;
cc.defineGetterSetter(_p, "height", _p._getHeight);
-
- _c.defaultPixelFormat = _c.PIXEL_FORMAT_DEFAULT;
};
cc._tmp.PrototypeTextureAtlas = function () {
diff --git a/cocos2d/core/textures/TexturesWebGL.js b/cocos2d/core/textures/TexturesWebGL.js
index c08cd2c49d..2dfe145e56 100644
--- a/cocos2d/core/textures/TexturesWebGL.js
+++ b/cocos2d/core/textures/TexturesWebGL.js
@@ -38,7 +38,6 @@ cc._tmp.WebGLTexture2D = function () {
* @extends cc.Class
*
* @property {WebGLTexture} name - <@readonly> WebGLTexture Object
- * @property {Number} defaultPixelFormat - The default pixel format
* @property {Number} pixelFormat - <@readonly> Pixel format of the texture
* @property {Number} pixelsWidth - <@readonly> Width in pixels
* @property {Number} pixelsHeight - <@readonly> Height in pixels
@@ -84,6 +83,7 @@ cc._tmp.WebGLTexture2D = function () {
releaseTexture: function () {
if (this._webTextureObj)
cc._renderContext.deleteTexture(this._webTextureObj);
+ this._htmlElementObj = null;
cc.loader.release(this.url);
},
@@ -225,7 +225,7 @@ cc._tmp.WebGLTexture2D = function () {
},
keepData: function (data, length) {
- //The texture data mustn't be saved becuase it isn't a mutable texture.
+ //The texture data mustn't be saved because it isn't a mutable texture.
return data;
},
@@ -325,10 +325,11 @@ cc._tmp.WebGLTexture2D = function () {
drawAtPoint: function (point) {
var self = this;
var coordinates = [
- 0.0, self.maxT,
- self.maxS, self.maxT,
- 0.0, 0.0,
- self.maxS, 0.0 ];
+ 0.0, self.maxT,
+ self.maxS, self.maxT,
+ 0.0, 0.0,
+ self.maxS, 0.0],
+ gl = cc._renderContext;
var width = self._pixelsWide * self.maxS,
height = self._pixelsHigh * self.maxT;
@@ -337,15 +338,15 @@ cc._tmp.WebGLTexture2D = function () {
point.x, point.y, 0.0,
width + point.x, point.y, 0.0,
point.x, height + point.y, 0.0,
- width + point.x, height + point.y, 0.0 ];
+ width + point.x, height + point.y, 0.0];
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
- self._shaderProgram.use();
- self._shaderProgram.setUniformsForBuiltins();
+ self._glProgramState.apply();
+ self._glProgramState._glprogram.setUniformsForBuiltins();
cc.glBindTexture2D(self);
- var gl = cc._renderContext;
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, vertices);
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, coordinates);
@@ -364,18 +365,19 @@ cc._tmp.WebGLTexture2D = function () {
0.0, 0.0,
self.maxS, 0.0];
- var vertices = [ rect.x, rect.y, /*0.0,*/
+ var vertices = [rect.x, rect.y, /*0.0,*/
rect.x + rect.width, rect.y, /*0.0,*/
rect.x, rect.y + rect.height, /*0.0,*/
- rect.x + rect.width, rect.y + rect.height /*0.0*/ ];
+ rect.x + rect.width, rect.y + rect.height /*0.0*/];
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
- self._shaderProgram.use();
- self._shaderProgram.setUniformsForBuiltins();
+ self._glProgramState.apply();
+ self._glProgramState._glprogram.setUniformsForBuiltins();
cc.glBindTexture2D(self);
var gl = cc._renderContext;
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, vertices);
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, coordinates);
@@ -422,6 +424,9 @@ cc._tmp.WebGLTexture2D = function () {
this._webTextureObj = cc._renderContext.createTexture();
this._htmlElementObj = element;
this._textureLoaded = true;
+ // Textures should be loaded with premultiplied alpha in order to avoid gray bleeding
+ // when semitransparent textures are interpolated (e.g. when scaled).
+ this._hasPremultipliedAlpha = true;
},
/**
@@ -442,19 +447,19 @@ cc._tmp.WebGLTexture2D = function () {
/**
* handler of texture loaded event
- * @param {Boolean} [premultipled=false]
+ * @param {Boolean} [premultiplied=false]
*/
- handleLoadedTexture: function (premultipled) {
- premultipled = (premultipled === undefined)?false: premultipled;
+ handleLoadedTexture: function (premultiplied) {
var self = this;
+ premultiplied =
+ (premultiplied !== undefined)
+ ? premultiplied
+ : self._hasPremultipliedAlpha;
// Not sure about this ! Some texture need to be updated even after loaded
- if (!cc._rendererInitialized)
+ if (!cc.game._rendererInitialized)
+ return;
+ if (!self._htmlElementObj)
return;
- if (!self._htmlElementObj) {
- var img = cc.loader.getRes(self.url);
- if (!img) return;
- self.initWithElement(img);
- }
if (!self._htmlElementObj.width || !self._htmlElementObj.height)
return;
@@ -464,7 +469,7 @@ cc._tmp.WebGLTexture2D = function () {
cc.glBindTexture2D(self);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
- if(premultipled)
+ if (premultiplied)
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
// Specify OpenGL texture image
@@ -477,7 +482,7 @@ cc._tmp.WebGLTexture2D = function () {
self.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
cc.glBindTexture2D(null);
- if(premultipled)
+ if (premultiplied)
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
var pixelsWide = self._htmlElementObj.width;
@@ -489,8 +494,11 @@ cc._tmp.WebGLTexture2D = function () {
self.maxS = 1;
self.maxT = 1;
- self._hasPremultipliedAlpha = premultipled;
+ self._hasPremultipliedAlpha = premultiplied;
self._hasMipmaps = false;
+ if (window.ENABLE_IMAEG_POOL) {
+ self._htmlElementObj = null;
+ }
//dispatch load event to listener.
self.dispatchEvent("load");
@@ -568,7 +576,7 @@ cc._tmp.WebGLTexture2D = function () {
var _t = this;
var gl = cc._renderContext;
- if(magFilter !== undefined)
+ if (magFilter !== undefined)
texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
cc.assert((_t._pixelsWide === cc.NextPOT(_t._pixelsWide) && _t._pixelsHigh === cc.NextPOT(_t._pixelsHigh)) ||
@@ -657,7 +665,6 @@ cc._tmp.WebGLTexture2D = function () {
var imageSize = cc.size(uiImage.getWidth(), uiImage.getHeight());
var pixelFormat = tex2d.defaultPixelFormat;
var bpp = uiImage.getBitsPerComponent();
- var i;
// compute pixel format
if (!hasAlpha) {
@@ -670,7 +677,7 @@ cc._tmp.WebGLTexture2D = function () {
}
// Repack the pixel data into the right format
- var length = width * height;
+ var i, length = width * height;
if (pixelFormat === tex2d.PIXEL_FORMAT_RGB565) {
if (hasAlpha) {
@@ -681,8 +688,8 @@ cc._tmp.WebGLTexture2D = function () {
for (i = 0; i < length; ++i) {
tempData[i] =
((((inPixel32[i] >> 0) & 0xFF) >> 3) << 11) | // R
- ((((inPixel32[i] >> 8) & 0xFF) >> 2) << 5) | // G
- ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 0); // B
+ ((((inPixel32[i] >> 8) & 0xFF) >> 2) << 5) | // G
+ ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 0); // B
}
} else {
// Convert "RRRRRRRRRGGGGGGGGBBBBBBBB" to "RRRRRGGGGGGBBBBB"
@@ -692,8 +699,8 @@ cc._tmp.WebGLTexture2D = function () {
for (i = 0; i < length; ++i) {
tempData[i] =
(((inPixel8[i] & 0xFF) >> 3) << 11) | // R
- (((inPixel8[i] & 0xFF) >> 2) << 5) | // G
- (((inPixel8[i] & 0xFF) >> 3) << 0); // B
+ (((inPixel8[i] & 0xFF) >> 2) << 5) | // G
+ (((inPixel8[i] & 0xFF) >> 3) << 0); // B
}
}
} else if (pixelFormat === tex2d.PIXEL_FORMAT_RGBA4444) {
@@ -704,9 +711,9 @@ cc._tmp.WebGLTexture2D = function () {
for (i = 0; i < length; ++i) {
tempData[i] =
((((inPixel32[i] >> 0) & 0xFF) >> 4) << 12) | // R
- ((((inPixel32[i] >> 8) & 0xFF) >> 4) << 8) | // G
- ((((inPixel32[i] >> 16) & 0xFF) >> 4) << 4) | // B
- ((((inPixel32[i] >> 24) & 0xFF) >> 4) << 0); // A
+ ((((inPixel32[i] >> 8) & 0xFF) >> 4) << 8) | // G
+ ((((inPixel32[i] >> 16) & 0xFF) >> 4) << 4) | // B
+ ((((inPixel32[i] >> 24) & 0xFF) >> 4) << 0); // A
}
} else if (pixelFormat === tex2d.PIXEL_FORMAT_RGB5A1) {
// Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
@@ -716,9 +723,9 @@ cc._tmp.WebGLTexture2D = function () {
for (i = 0; i < length; ++i) {
tempData[i] =
((((inPixel32[i] >> 0) & 0xFF) >> 3) << 11) | // R
- ((((inPixel32[i] >> 8) & 0xFF) >> 3) << 6) | // G
- ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 1) | // B
- ((((inPixel32[i] >> 24) & 0xFF) >> 7) << 0); // A
+ ((((inPixel32[i] >> 8) & 0xFF) >> 3) << 6) | // G
+ ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 1) | // B
+ ((((inPixel32[i] >> 24) & 0xFF) >> 7) << 0); // A
}
} else if (pixelFormat === tex2d.PIXEL_FORMAT_A8) {
// Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "AAAAAAAA"
@@ -766,7 +773,7 @@ cc._tmp.WebGLTexture2D = function () {
* @param {cc.Node} target
*/
removeLoadedEventListener: function (target) {
- this.removeEventListener("load", target);
+ this.removeEventTarget("load", target);
}
});
};
@@ -818,14 +825,17 @@ cc._tmp.WebGLTextureAtlas = function () {
//vertices
//gl.bindBuffer(gl.ARRAY_BUFFER, _t._buffersVBO[0]);
// XXX: update is done in draw... perhaps it should be done in a timer
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
gl.bindBuffer(gl.ARRAY_BUFFER, _t._quadsWebBuffer);
- if (_t.dirty){
+ if (_t.dirty) {
gl.bufferData(gl.ARRAY_BUFFER, _t._quadsArrayBuffer, gl.DYNAMIC_DRAW);
_t.dirty = false;
}
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); // vertices
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); // colors
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); // tex coords
@@ -845,18 +855,26 @@ cc._tmp.WebGLTextureAtlas = function () {
cc._tmp.WebGLTextureCache = function () {
var _p = cc.textureCache;
- _p.handleLoadedTexture = function (url) {
- var locTexs = this._textures;
+ _p.handleLoadedTexture = function (url, img) {
+ var locTexs = this._textures, tex, ext;
//remove judge(webgl)
- if (!cc._rendererInitialized) {
+ if (!cc.game._rendererInitialized) {
locTexs = this._loadedTexturesBefore;
}
- var tex = locTexs[url];
+ tex = locTexs[url];
if (!tex) {
tex = locTexs[url] = new cc.Texture2D();
tex.url = url;
}
- tex.handleLoadedTexture();
+ tex.initWithElement(img);
+ ext = cc.path.extname(url);
+ if (ext === ".png") {
+ tex.handleLoadedTexture(true);
+ }
+ else {
+ tex.handleLoadedTexture();
+ }
+ return tex;
};
/**
@@ -878,24 +896,31 @@ cc._tmp.WebGLTextureCache = function () {
var locTexs = this._textures;
//remove judge(webgl)
- if (!cc._rendererInitialized) {
+ if (!cc.game._rendererInitialized) {
locTexs = this._loadedTexturesBefore;
}
- var tex = locTexs[url] || locTexs[cc.loader._aliases[url]];
+ var tex = locTexs[url] || locTexs[cc.loader._getAliase(url)];
if (tex) {
- cb && cb.call(target, tex);
- return tex;
+ if (tex.isLoaded()) {
+ cb && cb.call(target, tex);
+ return tex;
+ }
+ else {
+ tex.addEventListener("load", function () {
+ cb && cb.call(target, tex);
+ }, target);
+ return tex;
+ }
}
tex = locTexs[url] = new cc.Texture2D();
tex.url = url;
- var loadFunc = cc.loader._checkIsImageURL(url) ? cc.loader.load : cc.loader.loadImg;
- loadFunc.call(cc.loader, url, function (err, img) {
+ var basePath = cc.loader.getBasePath ? cc.loader.getBasePath() : cc.loader.resPath;
+ cc.loader.loadImg(cc.path.join(basePath || "", url), function (err, img) {
if (err)
return cb && cb.call(target, err);
- cc.textureCache.handleLoadedTexture(url);
- var texResult = locTexs[url];
+ var texResult = cc.textureCache.handleLoadedTexture(url, img);
cb && cb.call(target, texResult);
});
diff --git a/cocos2d/core/utils/BinaryLoader.js b/cocos2d/core/utils/BinaryLoader.js
index 013c3dee6e..46b82b65cf 100644
--- a/cocos2d/core/utils/BinaryLoader.js
+++ b/cocos2d/core/utils/BinaryLoader.js
@@ -37,7 +37,8 @@ cc.loader.loadBinary = function (url, cb) {
var xhr = this.getXMLHttpRequest(),
errInfo = "load " + url + " failed!";
xhr.open("GET", url, true);
- if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
+ xhr.responseType = 'arraybuffer';
+ if (cc.loader.loadBinary._IEFilter) {
// IE-specific logic here
xhr.setRequestHeader("Accept-Charset", "x-user-defined");
xhr.onreadystatechange = function () {
@@ -49,12 +50,14 @@ cc.loader.loadBinary = function (url, cb) {
} else {
if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=x-user-defined");
xhr.onload = function () {
- xhr.readyState === 4 && xhr.status === 200 ? cb(null, self._str2Uint8Array(xhr.responseText)) : cb(errInfo);
+ xhr.readyState === 4 && xhr.status === 200 ? cb(null, new Uint8Array(xhr.response)) : cb(errInfo);
};
}
xhr.send(null);
};
+cc.loader.loadBinary._IEFilter = (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) && window.IEBinaryToArray_ByteStr && window.IEBinaryToArray_ByteStr_Last);
+
cc.loader._str2Uint8Array = function (strData) {
if (!strData)
return null;
@@ -75,10 +78,11 @@ cc.loader._str2Uint8Array = function (strData) {
cc.loader.loadBinarySync = function (url) {
var self = this;
var req = this.getXMLHttpRequest();
+ req.timeout = 0;
var errInfo = "load " + url + " failed!";
req.open('GET', url, false);
var arrayInfo = null;
- if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
+ if (cc.loader.loadBinary._IEFilter) {
req.setRequestHeader("Accept-Charset", "x-user-defined");
req.send(null);
if (req.status !== 200) {
@@ -99,15 +103,15 @@ cc.loader.loadBinarySync = function (url) {
return null;
}
- arrayInfo = this._str2Uint8Array(req.responseText);
+ arrayInfo = self._str2Uint8Array(req.responseText);
}
return arrayInfo;
};
//Compatibility with IE9
-var Uint8Array = Uint8Array || Array;
+window.Uint8Array = window.Uint8Array || window.Array;
-if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
+if (cc.loader.loadBinary._IEFilter) {
var IEBinaryToArray_ByteStr_Script =
"\r\n" +
//"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+