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 ]
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" +
//"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+